php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63234 DateTime::createFromFormat() with a Unix timestamp can be one day off
Submitted: 2012-10-08 06:21 UTC Modified: 2017-03-19 10:47 UTC
Votes:3
Avg. Score:3.7 ± 0.9
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:2 (66.7%)
From: christopher dot jf dot hopper at gmail dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 5.3.17 OS: Linux 2.6.32-220.17.1.el6.i686
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: christopher dot jf dot hopper at gmail dot com
New email:
PHP Version: OS:

 

 [2012-10-08 06:21 UTC] 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


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-11-10 01:29 UTC] 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.
 [2017-03-19 10:47 UTC] heiglandreas@php.net
-Status: Open +Status: Not a bug
 [2017-03-19 10:47 UTC] heiglandreas@php.net
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.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 03:01:32 2025 UTC