The AT TIME ZONE clause converts timestamp values from one time zone to another.
AT TIME ZONE converts timestamp values reliably, letting you store UTC and display local times without manual math. It handles daylight-saving transitions automatically.
Use value AT TIME ZONE source_zone AT TIME ZONE target_zone. The first AT TIME ZONE turns a timestamp without time zone into timestamptz, the second converts it to another zone.
Join Orders with Customers, fetch each customer’s zone, and convert the stored UTC timestamp to that zone using AT TIME ZONE.
SELECT o.id,
o.order_date AT TIME ZONE 'UTC' AT TIME ZONE c.user_tz AS local_time
FROM Orders o
JOIN Customers c ON c.id = o.customer_id;
Wrap the result in ::date to truncate the time portion without losing the zone-adjusted value.
Run SET TIME ZONE 'America/Los_Angeles'; All subsequent timestamptz values render in that zone until reset.
Store timestamptz in UTC to avoid daylight-saving bugs. Convert to local zones only when reading.
Create an index on the stored timestamptz column, not on computed zone conversions, for efficient range searches.
timestamp without time zone lacks zone info. Casting it directly to another zone skips DST rules. Always attach the source zone first.
'-05:00' ignores daylight savings. Use named zones such as 'America/New_York' to let PostgreSQL apply historical rules.
Remember: value AT TIME ZONE source AT TIME ZONE target. Store UTC, convert on output, and use named zones.
No. It returns a converted value in the result set; the underlying column remains unchanged.
You can create a functional index, but it increases storage. Prefer indexing the raw timestamptz column.
Run SELECT name FROM pg_timezone_names ORDER BY name; to see every zone PostgreSQL recognizes.