|
1 | 1 | --- |
2 | | -summary: "Timezone handling for agents, envelopes, and prompts" |
| 2 | +summary: "Where timezones show up in OpenClaw — envelopes, tool payloads, system prompt" |
3 | 3 | read_when: |
4 | | - - You need to understand how timestamps are normalized for the model |
5 | | - - Configuring the user timezone for system prompts |
| 4 | + - You want a quick mental model for timezone handling |
| 5 | + - You are deciding where to set or override a timezone |
6 | 6 | title: "Timezones" |
7 | 7 | --- |
8 | 8 |
|
9 | | -OpenClaw standardizes timestamps so the model sees a **single reference time**. |
| 9 | +OpenClaw standardizes timestamps so the model sees a **single reference time** instead of a mix of provider-local clocks. There are three surfaces where timezones show up, each with its own purpose: |
10 | 10 |
|
11 | | -## Message envelopes (local by default) |
| 11 | +## Three timezone surfaces |
12 | 12 |
|
13 | | -Inbound messages are wrapped in an envelope like: |
| 13 | +| Surface | What it shows | Default | Configured via | |
| 14 | +| ----------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------- | |
| 15 | +| Message envelopes | Wraps inbound channel messages: `[Signal +1555 2026-01-18 00:19 PST] hello` | Host-local | `agents.defaults.envelopeTimezone` | |
| 16 | +| Tool payloads | Channel `readMessages`-style tools return raw provider time + normalized `timestampMs` / `timestampUtc` | UTC fields always present | Not configurable — preserves provider-native timestamps | |
| 17 | +| System prompt | A small `Current Date & Time` block with the **time zone only** (no clock value, for cache stability) | Host timezone if `userTimezone` unset | `agents.defaults.userTimezone` | |
14 | 18 |
|
15 | | -``` |
16 | | -[Provider ... 2026-01-05 16:26 PST] message text |
17 | | -``` |
| 19 | +The system prompt deliberately omits the live clock to keep prompt caching stable across turns. When the agent needs the current time, it calls `session_status`. |
18 | 20 |
|
19 | | -The timestamp in the envelope is **host-local by default**, with minutes precision. |
20 | | - |
21 | | -You can override this with: |
| 21 | +## Setting the user timezone |
22 | 22 |
|
23 | 23 | ```json5 |
24 | 24 | { |
25 | 25 | agents: { |
26 | 26 | defaults: { |
27 | | - envelopeTimezone: "local", // "utc" | "local" | "user" | IANA timezone |
28 | | - envelopeTimestamp: "on", // "on" | "off" |
29 | | - envelopeElapsed: "on", // "on" | "off" |
| 27 | + userTimezone: "America/Chicago", |
30 | 28 | }, |
31 | 29 | }, |
32 | 30 | } |
33 | 31 | ``` |
34 | 32 |
|
35 | | -- `envelopeTimezone: "utc"` uses UTC. |
36 | | -- `envelopeTimezone: "user"` uses `agents.defaults.userTimezone` (falls back to host timezone). |
37 | | -- Use an explicit IANA timezone (e.g., `"Europe/Vienna"`) for a fixed offset. |
38 | | -- `envelopeTimestamp: "off"` removes absolute timestamps from envelope headers. |
39 | | -- `envelopeElapsed: "off"` removes elapsed time suffixes (the `+2m` style). |
40 | | - |
41 | | -### Examples |
42 | | - |
43 | | -**Local (default):** |
44 | | - |
45 | | -``` |
46 | | -[Signal Alice +1555 2026-01-18 00:19 PST] hello |
47 | | -``` |
48 | | - |
49 | | -**Fixed timezone:** |
50 | | - |
51 | | -``` |
52 | | -[Signal Alice +1555 2026-01-18 06:19 GMT+1] hello |
53 | | -``` |
54 | | - |
55 | | -**Elapsed time:** |
56 | | - |
57 | | -``` |
58 | | -[Signal Alice +1555 +2m 2026-01-18T05:19Z] follow-up |
59 | | -``` |
60 | | - |
61 | | -## Tool payloads (raw provider data + normalized fields) |
62 | | - |
63 | | -Tool calls (`channels.discord.readMessages`, `channels.slack.readMessages`, etc.) return **raw provider timestamps**. |
64 | | -We also attach normalized fields for consistency: |
65 | | - |
66 | | -- `timestampMs` (UTC epoch milliseconds) |
67 | | -- `timestampUtc` (ISO 8601 UTC string) |
68 | | - |
69 | | -Raw provider fields are preserved. |
70 | | - |
71 | | -## User timezone for the system prompt |
72 | | - |
73 | | -Set `agents.defaults.userTimezone` to tell the model the user's local time zone. If it is |
74 | | -unset, OpenClaw resolves the **host timezone at runtime** (no config write). |
75 | | - |
76 | | -```json5 |
77 | | -{ |
78 | | - agents: { defaults: { userTimezone: "America/Chicago" } }, |
79 | | -} |
80 | | -``` |
81 | | - |
82 | | -The system prompt includes: |
| 33 | +If `userTimezone` is unset, OpenClaw resolves the host timezone at runtime (no config write). `agents.defaults.timeFormat` (`auto` | `12` | `24`) controls 12h/24h rendering in envelopes and downstream surfaces, not in the system prompt section. |
83 | 34 |
|
84 | | -- `Current Date & Time` section with local time and timezone |
85 | | -- `Time format: 12-hour` or `24-hour` |
| 35 | +## When to override |
86 | 36 |
|
87 | | -You can control the prompt format with `agents.defaults.timeFormat` (`auto` | `12` | `24`). |
| 37 | +- **Use UTC envelopes** (`envelopeTimezone: "utc"`) when you want stable timestamps across hosts in different regions, or when you want UTC-aligned logs to match diagnostics output. |
| 38 | +- **Use a fixed IANA zone** (e.g. `"Europe/Vienna"`) when the gateway host is in one zone but the user is in another and you want envelopes to read in the user's zone regardless of host migration. |
| 39 | +- **Set `envelopeTimestamp: "off"`** for low-token envelopes when timestamp context is not useful for the conversation. |
88 | 40 |
|
89 | | -See [Date & Time](/date-time) for the full behavior and examples. |
| 41 | +For the full behavior reference, examples per provider, and elapsed-time formatting, see [Date & Time](/date-time). |
90 | 42 |
|
91 | 43 | ## Related |
92 | 44 |
|
93 | | -- [Heartbeat](/gateway/heartbeat) — active hours use timezone for scheduling |
94 | | -- [Cron Jobs](/automation/cron-jobs) — cron expressions use timezone for scheduling |
95 | | -- [Date & Time](/date-time) — full date/time behavior and examples |
| 45 | +- [Date & Time](/date-time) — full envelope/tool/prompt behavior and examples. |
| 46 | +- [Heartbeat](/gateway/heartbeat) — active hours use timezone for scheduling. |
| 47 | +- [Cron Jobs](/automation/cron-jobs) — cron expressions use timezone for scheduling. |
0 commit comments