Which rules does Oracle apply when converting a TIMESTAMP WITH TIME ZONE value after the session NLS_TIME_ZONE changes?
0 reputation · 11 Nov 2022, 10:07 UTC
0 reputation · 11 Nov 2022, 10:07 UTC
Determine how Oracle Database handles a TIMESTAMP WITH TIME ZONE value when the session’s NLS_TIME_ZONE parameter is changed between the time the value is inserted and the time it is queried. The value is stored with its original time‑zone offset, but retrieval may apply the current session time zone, potentially altering the displayed instant, especially when daylight‑saving‑time rules are involved.
Because the documentation does not explicitly state whether the original instant is preserved or the value is re‑zoned to the new session setting, and because internal DST‑transition handling may vary across releases, the exact outcome remains uncertain for mixed‑workload applications that rely on consistent timestamps.
34775 reputation · 11 Nov 2022, 16:46 UTC
When you query a TIMESTAMP WITH TIME ZONE column, Oracle preserves the original instant and the original time zone offset that were stored during the INSERT. Changing the session's NLS_TIME_ZONE parameter does not alter the value returned by a direct select of that column.
The impact of NLS_TIME_ZONE only manifests when the value is converted to a type that does not store time zone information (such as DATE or TIMESTAMP). In these cases, Oracle applies the following rules:
TIMESTAMP WITH TIME ZONE column returns the stored value and offset regardless of the session zone.DATE or TIMESTAMP, Oracle converts the stored UTC instant to the current NLS_TIME_ZONE of the session. The resulting "wall-clock" time will change if the session zone was altered between insertion and retrieval.When converting a stored instant to a new session time zone that involves a Daylight Saving Time (DST) transition, Oracle prioritizes the UTC instant over the local wall-clock time:
This behavior is consistent across Oracle 11gR2, 12c, 19c, and 21c. The core logic for preserving the stored offset in TIMESTAMP WITH TIME ZONE and using the session zone for implicit casts has remained stable across these releases.
To verify this behavior in your environment, use the following scoped commands:
-- 1. Setup and Insert
CREATE TABLE tz_test (ts TIMESTAMP WITH TIME ZONE);
INSERT INTO tz_test VALUES (TIMESTAMP '2023-03-12 01:30:00 US/Pacific');
COMMIT;
-- 2. Verify original value
SELECT ts FROM tz_test;
-- 3. Change session zone and observe difference
ALTER SESSION SET NLS_TIME_ZONE = 'Europe/London';
-- This remains unchanged (Original Offset)
SELECT ts FROM tz_test;
-- This changes based on NLS_TIME_ZONE (Implicit Cast)
SELECT CAST(ts AS TIMESTAMP) FROM tz_test;
Diagnostic Note: To provide a more specific recommendation for DST edge cases, please specify if you are using region-based time zones (e.g., 'US/Pacific') or fixed offsets (e.g., '-08:00'), as fixed offsets do not trigger DST transition logic.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 11 Nov 2022, 19:08 UTC
When a TIMESTAMP WITH TIME ZONE is inserted, Oracle stores the supplied timestamp together with its timezone offset, which together define an absolute UTC instant. The offset itself is not altered on disk. Upon retrieval, Oracle recomputes the instant from the stored values and then formats it according to the current session’s NLS_TIME_ZONE, applying that zone’s daylight‑saving rules. Consequently the displayed offset may differ from the original one, but the underlying instant remains unchanged. If the instant lands on a DST transition, the session zone’s transition rules determine which offset (pre‑ or post‑shift) is used. This behavior has been stable from 11g through 21c because it relies on the internal TIMEZONE_FILE that supplies the DST definitions.