FreeAI.DevTools

Epoch Converter in PHP

Convert Unix timestamps to dates and back in PHP: the idiomatic code, the gotchas, and a live converter.

How do you convert a Unix timestamp to a date in PHP?

Construct new DateTimeImmutable("@" . $ts); the @ prefix means epoch seconds and always yields UTC regardless of date.timezone. Going back, call $dt->getTimestamp(). PHP counts in seconds, so divide 13-digit JavaScript milliseconds by 1000 before the @ construction or the date is wildly wrong.

Epoch to date (PHP)
<?php
$ts = 1777010400;
$dt = new DateTimeImmutable("@$ts"); // @ prefix: epoch seconds, always UTC
echo $dt->format(DATE_ATOM); // 2026-04-24T06:00:00+00:00
Date to epoch (PHP)
<?php
$dt = new DateTimeImmutable("2026-04-24 06:00:00", new DateTimeZone("UTC"));
echo $dt->getTimestamp(); // 1777010400
Now:

The @ prefix ignores your timezone, everything else obeys it

PHP has a split personality on timezones. Construct a DateTimeImmutable from an @-prefixed epoch and you always get UTC, full stop, because an epoch is timezone-independent by definition. Construct one from a wall-clock string like "2026-04-24 06:00:00" without an explicit DateTimeZone and PHP falls back to the date.timezone ini setting, which differs between your dev container, your CI runner, and shared hosting. That asymmetry is why the same code produces different getTimestamp() values in different environments. The fix is mechanical: pass a DateTimeZone to every string-based constructor, and treat any bare strtotime() call in a code review as a smell.

Prefer DateTimeImmutable over date() and DateTime

The procedural date($format, $ts) function still works and still renders in the ini timezone, but the object API is safer for anything beyond a one-off echo. Choose DateTimeImmutable over DateTime: the mutable version's modify() and setTimezone() change the object in place, so a helper that adjusts a date for display quietly corrupts the caller's copy too. Immutable methods return new objects, and ->getTimestamp() returns an int of epoch seconds on both. On 64-bit builds, which is every modern PHP deployment, that int sails past 2038 without issue.

Frequently asked

Why does strtotime give a different timestamp on my server than locally?
strtotime interprets wall-clock strings in the date.timezone ini setting, and your server and laptop are configured differently. Use new DateTimeImmutable($string, new DateTimeZone("UTC")) so the zone is explicit in code instead of inherited from php.ini.
How do I convert milliseconds to a date in PHP?
Divide by 1000 first, since PHP counts epoch seconds: new DateTimeImmutable("@" . intdiv($ms, 1000)). If you need the sub-second part, use DateTimeImmutable::createFromFormat("U.u", sprintf("%.6f", $ms / 1000)) to keep microseconds.
What is the difference between DateTime and DateTimeImmutable?
DateTime mutates in place: modify() and setTimezone() change the original object, so shared references pick up edits they never asked for. DateTimeImmutable returns a new object from every modification, which makes date math safe to pass around. Prefer it in all new code.

More in this series

// The subscription desk

The Inference Report

The weekly briefing for AI engineers: model releases, pricing moves, benchmarks, and the news that changes what you should build with and what it costs. Every Tuesday, 5-minute read. No fluff.

Join AI engineers who stopped overpaying for tokens. Unsubscribe anytime.