Date Functions
How to extract, truncate, and calculate with dates and timestamps.
Dates and timestamps need more than simple comparisons. You often need to extract a year, round a timestamp to the nearest month, or compute the gap between two dates. SQL's date functions handle all of this directly in the query.
Extracting components with EXTRACT
EXTRACT pulls a single unit out of a date or timestamp:
SELECT EXTRACT(YEAR FROM hire_date) AS hire_year FROM employees;
SELECT EXTRACT(MONTH FROM created_at) AS month FROM orders;
SELECT EXTRACT(DOW FROM created_at) AS weekday FROM orders; -- 0 = Sunday
SELECT EXTRACT(HOUR FROM logged_at) AS hour FROM events;Common units: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, DOW (day of week), DOY (day of year), QUARTER.
Truncating with DATE_TRUNC
DATE_TRUNC rounds a timestamp down to a given precision. This is the go-to function for grouping by time period:
SELECT DATE_TRUNC('month', created_at) AS month, COUNT(*) AS orders
FROM orders
GROUP BY DATE_TRUNC('month', created_at)
ORDER BY month;Every timestamp in March 2024 becomes 2024-03-01 00:00:00. The result is one row per calendar month.
Valid precision values: 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'.
Date arithmetic
You can add or subtract intervals from any date or timestamp:
SELECT hire_date + INTERVAL '90 days' AS probation_end FROM employees;
SELECT NOW() - INTERVAL '30 days' AS thirty_days_ago;
SELECT NOW() + INTERVAL '1 year' AS one_year_from_now;Subtracting two timestamps returns an interval. Subtracting two dates returns an integer number of days:
SELECT (NOW() - hire_date) AS tenure FROM employees; -- interval
SELECT (end_date - start_date) AS days FROM projects; -- integerTo convert an interval to a plain number, use EXTRACT:
SELECT EXTRACT(DAY FROM (NOW() - hire_date)) AS days_employed
FROM employees;NOW, CURRENT_DATE, CURRENT_TIMESTAMP
NOW() and CURRENT_TIMESTAMP both return the current date and time with timezone. CURRENT_DATE returns only the date (no time component). NOW() is a function call; CURRENT_DATE and CURRENT_TIMESTAMP are keywords — no parentheses needed.
SELECT NOW(); -- 2024-03-15 14:32:00+00
SELECT CURRENT_DATE; -- 2024-03-15
SELECT CURRENT_TIMESTAMP; -- 2024-03-15 14:32:00+00Portability note
DATE_TRUNC is PostgreSQL-specific. SQL Server uses DATETRUNC or FORMAT; MySQL uses DATE_FORMAT and DATE_ADD. The concepts are universal — only the syntax changes when you switch databases.