Does PHP Time() Return a Gmt/Utc Timestamp

Does PHP time() return a GMT/UTC Timestamp?

time returns a UNIX timestamp, which is timezone independent. Since a UNIX timestamp denotes the seconds since 1970 UTC you could say it's UTC, but it really has no timezone.


To be really clear, a UNIX timestamp is the same value all over the world at any given time. At the time of writing it's 1296096875 in Tokyo, London and New York. To convert this into a "human readable" time, you need to specify which timezone you want to display it in. 1296096875 in Tokyo is 2011-01-27 11:54:35, in London it's 2011-01-27 02:54:35 and in New York it's 2011-01-26 21:54:35.

In effect you're usually dealing with (a mix of) these concepts when handling times:

  • absolute points in time, which I like to refer to as points in human history
  • local time, which I like to refer to as wall clock time
  • complete timestamps in any format which express an absolute point in human history
  • incomplete local wall clock time

Visualise time like this:

-------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???

(not to scale)

An absolute point on this line can be expressed as:

  • 1296096875
  • Jan. 27 2011 02:54:35 Europe/London

Both formats express the same absolute point in time in different notations. The former is a simple counter which started roughly here:

                          start of UNIX epoch
|
-------+-------------------+------++--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???

The latter is a much more complicated but equally valid and expressive counter which started roughly here:

              start of Gregorian calendar
|
-------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???

UNIX timestamps are simple. They're a counter which started at one specific point in time and which keeps increasing by 1 every second (for the official definition of what a second is). Imagine someone in London started a stopwatch at midnight Jan 1st 1970, which is still running. That's more or less what a UNIX timestamp is. Everybody uses the same value of that one stopwatch.

Human readable wall clock time is more complicated, and it's even more complicated by the fact that it's abbreviated and parts of it omitted in daily use. 02:54:35 means almost nothing on the timeline pictured above. Jan. 27 2011 02:54:35 is already a lot more specific, but could still mean a variety of different points on this line. "When the clock struck 02:54:35 on Jan. 27 2011 in London, Europe" is now finally an unambiguous absolute point on this line, because there's only one point in time at which this was true.

So, timezones are a "modifier" of "wall clock times" which are necessary to express a unique, absolute point in time using a calendar and hour/minute/second notation. Without a timezone a timestamp in such a format is ambiguous, because the clock struck 02:54:35 on Jan. 27 2011 in every country around the globe at different times.

A UNIX timestamp inherently does not have this problem.


To convert from a UNIX timestamp to a human readable wall clock time, you need to specify which timezone you'd like the time displayed in. To convert from wall clock time to a UNIX timestamp, you need to know which timezone that wall clock time is supposed to be in. You either have to include the timezone every single time with each such conversion, or you set the default timezone to be used with date_default_timezone_set.

PHP timestamps & timezone configuration

Using time() is the same as strtotime("now") and you do not need to worry about converting the timezone of the timestamp, as the timestamp has no timezone:

Does PHP time() return a GMT/UTC Timestamp?

time returns a UNIX timestamp, which is timezone independent. Since
a UNIX timestamp denotes the seconds since 1970 UTC you could say it's
UTC, but it really has no timezone.

You can then store that timestamp in your database. When you retrieve it you can convert it to the users timezone. With something like this:

date_default_timezone_set('UTC');

$timestamp = '1429066967';
//Supported Timezones: http://php.net/manual/en/timezones.php
$userTimezone = 'America/Los_Angeles';

$dt = new DateTime();
// Set the timestamp
$dt->setTimestamp($timestamp);
// Set the timezone
$dt->setTimezone(new DateTimeZone($userTimezone));
// Format the date
$date = $dt->format('Y-m-d H:i:s');

echo $date;

Outputs: 2015-04-14 20:02:47

But if you only have the UTC offset you could try this:

date_default_timezone_set('UTC');

$timestamp = '1429066967';
$offset = -8;
$userTimezone = timezone_name_from_abbr("", $offset*3600, false);


$dt = new DateTime();
// Set the timestamp
$dt->setTimestamp($timestamp);
// Set the timezone
$dt->setTimezone(new DateTimeZone($userTimezone));
// Format the date
$date = $dt->format('Y-m-d H:i:s');

echo $date;

Which also outputs: 2015-04-14 20:02:47

MySQL and PHP UTC time differs when in number format

Timezone processing can be a pain in the xss neck.

  • 1632383646 is 07:54:06 UTC, 09:54:06 CET
  • 1632390846 is 09:54:06 UTC, 11:54:06 CET

php's time() always returns the UNIX timestamp number (like 1632390846) in UTC. UNIX timestamps are always in UTC. (As long as your machine has its local time zone configured correctly.)

But, php's strtotime() function takes a date/time string 2021-09-23 09:54:06 as if it were in local time and converts it to a UNIX timestamp. Your machine is set to CET (+02:00), so strtime() subtracted two hours to get the timestamp, which is assumed always to be in UTC.

Application design wise, you may be wise to use MySQL to do all your timezone handling. It's set up remarkably well for that task.

  1. Use TIMESTAMP data types throughout. That way all your stored date/time values will be in UTC.

  2. If you're going global, ask each user to choose her time zone preference, with a string like Europe/Amsterdam or Asia/Kolkata. See this.

  3. When you run queries to your database on behalf of users, first give this MySQL statement

    SET time_zone = ###user-preference-string###

    and all your query results will be in local time.

  4. When you run database maintenance queries, first say

    SET time_zone = 'utc'

    and your output will be in UTC.

UNIX timestamp always in GMT?

yep, UNIX timestamp represents how much seconds past from unix-time epoch in GMT+0

UTC to local time adjustment woes with PHP

PHP's time() function will always return seconds since the epoch. The culprit for getting unexpected behavior is actually the date() function.

PHP's date() function will automatically convert the date to the current default timezone of PHP, which must be GMT - 3. This is why when you subtract 8 hours you're 5 hours behind.

Instead of using date(), you probably want to check in to gmdate(). Something like:

echo(gmdate("n/j/Y, g:i:s A", time() - 28800));

may be what you need.

Why is the local timestamp equal to the UTC timestamp?

Because timestamps are seconds since the Unix Epoch (January 1 1970 00:00:00 GMT). Notice the GMT? No matter what time zone you're in, the timestamp is relative to that time and timezone.

What you really want to do is:

$local = new DateTime();
$local->setTimeZone(new DateTimeZone('America/Los_Angeles'));
$gmt = new DateTime();
$gmt->setTimeZone(new DateTimeZone('UTC'));
var_dump($local === $gmt);


Related Topics



Leave a reply



Submit