Reputation: 144
$datetime = new DateTime( gmdate('Y-m-d H:i:s'), new DateTimeZone('UTC') );
$past_time = $datetime->createFromFormat( 'Y-m-d H:i:s', $past_time )->getTimestamp();
echo 'Past formed: ' . gmdate('H:i:s', $past_time ) . '<br><br>';
Is outputting:
2016-09-09 14:42:50
Past formed: 12:42:50
$past_time = $row->date_added;
Where date added is in a MySQL database and is equal to:
2016-09-09 14:42:50
I'm not changing the timezone, I'm merely converting a timestamp back into gmdate()
At which point is the time having 2 hours taken off it and how do I prevent it?
Edit
$datetime = new DateTime( gmdate('Y-m-d H:i:s'), new DateTimeZone('UTC') );
$past_time = $datetime->createFromFormat( 'Y-m-d H:i:s', $past_time, new DateTimeZone('UTC') )->getTimestamp();
echo 'Past formed: ' . gmdate('H:i:s', $past_time ) . '<br><br>';
This was the solution, I had to set the timezone despite never changing it
It must make sense in a round-a-bout way, but I still don't really understand where DateTime is getting its "from and to"
Upvotes: 1
Views: 74
Reputation: 522005
2016-09-09 14:42:50
is an incomplete timestamp, it is missing the timezone information. Without timezone information, this timestamp could refer to any of over 24 different absolute points in time. 14:42:50
in London, England occurs several hours after 14:42:50
in Tokyo, Japan.
DateTime
instances and UNIX timestamps (created with time()
or strtotime()
) are absolute points in time, they don't have and aren't influenced by timezones. When converting 2016-09-09 14:42:50
into one of these absolute timestamps, PHP needs to infer the missing information (the timezone) from somewhere. If you do not supply the information explicitly, it takes it from date_default_timezone_get
.
$datetime = new DateTime( gmdate('Y-m-d H:i:s'), new DateTimeZone('UTC') );
$past_time = $datetime->createFromFormat( 'Y-m-d H:i:s', $past_time )->getTimestamp();
Let's get rid of the completely superfluous $datetime
instance here for simplicity…
$past_time = DateTime::createFromFormat('Y-m-d H:i:s', $past_time)->getTimestamp();
createFromFormat
here is reading the incomplete timestamp and infers its timezone. That is where the mismatch is happening, it assumes a timezone other than what the timestamp actually represents. Hence the result is offset by a few hours. getTimestamp
than merely reformats that into a different, but still absolute, format of a UNIX timestamp.
echo 'Past formed: ' . gmdate('H:i:s', $past_time) . '<br><br>';
gmdate
reads the UNIX timestamp and outputs it converted to the GMT timezone. date
uses the date_default_timezone_get
timezone, gmdate
always uses GMT.
You've got a whole lot of unnecessary conversions going on here. The only thing you really need is:
$timestamp = DateTime::createFromFormat('Y-m-d H:i:s', $past_time, new DateTimeZone('UTC'));
echo 'Past formed: ', $timestamp->format('H:i:s');
2016-09-09 14:42:50
to a DateTime
instance.DateTime
instance in the desired format.Upvotes: 1
Reputation: 3795
Thing the issue is, when calling this line:
echo 'Past formed: ' . gmdate('H:i:s', $past_time ) . '<br><br>';
gmdate() looks up the current DateTimeZone in your PHP script, and acts on that.
So you have to use this first for the global timezone:
date_default_timezone_set()
Test what you have set up print date_default_timezone_get();
Upvotes: 0