WordPress.org

Make WordPress Core

Changeset 23618


Ignore:
Timestamp:
03/05/2013 04:14:14 PM (9 years ago)
Author:
nacin
Message:

Properly handle timezones in get_date_from_gmt() rather than relying on the implicit gmt_offset. This offset is only good for the current time, rather than the passed time, which causes problems when converting a DST date when DST is not in effect, or vice versa.

Update get_gmt_from_date() to make these functions match in formatting, as they are complementary and just reverse a few operations.

props scholesmafia
Tests: [1233/tests]

fixes #20328.

File:
1 edited

Legend:

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

    r23591 r23618  
    19071907 * Returns a date in the GMT equivalent.
    19081908 *
    1909  * Requires and returns a date in the Y-m-d H:i:s format. Simply subtracts the
    1910  * value of the 'gmt_offset' option. Return format can be overridden using the
    1911  * $format parameter. The DateTime and DateTimeZone classes are used to respect
    1912  * time zone differences in DST.
     1909 * Requires and returns a date in the Y-m-d H:i:s format. If there is a
     1910 * timezone_string available, the date is assumed to be in that timezone,
     1911 * otherwise it simply subtracts the value of the 'gmt_offset' option. Return
     1912 * format can be overridden using the $format parameter.
    19131913 *
    19141914 * @since 1.2.0
     
    19191919 * @return string GMT version of the date provided.
    19201920 */
    1921 function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
    1922     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);
    1923     if ( ! $matches )
    1924         return date( $format, 0 );
    1925 
    1926     $tz = get_option('timezone_string');
     1921function get_gmt_from_date( $string, $format = 'Y-m-d H:i:s' ) {
     1922    $tz = get_option( 'timezone_string' );
    19271923    if ( $tz ) {
    1928         date_default_timezone_set( $tz );
    1929         $datetime = date_create( $string );
     1924        $datetime = date_create( $string, new DateTimeZone( $tz ) );
     1925        if ( ! $datetime )
     1926            return gmdate( $format, 0 );
     1927        $datetime->setTimezone( new DateTimeZone( 'UTC' ) );
     1928        $string_gmt = $datetime->format( $format );
     1929    } else {
     1930        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 ) )
     1931            return gmdate( $format, 0 );
     1932        $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
     1933        $string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
     1934    }
     1935    return $string_gmt;
     1936}
     1937
     1938/**
     1939 * Converts a GMT date into the correct format for the blog.
     1940 *
     1941 * Requires and returns a date in the Y-m-d H:i:s format. If there is a
     1942 * timezone_string available, the returned date is in that timezone, otherwise
     1943 * it simply adds the value of gmt_offset. Return format can be overridden
     1944 * using the $format parameter
     1945 *
     1946 * @since 1.2.0
     1947 *
     1948 * @param string $string The date to be converted.
     1949 * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
     1950 * @return string Formatted date relative to the timezone / GMT offset.
     1951 */
     1952function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) {
     1953    $tz = get_option( 'timezone_string' );
     1954    if ( $tz ) {
     1955        $datetime = date_create( $string, new DateTimeZone( 'UTC' ) );
    19301956        if ( ! $datetime )
    19311957            return date( $format, 0 );
    1932 
    1933         $datetime->setTimezone( new DateTimeZone('UTC') );
    1934         $offset = $datetime->getOffset();
    1935         $datetime->modify( '+' . $offset / HOUR_IN_SECONDS . ' hours');
    1936         $string_gmt = gmdate($format, $datetime->format('U'));
    1937 
    1938         date_default_timezone_set('UTC');
     1958        $datetime->setTimezone( new DateTimeZone( $tz ) );
     1959        $string_localtime = $datetime->format( $format );
    19391960    } else {
    1940         $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
    1941         $string_gmt = gmdate($format, $string_time - get_option('gmt_offset') * HOUR_IN_SECONDS);
    1942     }
    1943     return $string_gmt;
    1944 }
    1945 
    1946 /**
    1947  * Converts a GMT date into the correct format for the blog.
    1948  *
    1949  * Requires and returns in the Y-m-d H:i:s format. Simply adds the value of
    1950  * gmt_offset.Return format can be overridden using the $format parameter
    1951  *
    1952  * @since 1.2.0
    1953  *
    1954  * @param string $string The date to be converted.
    1955  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
    1956  * @return string Formatted date relative to the GMT offset.
    1957  */
    1958 function get_date_from_gmt($string, $format = 'Y-m-d H:i:s') {
    1959     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);
    1960     $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
    1961     $string_localtime = gmdate($format, $string_time + get_option('gmt_offset') * HOUR_IN_SECONDS);
     1961        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) )
     1962            return date( $format, 0 );
     1963        $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
     1964        $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
     1965    }
    19621966    return $string_localtime;
    19631967}
Note: See TracChangeset for help on using the changeset viewer.