WordPress.org

Make WordPress Core

Changeset 23618


Ignore:
Timestamp:
03/05/13 16:14:14 (14 months 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.