From d448c448caded1e826ade450e4351b6e5ae2341c Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Tue, 3 Jul 2018 15:58:58 +0000 Subject: [PATCH] Date/Time: Add support for `gmt_offset` to `date_i18n()`. Prior to this change, `date_i18n()` only supported the `timezone_string` option, causing incorrect timezones to appear in formatted dates on sites that still rely on the `gmt_offset` option. Props Rarst. Fixes #34835. git-svn-id: https://develop.svn.wordpress.org/trunk@43387 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 30 +++++++++++++++++++++++++++ tests/phpunit/tests/date/dateI18n.php | 16 ++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 3c4a301298..b4df760ec6 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -138,6 +138,36 @@ function date_i18n( $dateformatstring, $timestamp_with_offset = false, $gmt = fa $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 ); } } + } else { + $offset = get_option( 'gmt_offset' ); + foreach ( $timezone_formats as $timezone_format ) { + if ( 'I' === $timezone_format ) { + continue; + } + + if ( false !== strpos( $dateformatstring, $timezone_format ) ) { + if ( 'Z' === $timezone_format ) { + $formatted = (string) ( $offset * HOUR_IN_SECONDS ); + } else { + $prefix = ''; + $hours = (int) $offset; + $separator = ''; + $minutes = abs( ( $offset - $hours ) * 60 ); + + if ( 'T' === $timezone_format ) { + $prefix = 'GMT'; + } elseif ( 'e' === $timezone_format || 'P' === $timezone_format ) { + $separator = ':'; + } + + $formatted = sprintf( '%s%+03d%s%02d', $prefix, $hours, $separator, $minutes ); + } + + $dateformatstring = ' ' . $dateformatstring; + $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring ); + $dateformatstring = substr( $dateformatstring, 1 ); + } + } } } $j = @date( $dateformatstring, $i ); diff --git a/tests/phpunit/tests/date/dateI18n.php b/tests/phpunit/tests/date/dateI18n.php index e92f58de6f..d5685190c7 100644 --- a/tests/phpunit/tests/date/dateI18n.php +++ b/tests/phpunit/tests/date/dateI18n.php @@ -67,4 +67,20 @@ class Tests_Date_I18n extends WP_UnitTestCase { $this->assertEquals( '2012-12-01 00:00:00 CST -06:00 America/Regina', date_i18n( 'Y-m-d H:i:s T P e', strtotime( '2012-12-01 00:00:00' ) ) ); } + + /** + * @ticket 34835 + */ + public function test_gmt_offset_should_output_correct_timezone() { + $timezone_formats = 'P I O T Z e'; + $timezone_string = 'America/Regina'; + $datetimezone = new DateTimeZone( $timezone_string ); + update_option( 'timezone_string', '' ); + $offset = $datetimezone->getOffset( new DateTime() ) / 3600; + update_option( 'gmt_offset', $offset ); + $datetime = new DateTime( 'now', $datetimezone ); + $datetime = new DateTime( $datetime->format( 'P' ) ); + + $this->assertEquals( $datetime->format( $timezone_formats ), date_i18n( $timezone_formats ) ); + } }