I need help with PHP DateTime with TimeZone converting to MongoDB\BSON\UTCDateTime. If I have string "2015-10-20T04:02:00.608000+01:00" it gives me a DateTime
$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', $string );
DateTime
date => "2015-10-20 04:02:00.608000"
timezone_type => 1
timezone => "+01:00"
If I convert it to MongoDB\BSON\UTCDateTime and convert back to PHP DateTime
$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
$mDate->toDateTime()->setTimeZone(new DateTimeZone('Europe/Bratislava'))
I will get a correct result 05:02
DateTime
date => "2015-10-20 05:02:00.000000"
timezone_type => 3
timezone => "Europe/Bratislava"
BUT if the input string has +02:00 TimeZone "2015-10-20T04:02:00.608000+02:00" and use the same approach the result is
DateTime
date => "2015-10-20 04:02:00.000000"
timezone_type => 3
timezone => "Europe/Bratislava"
Why is the second result 04:02 if I expect 06:02?
The response is correct. When you are adding a +
timezone onto the timestamp, you are, in effect going East from UTC. You are not adding to the UTC time, you are actually subtracting from what the time is in UTC. This means that 2015-10-20T04:02:00.608000+01:00
is 3am UTC. 2015-10-20T04:02:00.608000+02:00
is 2am UTC. You can see this more easily if you keep going higher with your timezone offsets
$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', "2015-10-20T04:02:00.608000+01:00");
$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
var_dump($date, $mDate->toDateTime());
object(DateTime)#1 (3) {
["date"]=>
string(26) "2015-10-20 04:02:00.608000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+01:00"
}
object(DateTime)#3 (3) {
["date"]=>
string(26) "2015-10-20 03:02:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.uT', "2015-10-20T04:02:00.608000+02:00");
$mDate = new \MongoDB\BSON\UTCDateTime( $date->format('U') * 1000 );
var_dump($date, $mDate->toDateTime());
object(DateTime)#1 (3) {
["date"]=>
string(26) "2015-10-20 04:02:00.608000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+02:00"
}
object(DateTime)#3 (3) {
["date"]=>
string(26) "2015-10-20 02:02:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
MongoDB stores the UTC timestamp. When you are adding the Europe/Bratislava
timezone, you are saying, "What time is in Bratislava for this UTC timestamp". For October (daylight savings time), it's a 1 hr difference.
On a side note. Try to never mix +XXXX
and Unicode/Olson timezones (Europe/Bratislava
). You will wind up with some very strange errors due to daylight savings time. If you need to record a user's local time to display back at some point, Create your DateTime
objects with the optional 3rd parameter like:
$customerTz = 'Europe/Bratislava';
$date = DateTime::createFromFormat( 'Y-m-d\TH:i:s.u', $dateString, $customerTz);
Also check to see if you really need to create a DateTime
at all, or just a new UTCDateTime
directly with a timestamp and deal with the tz's in the display logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With