How does PostgreSQL's AT TIME ZONE handle daylight saving transitions when converting UTC timestamps to a regional time zone on DigitalOcean Managed Databases?
0 reputation · 28 Mar 2021, 01:54 UTC
0 reputation · 28 Mar 2021, 01:54 UTC
26525 reputation · 28 Mar 2021, 05:41 UTC
When you run SELECT value AT TIME ZONE 'zone' on a timestamptz that is already UTC‑aware, PostgreSQL:
timestamp (no time‑zone) that represents the local wall‑clock time.timestamp values instead.
timestamptz AT TIME ZONE zone returns timestamp with the earlier offset in ambiguous hours; timestamp AT TIME ZONE zone returns timestamptz and uses the server’s current time zone setting.SELECT '2023-11-05 01:30:00+00'::timestamptz AT TIME ZONE 'America/New_York'; -- EST (earlier)
SELECT ('2023-11-05 01:30:00+00'::timestamptz + INTERVAL '1 hour') AT TIME ZONE 'America/New_York'; -- EDT (later)
AT TIME ZONE operator is independent of the session’s timezone GUC. It uses only the zone name you supply. The only session‑level setting that can influence the result indirectly is lc_time for locale‑specific formatting, not the conversion itself.tzdata package up‑to‑date. Therefore the DST rules applied by AT TIME ZONE are identical to a local PostgreSQL server.SELECT version();
SELECT * FROM pg_timezone_names WHERE name = 'America/New_York';
-- Spring forward (gap)
SELECT '2023-03-12 07:30:00+00'::timestamptz AT TIME ZONE 'America/New_York'; -- 2023-03-12 03:30:00-04 (EDT)
-- Fall back (ambiguous hour)
SELECT '2023-11-05 01:30:00+00'::timestamptz AT TIME ZONE 'America/New_York'; -- 2023-11-05 01:30:00-05 (EST)
Store all event timestamps as timestamptz in UTC. When you need to present them in a user’s local zone, simply apply:
SELECT event_ts AT TIME ZONE 'America/New_York' AS local_time
FROM events;
This guarantees consistent conversion across regions and seasons. If you must distinguish between the two offsets on the ambiguous hour, store the UTC timestamp and add the desired offset manually before the conversion.
Could you let me know which PostgreSQL version your DigitalOcean Managed Database is running? That will confirm the exact tzdata release and help verify the DST rules you see.
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 28 Mar 2021, 12:43 UTC
The AT TIME ZONE operator always returns a timestamp (no time‑zone) when the input is a timestamptz. If you need the result to retain zone awareness you can apply the operator a second time with UTC, e.g.:
SELECT (event_ts AT TIME ZONE 'America/New_York') AT TIME ZONE 'UTC' AS event_tz;
This yields a timestamptz representing the same instant but expressed in the target zone, preserving the DST‑aware offset chosen by the first conversion. The approach works identically on DigitalOcean Managed PostgreSQL because it uses the same IANA tzdata as community builds.