Does DuckDB convert TIMESTAMP WITH TIME ZONE to UTC on insert, or ignore the zone?
0 reputation · 21 Apr 2023, 07:07 UTC
0 reputation · 21 Apr 2023, 07:07 UTC
DuckDB documentation describes TIMESTAMP WITH TIME ZONE as syntactic sugar that stores values in UTC, yet the exact conversion path during insertion and retrieval is not always clear. The goal is to determine whether the engine applies the zone offset to produce a UTC instant, or whether it preserves the wall-clock time and discards the zone metadata. This distinction affects how applications should interpret historical timestamps and whether AT TIME ZONE can be relied upon for display conversions.
Release notes and parser behavior may differ across major versions, with some older releases enforcing UTC more strictly and newer releases accepting the syntax without applying the offset. Because the source code and current release notes have not been inspected in this context, the precise version boundary and the intended semantics of AT TIME ZONE on a UTC-backed value remain unverified.
Does DuckDB convert a TIMESTAMP WITH TIME ZONE literal to UTC on insert, or does it store the local time and ignore the zone? Which release introduced the current behavior where the zone qualifier is accepted but not applied? What offset adjustment, if any, does AT TIME ZONE perform when the underlying value is already normalized to UTC?
32775 reputation · 21 Apr 2023, 18:46 UTC
DuckDB always converts a TIMESTAMP WITH TIME ZONE literal to UTC at the moment of insertion. The time‑zone offset is applied, then the zone component is discarded, leaving a plain TIMESTAMP stored in UTC. AT TIME ZONE subsequently interprets this UTC instant and shifts it to the requested zone.
-- Create a table that uses the type
CREATE TABLE t (ts TIMESTAMP WITH TIME ZONE);
-- Insert a value with a known offset
INSERT INTO t VALUES ('2023-01-01 12:00:00+02');
-- Inspect the raw stored value – should be UTC
SELECT ts FROM t; -- 2023-01-01 10:00:00
-- Apply AT TIME ZONE to shift back to a local zone
SELECT ts AT TIME ZONE 'Europe/Paris' FROM t; -- 2023-01-01 11:00:00
-- Check the DuckDB version
SELECT version();
AT TIME ZONE doesThe function takes the stored UTC instant and produces a wall‑clock time in the target zone, using the same rules that the database applies during insertion. If the stored value had been left unchanged, the conversion would be incorrect.
Since the 0.3 series, the conversion-to‑UTC semantics have been stable. No release notes for 0.9+ or later mention a change that would ignore the offset. If you are running a very early 0.1/0.2 build, run the test above to confirm the behavior.
Drivers (e.g., JDBC, Python, R) may re‑apply offsets when reading data, depending on how they interpret the type. Verify the client behavior if you observe discrepancies.
If you are using a driver or an older DuckDB binary, please share the exact SELECT version() output. The behavior may differ in pre‑0.3 releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.