php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79863 Timezone conversion result depends on environment
Submitted: 2020-07-15 09:01 UTC Modified: 2020-07-25 20:31 UTC
From: bassjoe at web dot de Assigned:
Status: Open Package: Date/time related
PHP Version: 7.4.8 OS: CentOS Linux 7
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-07-15 09:01 UTC] bassjoe at web dot de
Description:
------------
WordPress uses (in wp-includes/formatting.php) the following PHP function calls to convert Date/Time objects to a different timezone (simplified):

    function get_gmt_from_date( $string ) {
        $datetime = date_create( $string, wp_timezone() );
        return $datetime->setTimezone( new DateTimeZone( 'UTC' ) )->format( 'Y-m-d H:i:s' );
    }

This fails on my Strato/CentOS7 Server (PHP 7.4.8) because get_gmt_from_date() returns the same value that is given as $string argument.  I can easily reproduce this with the following command on the console:

    php -r '$datetime = date_create("2020-07-13 10:38:15", new DateTimeZone("Europe/Berlin"));  echo $datetime->setTimezone( new DateTimeZone( "UTC" ) )->format( "Y-m-d H:i:s\n" );'
    
    2020-07-13 10:38:15

On my Fedora 31 workstation (also PHP 7.4.8) the same command returns the correct result:

    2020-07-13 08:38:15

I installed CentOS 7 on a VM but could not reproduce the error.  This means the result of these PHP functions depends on the server configuration.

The result of a timezone conversion obviously should not depend on the environment.

The effect I have noticed in WordPress is that changes in the Customizer can't be published immediately.

Test script:
---------------
php -r '$datetime = date_create("2020-07-13 10:38:15", new DateTimeZone("Europe/Berlin"));  echo $datetime->setTimezone( new DateTimeZone( "UTC" ) )->format( "Y-m-d H:i:s\n" );'

Expected result:
----------------
2020-07-13 08:38:15

Actual result:
--------------
2020-07-13 10:38:15

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-15 09:10 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-07-15 09:10 UTC] requinix@php.net
What is the value being returned by wp_timezone()?
 [2020-07-15 09:17 UTC] bassjoe at web dot de
-Status: Feedback +Status: Open
 [2020-07-15 09:17 UTC] bassjoe at web dot de
"Europe/Berlin"
 [2020-07-15 09:22 UTC] bassjoe at web dot de
wp_timezone()->getName() is what I logged and it was "Europe/Berlin"
 [2020-07-17 13:37 UTC] antonino dot spampinato86 at gmail dot com
<?php
$datetime = date_create("2020-07-13 10:38:15", timezone_open("Europe/Berlin")); date_timezone_set( $datetime, timezone_open( "UTC" ) ); date_format( $datetime, "Y-m-d H:i:s" ); var_dump($datetime);

Expected result:
----------------
object(DateTime)#5 (3) {
  ["date"]=>
  string(26) "2020-07-13 08:38:15.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}
timezone now is UTC?
 [2020-07-17 19:21 UTC] bassjoe at web dot de
The result is the same with this command sequence.

Workstation (correct):

    $ php -r '$datetime = date_create("2020-07-13 10:38:15", timezone_open("Europe/Berlin")); date_timezone_set( $datetime, timezone_open( "UTC" ) ); date_format( $datetime, "Y-m-d H:i:s" ); var_dump($datetime);'
    Command line code:1:
    class DateTime#2 (3) {
      public $date =>
      string(26) "2020-07-13 08:38:15.000000"
      public $timezone_type =>
      int(3)
      public $timezone =>
      string(3) "UTC"
    }

Server (wrong):

    $ php -r '$datetime = date_create("2020-07-13 10:38:15", timezone_open("Europe/Berlin")); date_timezone_set( $datetime, timezone_open( "UTC" ) ); date_format( $datetime, "Y-m-d H:i:s" ); var_dump($datetime);'
    object(DateTime)#2 (3) {
      ["date"]=>
      string(26) "2020-07-13 10:38:15.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(3) "UTC"
    }
 [2020-07-25 20:31 UTC] bassjoe at web dot de
Now this is very strange.  I get the correct result if I check out PHP 7.4.8 (same version as the REMI packages) from Git, compile it on CentOS 7, and run this php executable on the server. So in the same environment and while ignoring php.ini (with -n) I get different results for the same version.

# installed from remi repo:
# php-cli-7.4.8-2.el7.remi.x86_64
# php-7.4.8-2.el7.remi.x86_64

$ php --version
PHP 7.4.8 (cli) (built: Jul  9 2020 08:57:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies


$ php -n -r '$datetime = date_create("2020-07-13 10:38:15", new DateTimeZone("Europe/Berlin")); var_dump($datetime); $datetime->setTimezone( new DateTimeZone( "UTC" ) ); var_dump($datetime);'

object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2020-07-13 10:38:15.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}
object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2020-07-13 10:38:15.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}


# self-compiled on centos 7 => correct result

$ sapi/cli/php --version
PHP 7.4.8 (cli) (built: Jul 25 2020 22:12:24) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies


$ sapi/cli/php -n -r '$datetime = date_create("2020-07-13 10:38:15", new DateTimeZone("Europe/Berlin")); var_dump($datetime); $datetime->setTimezone( new DateTimeZone( "UTC" ) ); var_dump($datetime);'

object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2020-07-13 10:38:15.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}
object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2020-07-13 08:38:15.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Oct 26 05:01:24 2020 UTC