41 Date Functions and COALESCE
PostgreSQL has rich date/time arithmetic. date_trunc rounds to a precision; extract pulls a single field; interval lets you add and subtract durations; date_part, age, to_char, to_date cover the rest. And COALESCE — not date-specific but worth pairing with date logic — is how you supply defaults for possibly-NULL values.
What you’ll learn
current_date,current_timestamp,now(),clock_timestamp()date_trunc(unit, ts): truncate to year, month, day, hour, etc.extract(field FROM ts): pull year, month, day-of-week, …intervalarithmetic and formattingCOALESCEfor NULL fallbacks
Example
date_trunc('month', ts) is the standard way to “bin by month” in analytics. The result is a timestamp (or timestamptz) at midnight on the first of that month. Use extract(isodow FROM ts) to group by weekday, date_trunc('week', ts) for calendar weeks, or date_bin (PostgreSQL 14+) for fixed-width buckets.
extract returns a numeric (or double precision in older versions). The dow field uses Sunday=0; isodow uses Monday=1 (matching ISO 8601). When in doubt, isodow matches what most “Monday is the start of the week” assumptions expect.
age(end, start) returns an interval normalized into years/months/days, which is useful for displays (“3 years, 2 months”). For raw differences, subtract two timestamptz values to get an interval in days/hours/seconds.
COALESCE walks its arguments left-to-right and returns the first non-NULL. It is the canonical “default value” tool: COALESCE(user.display_name, user.email, 'Anonymous').
Run the example
To run:
Common pitfalls
now()returns the transaction start time. Inside a long transaction, every call returns the same value. Useclock_timestamp()for true wall-clock.- Mixing
timestampandtimestamptzsilently uses the session’s time zone. Be explicit:at time zone 'UTC'for cast/display, and store astimestamptzwhenever possible. date_truncreturns a value of the same type —date_trunc('day', timestamptz)returns atimestamptz, not adate. Cast if you needdate.extract(epoch FROM ts)returnsnumericseconds since the Unix epoch in PostgreSQL 17;date_part('epoch', ts)returnsdouble precision. Useful when interoperating with code that uses Unix time.COALESCEshort-circuits, so side-effecting expressions in later arguments are not evaluated when an earlier one is non-NULL.
For “the first day of next month,” date_trunc('month', current_date) + interval '1 month'. For “the last day of this month,” date_trunc('month', current_date) + interval '1 month' - interval '1 day'. These idioms are everywhere in reporting queries.
Compute the first day of the current year (date_trunc('year', current_date)). Format a timestamp as ISO 8601: to_char(current_timestamp, 'YYYY-MM-DD"T"HH24:MI:SSOF'). Use COALESCE in a SELECT against tasks_example to display due_at or ’no deadline'.
Downloads
SQL file: date-functions-and-coalesce.sql · All lesson files · Setup guide