Date & Time Types
PostgreSQL has a dedicated type for every shape of temporal data you might need: a calendar date on its own, a time of day on its own, a combined date-and-time with or without timezone awareness, and a duration between two points in time.
Type | Stores | Example |
|---|---|---|
| A calendar date, no time |
|
| A time of day, no date |
|
| Date + time, no timezone awareness |
|
| Date + time, timezone-aware (stored as UTC) |
|
| A span of time — a duration |
|
TIMESTAMP vs TIMESTAMPTZ: the distinction that matters most
This is the single most important thing to understand about PostgreSQL's date/time types, and it trips up a lot of developers coming from other systems.
The same literal, two different types
SET timezone = 'UTC';
CREATE TABLE demo (
ts_naive TIMESTAMP,
ts_aware TIMESTAMPTZ
);
INSERT INTO demo VALUES ('2026-07-09 14:30:00-05', '2026-07-09 14:30:00-05');
SELECT ts_naive, ts_aware FROM demo;
-- ts_naive: 2026-07-09 14:30:00 (the -05 offset was simply discarded)
-- ts_aware: 2026-07-09 19:30:00+00 (converted to UTC for storage)
SET timezone = 'America/New_York';
SELECT ts_naive, ts_aware FROM demo;
-- ts_naive: 2026-07-09 14:30:00 (unchanged — it never had timezone info)
-- ts_aware: 2026-07-09 15:30:00-04 (re-rendered for the new session timezone)DATE and TIME on their own
DATE and TIME columns
CREATE TABLE events (
event_date DATE NOT NULL,
start_time TIME NOT NULL
);
INSERT INTO events VALUES ('2026-08-15', '09:00:00');INTERVAL: durations
Working with intervals
SELECT INTERVAL '1 day 4 hours'; SELECT now() + INTERVAL '30 minutes' AS half_hour_from_now; SELECT now() - INTERVAL '7 days' AS one_week_ago; -- The difference between two timestamps is itself an interval SELECT '2026-08-15 09:00:00'::timestamptz - now() AS time_until_event;
Getting the current time
NOW() and CURRENT_TIMESTAMP
SELECT now(); -- returns TIMESTAMPTZ SELECT CURRENT_TIMESTAMP; -- SQL-standard equivalent, also TIMESTAMPTZ SELECT CURRENT_DATE; -- just the date SELECT CURRENT_TIME; -- just the time
DATE,TIME,TIMESTAMP, andTIMESTAMPTZeach cover a different combination of date, time, and timezone awareness.TIMESTAMPis naive — it has no idea what timezone it represents.TIMESTAMPTZstores everything as UTC internally and converts on display based on the session timezone.Default to
TIMESTAMPTZfor user-facing timestamps to avoid an entire class of timezone bugs.INTERVALrepresents a duration and is what you get when you subtract one timestamp from another.