Timezone getting ignored on the command line - php

The output of the following is two identiacal lines of UTC
date_default_timezone_set('Europe/London');
$datetime = new DateTime();
echo "\n" . $datetime->format('U');
$datetime->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo "\n" . $datetime->format('U');
They should obviously be different, and neither should be UTC!
As well as setting the timezone in the code, its set in php.ini as
date.timezone = 'Europe/London'
PHP version is PHP 5.6.30, and all appears to be working when you use the web-browser, running on OS X.

They should obviously be different, and neither should be UTC!
Completely wrong. Twice.
The U format specifier of DateTime::format() prints the date as a timestamp. As the documentation explains in the "Description" column, its meaning is "Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)"
You don't change the date or time stored in the $datetime object between the two calls to DateTime::format(), it is still the same date. The number of second passes since the Unix Epoch didn't change. There is no reason for the second call to DateTime::format() to print a different value.
Changing the timezone doesn't affect the date. It affects only how the date is represented using date & time components (years, months, days, hours, minutes, seconds, timezone).
A timestamp is an absolute representation of a date. It represents the number of seconds that passed since a fixed moment in the past. It doesn't depend on timezones.
Change the formatting to:
echo($datetime->format('U: Y-m-d H:i:s e')."\n");
and see for yourself:
1504791287: 2017-09-07 14:34:47 Europe/London
1504791287: 2017-09-08 02:19:47 Pacific/Chatham

Related

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?
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'));

ISO date formats to wrong day

Short question but I can't get my finger on it. This piece of code:
$date = '2015-12-08T00:00:00+01:00';
echo date('D', strtotime($date));
returns Mon while
$date = '2015-12-08T00:00:00';
echo date('D', strtotime($date));
returns Tue. Why is that? The +01:00 is for the timezone, but that should not affect the day in my opinion.
First I've looked up that 08-12-2015 is in fact a Tuesday, so now we know the first one is incorrect.
PHP's date() is an Unix timestamp according to their own docs.
My belief is that adding the +1 as a timezone triggers the calculation to the +0 timezone (UTC) when asking for the day of the week and therefore returns 23:00 on monday as the current UTC time.
You can specify the timezone before executing the rest of the code: date_default_timezone_set('Europe/Amsterdam');
<?php
date_default_timezone_set('Europe/Amsterdam'); //this is an example of a +1 timezone, choose one from http://php.net/manual/en/timezones.php
$date = '2015-12-08T00:00:00+01:00';
echo date('D', strtotime($date) );
?>
strtotime will parse your date string using the supplied time zone or using the default timezone if unspecified. We can't see from the code you've posted what time zone your server is configured to, but once the date is parsed and converted to your time zone, the time may legitimately occur in the previous day, hence why you're seeing 'Mon'.
Either supply a time zone in the strtotime call via the now argument or set one globally with date_default_timezone_set.

PHP date timestamp timezone not converted properly

So I have this code:
$timestamp = 1414708099;
echo $timestamp;
$date = date_make_date($timestamp, 'UTC', 'datestamp');
date_timezone_set($date, timezone_open('America/New_York'));
$timestamp = $date->format('U');
echo '<br>';
echo $timestamp;
which is supposed to convert the timezone of the initial timestamp from UTC to new york.
but then this ends up printing
1414708099<br>1414708099
hence the timezone didnt change...
what did I do wrong?
btw it also uses Drupal 6 date_api.module: http://drupalcontrib.org/api/drupal/contributions!date!date_api.module/function/date_make_date/6
As per comments
A timestamp is always UTC. You can't apply a time zone to a timestamp - consider its timezone as 0. Whatever you do, it stays 0. You asked for a date formatted with U - manual states this:
U: Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
You can't get seconds from Unix Epoch for New York. That number is the same for any location in the world.
Now, had you formatted that date using, say, $date->format('Y-m-d H:i:s') then you would get correctly formatted time with the timezone offset for New York.
Long story short - there is no problem whatsoever here. It all works as intended.

PHP date() function ignores the timestamp parameter

The output of the following program can be seen here: http://codepad.org/egNGJBUL
<?php
/* Checking if time() is really timezone independent */
date_default_timezone_set('UTC');
echo time();
echo "\n";
date_default_timezone_set('Australia/Queensland');
echo time();
echo "\n";
/* Using date() function passing timestamp parameter */
date_default_timezone_set('UTC');
echo date('Y-m-d H:i:s',time());
echo "\n";
date_default_timezone_set('Australia/Queensland');
echo date('Y-m-d H:i:s',time());
echo "\n";
/* Using date() function without passing timestamp parameter */
date_default_timezone_set('UTC');
echo date('Y-m-d H:i:s');
echo "\n";
date_default_timezone_set('Australia/Queensland');
echo date('Y-m-d H:i:s');
echo "\n";
From line 1-2 of the output, we can see time() returns a value which is really timezone independent.
In line 3-4, it's strange that date() function ignores the timestamp parameter and still display the date time according to the timezone set.
Why is it like this?
Not really sure what you are expecting to see, but yes, looks very normal to me.
A timestamp is a integer counted from a certain point in time (usually the UNIX EPOCH). While the display of this value is timezone independent, it is no more or less so that say, the value of a properly formatted date, notated with a timezone, is timezone independent...
example, all of the following statements are both true (logically)
1297799809 == 1297799809
2011-02-15 19:56:49 (UTC) == 2011-02-16 05:56:49 (Austria/Queensland)
All time is 'timezone independant'. Timezones only affect the way we display a particular moment in time.
date() functions second parameter, if not specified, is time() value.
date() Returns a string formatted according to the given format string using the given integer timestamp or the current time if no timestamp is given. In other words, timestamp is optional and defaults to the value of time().
from date()'s manual
So actually nothing is being ingnored.
The date function returns the date of a timestamp calculated for the current timezone, as others have said, if no timestamp is passed to it, then the current time is used for the timestamp, so passing time() is the same as not passing anything at all.
However, doing something like $time = time();sleep 5;echo date($format,$time); will get you a date 5 seconds in the past.
It's meant to display the date formatted for current timezone so you can have a universal method of keeping time that's constant across computers/servers and be easily parsable, and yet be able to display the date in any timezone desired.
The UTC timezone is actually the time that the timestamp is calculated to, more precisely, the number of seconds since 00:00 Jan 1, 1970 UTC, then it adds or subtracts 3600 (60*60) seconds from/to the timestamp per hour offset from UTC time to get the time in the currently set timezone.

PHP DateTime Inconsistency? What am I missing?

Using PHP 5.2.5 I was working with some DateTime objects and noticed a time that seemed off. The problem I'm having may be related to timezones, but I'm not sure - I'm creating a DateTime from a Unix Time Stamp and getting different/unexpected results depending on how I output it.
I created the following to easily illustrate the "issue":
$timezone = new DateTimeZone('America/Chicago');
$now = time();
$now_datetime = new DateTime('#' . $now, $timezone);
echo phpversion() . "\n\n";
echo $now . "\n";
echo $now_datetime->format('U') . "\n\n";
echo date('g:i:sa', $now) . "\n";
echo $now_datetime->format('g:i:sa') . "\n\n";
This outputs the following:
5.2.5
1287676530
1287676530
10:55:30am
3:55:30pm
I'm currently in the correct timezone, and the server shows the "right" time (10am) when using the date() function to output a formatted date, as well as 'America/Chicago' being the default timezone on that machine. But, when outputting values via DateTime::format(), the times are very different.
I added the ->format('U') just to verify that it was holding the correct timestamp.
So, I'm probably doing something wrong or I have the wrong expectations. So what am I missing?
It seems like a timezone issue with DateTime, but if that's the case, why does it show "now" in America/Chicago as ... wrong?
The timezone you 'insert' into DateTime is the timezone of the string, which may not be your current timezone, so PHP can calculate the actual datetime, not the timezone it uses to format your output. If you want it to output the time in a specific timezone, use $now_datetime->setTimezone($timezone).
The manual on DateTime's constructor has the answer:
The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp (e.g. #946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).
This means that your timestamp is treated as a GMT one, explaining the 7 hours' difference.

Categories