Skip to content

Agents report timestamps in UTC because nothing ever told them the user's timezone — and no prompt has a clock #329

Description

@serge-ivo

The report

When the leader agent replied it told me the time in UTC. I don't care about UTC. I need all
timestamps in my time zone. Do I have to specify it?

Real example, Coder Lead 2026-08-06:

"The FAS cleanup run is active at iteration 2 (started at 22:33:34 UTC)"
"the run completed at 22:34:19 UTC today"

Answer: no, you should not have to — and the agent is not at fault

Two facts, both verified:

So the agent reads ISO UTC strings out of tool results and labels them UTC. Given what it has, that
is the correct answer — inventing a local time would be worse. The gap is that nobody ever told
it where the user lives.

The platform already has the machinery

lib/triggers.ts validates timezones (isValidTimeZone) and stores one per trigger — that
landed with #18's timezone-aware schedules. What is missing is a user-level default, which is
the thing every other surface needs.

The browser knows it for free: Intl.DateTimeFormat().resolvedOptions().timeZone.

Design: format at the source, do not make the model convert

The obvious fix — tell the agent the timezone and let it convert — is the wrong one. Timezone
arithmetic in a language model is exactly the class of thing it does almost right: DST edges,
day boundaries, "yesterday" near midnight. A wrong-by-one-hour timestamp presented confidently is
worse than UTC presented honestly.

Instead:

  1. Capture timezone into users.preferences — defaulted from the browser on first load,
    editable on the Preferences page ([docs] Update Coder docs for runner-node picker, engines, and package paths #211's home for exactly this kind of account-level setting).
  2. Format tool outputs at the source. Run timings, board timestamps and subordinate_status
    render in the user's zone before the model ever sees them, with the zone named
    (22:33:34 UTC8:33:34 am AEST). The model then repeats a correct string rather than
    computing one.
  3. Tell the agent the current time and zone in the prompt as well, so it can reason about
    "today" and "overnight" — but as context, not as a conversion instruction.

This is the same principle as rendering a technicality slider as a described band rather than
"70/100" (#223): give the model language it can only repeat, not arithmetic it can get subtly wrong.

Also worth covering

The console renders timestamps too (formatDateTime in the SDK). Those should use the same stored
preference rather than the browser default, so a user who overrides the zone sees it applied
consistently rather than in the chat only.

Verification

  • A fresh account has its timezone populated from the browser without being asked.
  • The Lead reports run times in the user's zone, named, with no UTC anywhere in the reply.
  • Changing the timezone in Preferences changes both chat replies and console timestamps.
  • A user whose zone observes DST gets correct local times either side of a transition — the case
    that catches naive offset arithmetic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions