Dates, times, and timezones
Working with dates is the single most confusing part of automations, and there's one reason: the grid shows you local time, but flows, PHPScript, and the API work in UTC. Once you understand that, the rules below are simple.
The one rule
A record's date, datetime, and time field values are stored in UTC. The grid and forms convert them to your local timezone for display — but flows, PHPScript, and the public API see the raw UTC value, with no conversion.
So a value that looks correct in the grid can look "wrong" (off by your timezone offset) inside a flow or an API response. It isn't wrong — it's UTC.
The three field types
| Field type | Format | Timezone |
|---|---|---|
date |
YYYY-MM-DD |
Neutral — a plain calendar date, never shifted between timezones. |
datetime |
YYYY-MM-DD HH:MM:SS |
UTC. |
time |
HH:MM:SS |
UTC — easy to forget, since a bare time has no date attached. |
Only datetime and time are affected by timezones. A date is just a date — converting it does nothing.
The now tokens come in two flavors
The current moment is available as built-in tokens. There are two sets:
| Local (account owner's timezone) | UTC |
|---|---|
{{now.date}} |
{{now.date_utc}} |
{{now.datetime}} |
{{now.datetime_utc}} |
{{now.time}} |
{{now.time_utc}} |
Plus {{now.timezone}} — the account owner's timezone name (e.g. Europe/London).
The PHPScript equivalents sys_current_datetime() and sys_current_date() return the local (owner's timezone) value, matching {{now.datetime}} / {{now.date}}.
Rule of thumb: writing into a record field → use the
_utctoken. Showing a value to a person (email, comment, message) → use the local token.
Decision rules
- Stamp the current time into a datetime field →
{{now.datetime_utc}}(builder), ordate_to_utc(sys_current_datetime())(PHPScript). - Show a record's datetime to a person →
date_from_utc({{record.starts_at}})— converts the stored UTC value to the owner's local time (pass a timezone as the second argument to override). - Compare two record datetime fields → both are already UTC, so compare them directly. No conversion.
- A
date-only field → never convert it. - A user typed a local time you need to store →
date_to_utc("2026-06-12 09:00:00")— converts from the owner's timezone (or a timezone you pass) to UTC before saving.
date_to_utc() and date_from_utc() accept any format strtotime understands, default to the account owner's timezone when you don't pass one, and leave date-only input unchanged. See date_to_utc() and date_from_utc().
Examples
Wrong — stores local time labeled as UTC, so the field is off by the owner's offset:
update_record: starts_at = {{now.datetime}}
Right — stores the correct UTC instant:
update_record: starts_at = {{now.datetime_utc}}
Right (PHPScript) — convert an owner-local time before writing, convert back when displaying:
// Owner is America/New_York; store 9am local as UTC.
$utc = date_to_utc("2026-06-12 09:00:00"); // "2026-06-12 13:00:00"
record_update("events", $record["_meta"]["id"], ["starts_at" => $utc]);
// Later, show it back in local time.
$local = date_from_utc($record["starts_at"]); // back to owner's timezone
record_comment("events", $record["_meta"]["id"], "Starts at " . $local);
Using the public API
- Reading a record returns
date/datetime/timevalues exactly as stored — UTC, no conversion. - Writing a record expects the same: send
datetime/timevalues in UTC. - Because the web grid then displays those as your local time, a value you POST in UTC may appear shifted when you open the record in the browser. That's expected.
- Relative date tokens (
today,now,yesterday,+7d,-30d,start_of_week, …) are resolved server-side only in query filters — they do not work when creating or updating records, and they are not available in flows or PHPScript.
See the Public API and the API reference for record formats.
Why the grid looks different
The grid, forms, and exports convert stored UTC values into the signed-in user's timezone for display and back again on save. Flows and the API skip that step and work in UTC. That difference — local display vs UTC storage — is the whole source of the confusion. When a value looks off in a flow, it's almost always UTC doing exactly what it should.
See also: date_to_utc(), date_from_utc(), sys_current_datetime(), Automations, Public API.