Edit report at https://bugs.php.net/bug.php?id=63234&edit=1
ID: 63234
Comment by: mail+php at requinix dot 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
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:
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.
Previous Comments:
------------------------------------------------------------------------
[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 ([email protected])
(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