Skip to content
Release

A day short: Statamic 6 and time zones

Statamic 6 started handling every control panel date as UTC. For dates without a time, editors could see or even save the wrong day, depending on where they sat. May fixed that, and July closed the gaps around it.

· 8 min read · Thomas Sausen

When Christmas fell on the 24th

Picture an editor in Amsterdam who opens an entry, picks December 25 in a date field, and saves. Statamic stores December 24.

That's the example Duncan McClean used to explain #14552, one of a run of fixes that landed in May. The reports that led there were just as concrete: a site in Rome whose listings showed every date a day early, and a US team whose pages returned 404s because a publish date had jumped a day. Both go back to a decision made the previous summer, when Statamic 6 started moving every date through the control panel as UTC. Making it work for everyone took until this summer, and the first to notice were editors east of UTC. Which, if you're reading this in Europe, means you and your clients.

What Statamic 6 changed

The groundwork is #11409, "Improved Timezone Handling", also by Duncan. It shipped in the first Statamic 6 alpha in August 2025. Along the way it closed several issues that had been open for years, such as an API that ignored the configured time zone.

Why UTC at all? A time without a time zone is ambiguous: 14:00 in Berlin is a different moment from 14:00 in London. A website involves more parties than it seems, from the editor and the server to the content files, the visitors and any app reading the API. Laravel defaults to UTC, as do many hosts, so even a site whose editors all sit in one country converts somewhere. Daylight saving time adds its own trouble: one night a year has an hour that happens twice, another has an hour that never happens. UTC has neither problem. Store and compare in UTC, convert only for display, and a moment means the same thing everywhere.

The model it introduced:

  • In the control panel, dates travel as UTC, and the browser shows them in the editor's own time zone. When the editor changes a date, it goes back to UTC, and on save, to the app time zone.

  • In templates, a date field augments to a UTC Carbon instance. It's converted only on output, using a new display_timezone option in config/statamic/system.php.

  • In modifiers, you're working with UTC unless you put tz at the start of the chain or enable localize_dates_in_modifiers. For upgraded sites that option is on by default.

  • The REST and GraphQL APIs always return UTC.

The recommendation for new sites: leave the app time zone at UTC and set display_timezone instead.

The original plan was to migrate every existing site's dates to UTC during the upgrade. The team dropped that because it would have touched too much content. Existing sites keep storing dates in their app time zone, and the migration became an optional command, php please migrate-dates-to-utc, for anyone who wants to switch.

Why a date moved

The model works for timestamps. It breaks for dates that have no time at all.

On Statamic 6.8, Lorenzo Morici opened #14413 with a precise diagnosis. His site runs on Europe/Rome, with a date field set to time_enabled: false and format Y-m-d. An entry stored as 2026-03-14 showed March 14 in the publish form and on the frontend, but March 13 in the collection listing.

The cause is the UTC step. A date without a time is midnight. Midnight on March 14 in Rome is 23:00 on March 13 in UTC. The listing received that UTC value and had no way of knowing it was meant to be a plain date, so it showed the day before. Every time zone ahead of UTC is affected, which covers almost all of Europe.

Aaron Bushnell added a case from the other side of the Atlantic to the same thread. His team runs the app on UTC, with editors in Mountain and Eastern time. Around 6:30 in the evening, an editor in Eastern time saw the next day in the date picker. Because their pages hide future-dated entries, a page could return a 404 until someone moved its date back by a day.

Jason Varga's first answer was that a format like Y-m-d throws away the time information Statamic 6 needs, and that a workaround was coming. Lorenzo replied that he'd started with the default format and seen the same thing: midnight on March 16 saved as 23:00 on March 15.

May: three fixes and a visible time zone

The answer arrived in the first week of May, mostly in Statamic 6.17.

Plain dates stay plain. #14552 skips time zone conversion entirely when a field's format contains no time. Those values now travel between server and browser as plain Y-m-d strings and are handled as calendar dates without a time zone. Jason fixed the same shift in the listing column in #14602.

You can stop localizing. #14554 lets you pin date fields to a time zone instead of the editor's browser. There's a site-wide default in config/statamic/cp.php:

'default_timezone' => env('STATAMIC_CP_DEFAULT_TIMEZONE', 'auto'),

auto keeps the browser behavior. Any IANA time zone pins every date field to it, and each field can override the default in its settings. This closed two community ideas, #1441 and #1453, that asked for exactly this: a publish date that shows the site's time, wherever the editor sits.

You can see which time you're looking at. Since 6.15, the date picker always shows its time zone (#14518), and the range picker followed. With #14612, hovering a date in a listing shows a small card with the same moment in several time zones: the site's display time zone, your own, and the field's if it has one.

If the site and your browser share a time zone, the second row is greyed out, because it adds nothing. The card only appears for dates with a time. Plain dates don't get one, since they're no longer converted.

July: the edges

The July fixes are about the places a time zone can quietly slip.

Date ranges drifted on every save. Range fields with times didn't honor the field's time zone when saving. Lazizbek Ergashev traced it in #15001, shipped in 6.25. Single dates were interpreted in the field's time zone before being converted to UTC. Ranges skipped that step, so the wall-clock time was treated as UTC. Loading did it correctly, saving didn't, and the stored value moved by the offset each time. His test case: in a field set to New York, entering 05:00 saved 05:00 UTC instead of 09:00 UTC.

Queries compared the wrong moment. whereDate() and whereTime() took a Carbon value and reparsed it in the app's time zone instead of converting it. If the value you passed was in another time zone, the query compared a different instant than you meant. Marco Rieser fixed that in #14940, in 6.24.2, together with #14937, which shows date bindings in the app time zone when you dump raw SQL.

Neither is dramatic on its own. Together they show what the Statamic 6 model asks of every piece of code that touches a date: know which time zone a value is in, and convert instead of reinterpreting.

Before you update

If your site has date fields without a time, 6.17 is the version that matters. Range fields with times need 6.25, and if editors saved ranges on an earlier version, it's worth checking that their times are still where they should be.

After that, the more interesting question isn't technical: whose clock should your editors see? The control panel defaults to the editor's browser. For publish dates, events or anything tied to one place, pinning fields to the site's time zone with default_timezone is often the safer choice, especially if your collections hide future-dated entries.

Two things are easy to miss in custom code. Statamic only converts dates for display on requests that pass through its Localize middleware, so your own routes need it too. And the REST and GraphQL APIs always return UTC, which anything consuming them has to convert.

A date is not a moment

Much of what went wrong comes down to one distinction. A publish timestamp is a moment, and a moment belongs in UTC. December 25 is a day on a calendar, and it should stay that day wherever the editor is. Statamic 6 started out treating both the same way. It took a bug report from Rome, a thread with editors in two US time zones, and a run of fixes through May and July to pull them apart again.

Sources

Author

Thomas Sausen is a freelance web developer and the editor of Flatbard. He builds with Statamic and writes about the surrounding ecosystem.