format( self::DATE ) === $date; } /** * Adds days to a Y-m-d date. * * @since 0.1.0 * * @param string $date Y-m-d date. * @param int $days Days to add, may be negative. * @return string */ public static function add_days( string $date, int $days ): string { return self::parse( $date )->modify( sprintf( '%+d days', $days ) )->format( self::DATE ); } /** * Whole days from one Y-m-d date to another (negative when the second is earlier). * * @since 0.1.0 * * @param string $from Y-m-d date. * @param string $to Y-m-d date. * @return int */ public static function days_between( string $from, string $to ): int { $diff = self::parse( $from )->diff( self::parse( $to ) ); return $diff->invert ? - (int) $diff->days : (int) $diff->days; } /** * Adds months to a Y-m-d date. When the target month is shorter, the result * is clamped to its last day, so 31 January plus one month is 28 February. * * @since 0.1.0 * * @param string $date Y-m-d date. * @param int $months Months to add, may be negative. * @return string */ public static function add_months( string $date, int $months ): string { $start = self::parse( $date ); $day = (int) $start->format( 'j' ); $first = $start->modify( 'first day of this month' )->modify( sprintf( '%+d months', $months ) ); $last = (int) $first->format( 't' ); return $first->setDate( (int) $first->format( 'Y' ), (int) $first->format( 'n' ), min( $day, $last ) )->format( self::DATE ); } /** * Converts a UTC MySQL datetime to the site timezone for display. * * @since 0.1.0 * * @param string $gmt UTC datetime. * @param string $format PHP date format. Empty uses the site date and time format. * @return string */ public static function to_site( string $gmt, string $format = '' ): string { if ( '' === $gmt || '0000-00-00 00:00:00' === $gmt ) { return ''; } if ( '' === $format ) { $format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); } return wp_date( $format, strtotime( $gmt . ' UTC' ) ); } /** * Parses a Y-m-d date as midnight UTC. * * @param string $date Y-m-d date. * @return DateTimeImmutable */ private static function parse( string $date ): DateTimeImmutable { return new DateTimeImmutable( $date . ' 00:00:00', new DateTimeZone( 'UTC' ) ); } }