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.



git-svn-id: http://core.svn.wordpress.org/trunk@23618 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Nacin 2013-03-05 16:14:14 +00:00
parent 06762563eb
commit 2ca0cdcdfe
1 changed files with 33 additions and 29 deletions

View File

@ -1906,10 +1906,10 @@ function _wp_iso_convert( $match ) {
/** /**
* Returns a date in the GMT equivalent. * Returns a date in the GMT equivalent.
* *
* Requires and returns a date in the Y-m-d H:i:s format. Simply subtracts the * Requires and returns a date in the Y-m-d H:i:s format. If there is a
* value of the 'gmt_offset' option. Return format can be overridden using the * timezone_string available, the date is assumed to be in that timezone,
* $format parameter. The DateTime and DateTimeZone classes are used to respect * otherwise it simply subtracts the value of the 'gmt_offset' option. Return
* time zone differences in DST. * format can be overridden using the $format parameter.
* *
* @since 1.2.0 * @since 1.2.0
* *
@ -1918,27 +1918,19 @@ function _wp_iso_convert( $match ) {
* @param string $format The format string for the returned date (default is Y-m-d H:i:s) * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
* @return string GMT version of the date provided. * @return string GMT version of the date provided.
*/ */
function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') { function get_gmt_from_date( $string, $format = 'Y-m-d H:i:s' ) {
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); $tz = get_option( 'timezone_string' );
if ( ! $matches )
return date( $format, 0 );
$tz = get_option('timezone_string');
if ( $tz ) { if ( $tz ) {
date_default_timezone_set( $tz ); $datetime = date_create( $string, new DateTimeZone( $tz ) );
$datetime = date_create( $string );
if ( ! $datetime ) if ( ! $datetime )
return date( $format, 0 ); return gmdate( $format, 0 );
$datetime->setTimezone( new DateTimeZone( 'UTC' ) );
$datetime->setTimezone( new DateTimeZone('UTC') ); $string_gmt = $datetime->format( $format );
$offset = $datetime->getOffset();
$datetime->modify( '+' . $offset / HOUR_IN_SECONDS . ' hours');
$string_gmt = gmdate($format, $datetime->format('U'));
date_default_timezone_set('UTC');
} else { } else {
$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); 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 ) )
$string_gmt = gmdate($format, $string_time - get_option('gmt_offset') * HOUR_IN_SECONDS); return gmdate( $format, 0 );
$string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
$string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
} }
return $string_gmt; return $string_gmt;
} }
@ -1946,19 +1938,31 @@ function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
/** /**
* Converts a GMT date into the correct format for the blog. * Converts a GMT date into the correct format for the blog.
* *
* Requires and returns in the Y-m-d H:i:s format. Simply adds the value of * Requires and returns a date in the Y-m-d H:i:s format. If there is a
* gmt_offset.Return format can be overridden using the $format parameter * timezone_string available, the returned date is in that timezone, otherwise
* it simply adds the value of gmt_offset. Return format can be overridden
* using the $format parameter
* *
* @since 1.2.0 * @since 1.2.0
* *
* @param string $string The date to be converted. * @param string $string The date to be converted.
* @param string $format The format string for the returned date (default is Y-m-d H:i:s) * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
* @return string Formatted date relative to the GMT offset. * @return string Formatted date relative to the timezone / GMT offset.
*/ */
function get_date_from_gmt($string, $format = 'Y-m-d H:i:s') { function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) {
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); $tz = get_option( 'timezone_string' );
$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); if ( $tz ) {
$string_localtime = gmdate($format, $string_time + get_option('gmt_offset') * HOUR_IN_SECONDS); $datetime = date_create( $string, new DateTimeZone( 'UTC' ) );
if ( ! $datetime )
return date( $format, 0 );
$datetime->setTimezone( new DateTimeZone( $tz ) );
$string_localtime = $datetime->format( $format );
} else {
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) )
return date( $format, 0 );
$string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
$string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
}
return $string_localtime; return $string_localtime;
} }