Make WordPress Core


Ignore:
Timestamp:
08/23/2019 11:02:51 AM (5 years ago)
Author:
SergeyBiryukov
Message:

Date/Time: Rewrite and simplify get_gmt_from_date(), get_date_from_gmt(), and iso8601_to_datetime() using wp_timezone().

Improve unit test coverage.

Props Rarst, goodevilgenius.
Fixes #31809.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/formatting.php

    r45796 r45887  
    33853385 * Returns a date in the GMT equivalent.
    33863386 *
    3387  * Requires and returns a date in the Y-m-d H:i:s format. If there is a
    3388  * timezone_string available, the date is assumed to be in that timezone,
    3389  * otherwise it simply subtracts the value of the 'gmt_offset' option. Return
    3390  * format can be overridden using the $format parameter.
     3387 * Requires and returns a date in the Y-m-d H:i:s format.
     3388 * Return format can be overridden using the $format parameter.
    33913389 *
    33923390 * @since 1.2.0
    33933391 *
    33943392 * @param string $string The date to be converted.
    3395  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
     3393 * @param string $format The format string for the returned date. Default 'Y-m-d H:i:s'.
    33963394 * @return string GMT version of the date provided.
    33973395 */
    33983396function get_gmt_from_date( $string, $format = 'Y-m-d H:i:s' ) {
    3399     $tz = get_option( 'timezone_string' );
    3400     if ( $tz ) {
    3401         $datetime = date_create( $string, new DateTimeZone( $tz ) );
    3402         if ( ! $datetime ) {
    3403             return gmdate( $format, 0 );
    3404         }
    3405         $datetime->setTimezone( new DateTimeZone( 'UTC' ) );
    3406         $string_gmt = $datetime->format( $format );
    3407     } else {
    3408         if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) {
    3409             $datetime = strtotime( $string );
    3410             if ( false === $datetime ) {
    3411                 return gmdate( $format, 0 );
    3412             }
    3413             return gmdate( $format, $datetime );
    3414         }
    3415         $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
    3416         $string_gmt  = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    3417     }
    3418     return $string_gmt;
     3397    $datetime = date_create( $string, wp_timezone() );
     3398
     3399    if ( false === $datetime ) {
     3400        return gmdate( $format, 0 );
     3401    }
     3402
     3403    return $datetime->setTimezone( new DateTimeZone( 'UTC' ) )->format( $format );
    34193404}
    34203405
     
    34223407 * Converts a GMT date into the correct format for the blog.
    34233408 *
    3424  * Requires and returns a date in the Y-m-d H:i:s format. If there is a
    3425  * timezone_string available, the returned date is in that timezone, otherwise
    3426  * it simply adds the value of gmt_offset. Return format can be overridden
    3427  * using the $format parameter
     3409 * Requires and returns a date in the Y-m-d H:i:s format.
     3410 * Return format can be overridden using the $format parameter.
    34283411 *
    34293412 * @since 1.2.0
    34303413 *
    34313414 * @param string $string The date to be converted.
    3432  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
    3433  * @return string Formatted date relative to the timezone / GMT offset.
     3415 * @param string $format The format string for the returned date. Default 'Y-m-d H:i:s'.
     3416 * @return string Formatted date relative to the timezone.
    34343417 */
    34353418function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) {
    3436     $tz = get_option( 'timezone_string' );
    3437     if ( $tz ) {
    3438         $datetime = date_create( $string, new DateTimeZone( 'UTC' ) );
    3439         if ( ! $datetime ) {
    3440             return gmdate( $format, 0 );
    3441         }
    3442         $datetime->setTimezone( new DateTimeZone( $tz ) );
    3443         $string_localtime = $datetime->format( $format );
    3444     } else {
    3445         if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) {
    3446             return gmdate( $format, 0 );
    3447         }
    3448         $string_time      = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
    3449         $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    3450     }
    3451     return $string_localtime;
     3419    $datetime = date_create( $string, new DateTimeZone( 'UTC' ) );
     3420
     3421    if ( false === $datetime ) {
     3422        return gmdate( $format, 0 );
     3423    }
     3424
     3425    return $datetime->setTimezone( wp_timezone() )->format( $format );
    34523426}
    34533427
     
    34743448
    34753449/**
    3476  * Converts an iso8601 date to MySQL DateTime format used by post_date[_gmt].
     3450 * Converts an iso8601 (Ymd\TH:i:sO) date to MySQL DateTime (Y-m-d H:i:s) format used by post_date[_gmt].
    34773451 *
    34783452 * @since 1.5.0
    34793453 *
    34803454 * @param string $date_string Date and time in ISO 8601 format {@link https://en.wikipedia.org/wiki/ISO_8601}.
    3481  * @param string $timezone    Optional. If set to GMT returns the time minus gmt_offset. Default is 'user'.
    3482  * @return string The date and time in MySQL DateTime format - Y-m-d H:i:s.
     3455 * @param string $timezone    Optional. If set to 'gmt' returns the result in UTC. Default 'user'.
     3456 * @return string|bool The date and time in MySQL DateTime format - Y-m-d H:i:s, or false on failure.
    34833457 */
    34843458function iso8601_to_datetime( $date_string, $timezone = 'user' ) {
    3485     $timezone = strtolower( $timezone );
    3486 
    3487     if ( $timezone == 'gmt' ) {
    3488 
    3489         preg_match( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits );
    3490 
    3491         if ( ! empty( $date_bits[7] ) ) { // we have a timezone, so let's compute an offset
    3492             $offset = iso8601_timezone_to_offset( $date_bits[7] );
    3493         } else { // we don't have a timezone, so we assume user local timezone (not server's!)
    3494             $offset = HOUR_IN_SECONDS * get_option( 'gmt_offset' );
    3495         }
    3496 
    3497         $timestamp  = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] );
    3498         $timestamp -= $offset;
    3499 
    3500         return gmdate( 'Y-m-d H:i:s', $timestamp );
    3501 
    3502     } elseif ( $timezone == 'user' ) {
    3503         return preg_replace( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string );
    3504     }
     3459    $timezone    = strtolower( $timezone );
     3460    $wp_timezone = wp_timezone();
     3461    $datetime    = date_create( $date_string, $wp_timezone ); // Timezone is ignored if input has one.
     3462
     3463    if ( false === $datetime ) {
     3464        return false;
     3465    }
     3466
     3467    if ( 'gmt' === $timezone ) {
     3468        return $datetime->setTimezone( new DateTimeZone( 'UTC' ) )->format( 'Y-m-d H:i:s' );
     3469    }
     3470
     3471    if ( 'user' === $timezone ) {
     3472        return $datetime->setTimezone( $wp_timezone )->format( 'Y-m-d H:i:s' );
     3473    }
     3474
     3475    return false;
    35053476}
    35063477
Note: See TracChangeset for help on using the changeset viewer.