documentation/concepts/timestamps-timezones.md
QuestDB stores all timestamps in UTC without time zone information. To query data at your local time, use TICK syntax. To display results in local time, use conversion functions.
:::tip Key Points
@timezone to query data at your local timeAmerica/New_York) over abbreviations (EST)to_timezone() only when displaying local time in results
:::QuestDB uses the IANA tz database. Specify time zones by geographic region or UTC offset:
| Format | Example | Recommended? |
|---|---|---|
| Geographic region | America/New_York | ✅ Best |
| UTC offset | +02:00, -05:00 | ✅ Good |
| Abbreviation | EST, CST | ⚠️ Avoid |
Avoid abbreviations — the same abbreviation often maps to multiple time
zones. For example, CST could mean U.S. Central Standard Time or China
Standard Time. QuestDB can only recognize one, leading to unexpected results.
For valid time zone names, see the IANA time zone database.
:::note
The tz database includes historic transitions. QuestDB applies the correct offset based on the timestamp value, accounting for historical daylight saving time changes.
:::
You're in New York and want trades from 9am your time. Use
TICK syntax with @timezone:
SELECT * FROM trades
WHERE ts IN '2024-01-15T09:00@America/New_York;1h';
TICK converts your local time to UTC intervals, enabling efficient interval scans. More examples:
-- London business hours (09:00-17:00) for January workdays
SELECT * FROM trades
WHERE ts IN '2024-01-[01..31]T09:00@Europe/London#wd;8h';
-- NYSE trading hours (09:30-16:00 Eastern)
SELECT * FROM trades
WHERE ts IN '2024-01-[01..31]T09:30@America/New_York#wd;6h30m';
-- Last 5 business days, Tokyo morning session
SELECT * FROM trades
WHERE ts IN '[$today-5bd..$today-1bd]T09:00@Asia/Tokyo;2h30m';
TICK handles DST transitions automatically — a 9 AM start time in New York maps to different UTC times in winter vs summer.
TICK generates UTC intervals at query planning time, enabling binary search. Converting each row forces a full table scan:
-- Efficient: interval scan (sub-millisecond on billions of rows)
WHERE ts IN '2024-01-[01..31]T09:00@Europe/London;8h'
-- Inefficient: full table scan (must read every row)
WHERE extract(hour FROM to_timezone(ts, 'Europe/London')) BETWEEN 9 AND 17
When you need local time in query results (not filtering), use to_timezone():
SELECT
to_timezone(ts, 'Europe/Berlin') as local_time,
symbol,
price
FROM trades
WHERE ts IN '2024-01-15';
| local_time | symbol | price |
|---|---|---|
| 2024-01-15T10:30:00.000000Z | BTC-USD | 42000 |
If source data arrives in local time, convert to UTC before storing:
INSERT INTO trades
SELECT to_utc(local_ts, 'America/New_York'), symbol, price
FROM source_data;
This ensures consistent ordering and avoids ambiguity during DST transitions.
@timezone syntax referenceto_timestamp(), to_utc(), to_timezone()