You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No prompt tells an agent what time it is. Grepping agent-think.ts and agent-do-prompt.ts
for a clock or a locale returns nothing.
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.
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 UTC → 8:33:34 am AEST). The model then repeats a correct string rather than
computing one.
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.
The report
Real example, Coder Lead 2026-08-06:
Answer: no, you should not have to — and the agent is not at fault
Two facts, both verified:
users.preferences(which exists since [docs] Update Coder docs for runner-node picker, engines, and package paths #211 forvoice and translation), not in
user_profile, not in any migration.agent-think.tsandagent-do-prompt.tsfor a clock or a locale returns nothing.
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.tsvalidates timezones (isValidTimeZone) and stores one per trigger — thatlanded 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:
timezoneintousers.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).
subordinate_statusrender in the user's zone before the model ever sees them, with the zone named
(
22:33:34 UTC→8:33:34 am AEST). The model then repeats a correct string rather thancomputing one.
"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 (
formatDateTimein the SDK). Those should use the same storedpreference rather than the browser default, so a user who overrides the zone sees it applied
consistently rather than in the chat only.
Verification
that catches naive offset arithmetic.