PrimuS
PrimuS

Reputation: 2683

Wrong Timestamp/Timezone conversion

I have a DateTime from my MySQL Database which I convert to a Unix TimeStamp with Twig:

In DB: 2016-06-22 00:00:00

In Twig as TimeStamp: dbEntry.start|date('U') ==> 1466546400

In Twig as Date dbEntry.start|date('Y-m-d H:i) ==> 2016-06-22 00:00

Doublechecking that timestamp here http://www.gaijin.at/olsutc.php says that the timestamp is local time.

I send this timestamp via AjaxCall to my Backend, where this happens:

$dateDB = \DateTime::createFromFormat('U',$date)->format('Y-m-d H:i');
dump($dateDB);

($date being 1466546400)

Output

2016-06-21 22:00

In all my php.ini files I set the timezone to Europe/Berlin, but the resulting timestamp is clearly UTC. Even setting the timezone manually with

$dateDB = \DateTime::createFromFormat('U',$date,new \DateTimeZone('Europe/Berlin'))->format('Y-m-d H:i');
    dump($dateDB);

leads to 2016-06-21 22:00 as well.

How does this happen, and where can I start to look for it, besides the php.ini files?

Side Note

I see that this has been addresses here PHP timestamps & timezone configuration as well, I could just manually add 7200 seconds, but would that still be correct in Winter due to DailightSavingTime?

Upvotes: 3

Views: 1173

Answers (1)

Álvaro González
Álvaro González

Reputation: 146350

The issue comes from the fact that createFromFormat() is ignoring its third argument (time zone) by design:

Note: The timezone parameter and the current timezone are ignored when the time parameter either contains a UNIX timestamp (e.g. 946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).

Here's a cleaner test case:

$dt = new DateTime('2016-06-22 00:00:00', new DateTimeZone('Europe/Berlin'));
$dt2 = DateTime::createFromFormat('U', $dt->getTimestamp(), new \DateTimeZone('Europe/Berlin'));
var_dump($dt->format('c'), $dt2->format('c'));
string(25) "2016-06-22T00:00:00+02:00"
string(25) "2016-06-21T22:00:00+00:00"

Here, you'd need to change time zone afterwards (default time zone is only used when no time zone information exists):

$dt2->setTimeZone(new DateTimeZone('Europe/Berlin'));

Upvotes: 3

Related Questions