Bug #63234 [Opn->Nab]: DateTime::createFromFormat() with a Unix timestamp can be one day off

From: Date: Sun, 19 Mar 2017 10:47:04 +0000
Subject: Bug #63234 [Opn->Nab]: DateTime::createFromFormat() with a Unix timestamp can be one day off
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-207940@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=63234&edit=1 ID: 63234 Updated by: heiglandreas@php.net Reported by: christopher dot jf dot hopper at gmail dot com Summary: DateTime::createFromFormat() with a Unix timestamp can be one day off -Status: Open +Status: Not a bug Type: Bug Package: Date/time related Operating System: Linux 2.6.32-220.17.1.el6.i686 PHP Version: 5.3.17 Block user comment: N Private report: N New Comment: This is not a bug but related to your timezone settings. The first DateTime-Object you create is created within your default timezone. And as that is east to UTC the 00:00 H is related to your local time. The timestamp though is UTC. The DateTime-Object you then create from the timestamp will use UTC as timezone (as you created it from a timestamp). And in UTC 00:00 your local time is some time *before* that (depending on your offset to UTC). You can see that when you add the following lines to your test-script: echo $d->format('c') . "\n"; echo $e->format('c') . "\n"; As it's not a bug, I'm going to close this issue. Previous Comments: ------------------------------------------------------------------------ [2012-11-10 01:29:00] mail+php at requinix dot net There's a bug here but it's a little different from how you've described it. Take a careful look at the note attached to the $timezone parameter to DateTime's constructor and its createFromFormat(): "The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp..." When you create $e you specify a timestamp and thus the current timezone is ignored. Completely and utterly ignored. echo $d->getTimezone()->getName() . " <-> " . $e->getTimezone()->getName(); Since the timezone is +0 you get a different formatted time than you originally gave to $d. Thus the bug is more that the constructor doesn't set a timezone at all when really it should - even if it doesn't have any impact on the $time itself. To work around this for now you can set the timezone in $e, or even easier use setTimestamp() as you've shown. ------------------------------------------------------------------------ [2012-10-08 06:21:51] christopher dot jf dot hopper at gmail dot com Description: ------------ == PHP Version Information == # php --version PHP 5.3.3 (cli) (built: May 7 2012 19:58:17) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans # cat /proc/version Linux version 2.6.32-220.17.1.el6.i686 (mockbuild@c6b5.bsys.dev.centos.org) (gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) ) #1 SMP Tue May 15 22:09:39 BST 2012 == Describing The Problem == When using the static method DateTime::createFromFormat() or the new DateTime() constructor to create a DateTime object instance from a Unix Timestamp, the resulting date can be one day out, even though the timestamp is not. To reproduce the bug, run the test script below. Test script: --------------- <?php // Bad $d=DateTime::createFromFormat("!Y-m-d H:i:s", "2012-11-30 00:00:00"); echo $d->getTimestamp() . PHP_EOL; echo $d->format("Y-m-d") . PHP_EOL; $e=new DateTime("@". $d->getTimestamp()); echo $e->getTimestamp() . PHP_EOL; echo $e->format("Y-m-d") . PHP_EOL . PHP_EOL; /* 1354194000 2012-11-30 1354194000 2012-11-29 */ // Bad $d=DateTime::createFromFormat("!Y-m-d H:i:s", "2012-11-30 00:00:00"); echo $d->getTimestamp() . PHP_EOL; echo $d->format("Y-m-d") . PHP_EOL; $e=DateTime::createFromFormat("U", $d->getTimestamp()); echo $e->getTimestamp() . PHP_EOL; echo $e->format("Y-m-d") . PHP_EOL . PHP_EOL; /* 1354194000 2012-11-30 1354194000 2012-11-29 */ // Good $d=DateTime::createFromFormat("!Y-m-d H:i:s", "2012-11-30 00:00:00"); echo $d->getTimestamp() . PHP_EOL; echo $d->format("Y-m-d") . PHP_EOL; $e=new DateTime(); $e->setTimestamp($d->getTimestamp()); echo $e->getTimestamp() . PHP_EOL; echo $e->format("Y-m-d") . PHP_EOL; /* 1354194000 2012-11-30 1354194000 2012-11-30 */ Expected result: ---------------- 1354194000 2012-11-30 1354194000 2012-11-30 1354194000 2012-11-30 1354194000 2012-11-30 1354194000 2012-11-30 1354194000 2012-11-30 Actual result: -------------- 1354194000 2012-11-30 1354194000 2012-11-29 1354194000 2012-11-30 1354194000 2012-11-29 1354194000 2012-11-30 1354194000 2012-11-30 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=63234&edit=1

« previous php.bugs (#207940) next »