Signature
gmdate(string $format, ?int $timestamp = null): stringPurpose
gmdate() turns a Unix timestamp into a formatted string in Greenwich Mean Time (GMT/UTC). It works like date(), with one difference: date() converts the timestamp into the script's default timezone, while gmdate() always uses UTC. That makes it a good choice when output must not depend on server configuration, for example in logs, cache keys, protocol headers or stored values.
Signature
Parameters and defaults
$formatis the pattern describing the output. It uses the same format characters asdate(), such asY(four-digit year),m(month with leading zero),d(day with leading zero),H,iands.$timestampis an optional integer Unix timestamp. If you omit it or passnull, PHP uses the current time, astime()would. Since PHP 8.0.0 the parameter is explicitly nullable.
Because the default depends on the current time, the examples below always pass a fixed timestamp so the results are repeatable.
Return value and failure cases
The function returns a string. Passing a value that cannot be used as an integer timestamp, such as a non-numeric string, raises a TypeError. Unrecognized format characters are not an error; they are copied to the output unchanged, which is why letters you want printed literally should be escaped with a backslash.
Example 1: the Unix epoch
Timestamp 0 is the start of the Unix epoch. In UTC that is midnight on 1 January 1970.
echo gmdate("Y-m-d H:i:s", 0), "\n";1970-01-01 00:00:00
Example 2: date() versus gmdate()
The next script sets a non-UTC default timezone. The same timestamp is shown through both functions. date() follows the default timezone, so the result is shifted and even lands on a different calendar day. gmdate() ignores the setting.
date_default_timezone_set('Europe/Helsinki');
$ts = 1700000000;
echo date('Y-m-d H:i:s', $ts), "\n";
echo gmdate('Y-m-d H:i:s', $ts), "\n";2023-11-15 00:13:20 2023-11-14 22:13:20
Example 3: calendar details and escaping
Format characters can expose more than the visible date. Here l is the full weekday name, L is 1 in a leap year, t is the number of days in the month, and z is the zero-based day of the year. The timestamp is 29 February 2000 at midnight UTC.
echo gmdate('Y-m-d l L t z', 951782400), "\n";
echo gmdate('D, d M Y H:i:s \G\M\T', 86400 * 365), "\n";2000-02-29 Tuesday 1 29 59 Fri, 01 Jan 1971 00:00:00 GMT
The second line shows escaping: \G\M\T prints the literal letters GMT instead of treating them as format characters. This is the usual way to build an HTTP-style date string by hand.
Edge cases
- Default timezone has no effect on the result. Changing it with
date_default_timezone_set()affectsdate()but notgmdate(). - Omitting the timestamp reads the clock. Anything built on it is non-deterministic, so pass an explicit timestamp in tests.
- Literal text needs escaping. Letters such as
T,Dordmean something to the formatter. Prefix each literal letter with a backslash, and remember that inside a double-quoted PHP string the backslash itself has to be written as\\in some cases. Single quotes are often easier. - The input is a timestamp, not a date string. To format text such as
2024-05-01, convert it first, for example withgmmktime()or aDateTimeImmutableobject. - Timestamps before 1970 are negative integers and format as earlier dates.
Common mistakes
- Assuming
gmdate()anddate()match. They only match when the default timezone is already UTC. Code that appears to work on one server may differ on another. - Building a timestamp with
mktime()and formatting it withgmdate().mktime()interprets its arguments in the default timezone, whilegmdate()prints UTC, so the printed hour can differ from the one you supplied. Usegmmktime()when both sides should be UTC. - Passing milliseconds. Many systems, including JavaScript, produce millisecond timestamps.
gmdate()expects seconds, so divide by 1000 and cast tointfirst. - Forgetting to escape literal characters. An unescaped letter in the format may be replaced by a date part.
- Expecting timezone names to be consistent. If you need to show a zone label, prefer a literal escaped suffix like
\G\M\Tor\U\T\Cthat you control.
Related functions
date()formats a timestamp in the default timezone.mktime()builds a timestamp from local date parts.gmmktime()builds a timestamp from GMT date parts.DateTimeImmutable::__construct()creates an object-based date value.DateTimeInterface::format()formats date objects with the same format syntax.
Recap
gmdate() takes a format string and an optional integer timestamp and returns a UTC-formatted string. Use it when the output must be independent of the configured timezone, pass fixed timestamps for predictable results, escape literal letters, and pair it with gmmktime() rather than mktime() when building timestamps from date parts.
Tested examples
echo gmdate("Y-m-d H:i:s", 0), "\n";
1970-01-01 00:00:00
date_default_timezone_set('Europe/Helsinki');
$ts = 1700000000;
echo date('Y-m-d H:i:s', $ts), "\n";
echo gmdate('Y-m-d H:i:s', $ts), "\n";
2023-11-15 00:13:20 2023-11-14 22:13:20
echo gmdate('Y-m-d l L t z', 951782400), "\n";
echo gmdate('D, d M Y H:i:s \G\M\T', 86400 * 365), "\n";
2000-02-29 Tuesday 1 29 59 Fri, 01 Jan 1971 00:00:00 GMT