简体   繁体   中英

gmdate not constant across servers?

I've been working on a application that needs to do a lot of calculations with time.

To keep everything working a supposed to, I started with:

$dateToday = strtotime(gmdate("m/d/y"));

As I understood, this is supposed to return the GMT date. So whichever timezone the server is in, I should get the same time?

So, as I developed on localhost everything worked smoothly, but when I moved to a server in a different timezone, I started getting problems.

Echo'ing "$dateToday" on localhost gives me "1501192800", while doing the same on the server I get "1501214400". That is the same as the 6h time difference between my local machine and the server.

So what am I missing here?

Thanks

 $dateToday = strtotime(gmdate("m/d/y")); 

As I understood, this is supposed to return the GMT date.

Not at all.

gmdate() formats a date using the GMT timezone. Since you called it with only one argument, it gets the date to format by calling time() .

time() returns the current timestamp, ie the number of seconds passed since Jan 1, 1970, 0:00:00 UTC .

Then, gmdate() uses the format you provide in its first argument to produce a text representation of its second argument (the current timestamp as we saw). The value returned by gmdate("m/d/Y") is 07/28/2017 .

Then, 07/28/2017 is passed to strtotime() that tries to interpret it as a date and computes a timestamp from it. Because it doesn't contain any time component, strtotime() assumes the time is 0:00:00 .

And here comes the catch. Because the string provided as argument to strtotime() also does not contain any timezone information, PHP uses its configuration to assume a timezone. As you already discovered, running the code on two servers can produce different results because of different configurations.

For me, strtotime(gmdate('m/d/Y')) returns 1501200000 and this is the timestamp (the moment in time) when today ( July 18, 2017 ) started on the UTC timezone (because the PHP I used for testing uses "UTC" as its default timezone ). The values you get on different servers are the time moments when today started on their respective timezones.

If I run the same code with a PHP that is correctly configured for my timezone ( Europe/Bucharest ) I get 1501189200 . It is 10800 seconds before the value I use with UTC because Europe/Bucharest currently is on UTC+3 (the regular +2 of the Eastern Europe Standard Time plus 1 hour because of the Daylight Savings Time.

PHP currently provides a set of classes to handle date and time: DateTime and the other classes whose name start with Date (find them in the documentation). They are easier to use than the old date & time functions and they also know how to handle the timezones (the old functions do not know).

Creating a DateTime object that stores the start of today in UTC timezone is as easy as:

$dateToday = new DateTime("today 0:00:00", new DateTimeZone("UTC"));

You can as well create a DateTime object for "now" (in the desired timezone) and then set its time to 0:00:00 :

$dateToday = new DateTime("now", new DateTimeZone("UTC"));
$dateToday->setTime(0, 0, 0);

For the DateTime objects that are not modified in the code (they are only read) then you better create DateTimeImmutable objects. This class prevents accidental changing of the values it stores.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM