PostgreSQL Date Functions

Working with dates and times in PostgreSQL

📅 What are Date Functions?

Date functions in PostgreSQL help you work with dates, times, and timestamps. They allow you to get current dates, calculate differences, extract parts, and perform date arithmetic easily.


-- Get current date and time
SELECT NOW();
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
                                    

Output:

NOW(): 2024-01-15 14:30:25

CURRENT_DATE: 2024-01-15

CURRENT_TIME: 14:30:25

Common Date Functions

🕐

Current Date/Time

Get current date and time

SELECT NOW();
📊

Extract Parts

Get year, month, day, etc.

SELECT EXTRACT(YEAR FROM NOW());

Date Arithmetic

Add or subtract dates

SELECT CURRENT_DATE + INTERVAL '7 days';
🔄

Format Dates

Convert date formats

SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');

🔹 NOW() and CURRENT_DATE

Get the current date and time from your database server. NOW() returns a timestamp with date and time, while CURRENT_DATE returns only the date. These are essential for timestamping records and date comparisons.

-- Get current timestamp
SELECT NOW();
-- Returns: 2024-01-15 14:30:25.123456

-- Get current date only
SELECT CURRENT_DATE;
-- Returns: 2024-01-15

-- Get current time only
SELECT CURRENT_TIME;
-- Returns: 14:30:25.123456

-- Practical example
SELECT 
    order_id,
    order_date,
    NOW() - order_date AS time_since_order
FROM orders;
                            

Output:

NOW(): 2024-01-15 14:30:25

CURRENT_DATE: 2024-01-15

🔹 EXTRACT()

Extract specific parts from a date or timestamp like year, month, day, hour, or minute. This function is invaluable for grouping data by time periods or filtering based on specific date components.

-- Extract year
SELECT EXTRACT(YEAR FROM NOW());
-- Returns: 2024

-- Extract month
SELECT EXTRACT(MONTH FROM NOW());
-- Returns: 1

-- Extract day
SELECT EXTRACT(DAY FROM NOW());
-- Returns: 15

-- Extract multiple parts
SELECT 
    order_date,
    EXTRACT(YEAR FROM order_date) AS year,
    EXTRACT(MONTH FROM order_date) AS month,
    EXTRACT(DAY FROM order_date) AS day
FROM orders;
                            

Output:

YEAR: 2024

MONTH: 1

DAY: 15

🔹 Date Arithmetic with INTERVAL

Add or subtract time periods from dates using INTERVAL. You can work with days, months, years, hours, minutes, and more. This makes calculating future dates, deadlines, or date ranges straightforward.

-- Add days
SELECT CURRENT_DATE + INTERVAL '7 days';
-- Returns: 2024-01-22

-- Subtract months
SELECT CURRENT_DATE - INTERVAL '3 months';
-- Returns: 2023-10-15

-- Add hours and minutes
SELECT NOW() + INTERVAL '2 hours 30 minutes';

-- Calculate due dates
SELECT 
    order_date,
    order_date + INTERVAL '30 days' AS due_date,
    order_date + INTERVAL '1 year' AS warranty_end
FROM orders;
                            

Output:

+7 days: 2024-01-22

-3 months: 2023-10-15

🔹 AGE()

Calculate the difference between two dates as an interval showing years, months, and days. AGE is perfect for calculating ages, time elapsed, or how long until a future date.

-- Calculate age from birthdate
SELECT AGE(CURRENT_DATE, '1990-05-15');
-- Returns: 33 years 8 mons 0 days

-- Age with single argument (from current date)
SELECT AGE('1990-05-15');
-- Returns: 33 years 8 mons 0 days

-- Calculate account age
SELECT 
    username,
    created_date,
    AGE(CURRENT_DATE, created_date) AS account_age
FROM users;
                            

Output:

AGE: 33 years 8 mons 0 days

🔹 DATE_PART()

Similar to EXTRACT but returns a double precision number. DATE_PART is useful when you need numeric values for calculations or when working with specific date components in mathematical operations.

-- Get year as number
SELECT DATE_PART('year', NOW());
-- Returns: 2024

-- Get day of week (0=Sunday, 6=Saturday)
SELECT DATE_PART('dow', NOW());
-- Returns: 1 (Monday)

-- Get day of year
SELECT DATE_PART('doy', NOW());
-- Returns: 15

-- Group by month
SELECT 
    DATE_PART('month', order_date) AS month,
    COUNT(*) AS order_count
FROM orders
GROUP BY month;
                            

Output:

YEAR: 2024

DAY OF WEEK: 1

🔹 TO_CHAR() - Format Dates

Convert dates to formatted strings using pattern templates. TO_CHAR gives you complete control over how dates appear, perfect for reports, displays, and exporting data in specific formats.

-- Format as YYYY-MM-DD
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');
-- Returns: 2024-01-15

-- Format as Month DD, YYYY
SELECT TO_CHAR(NOW(), 'Month DD, YYYY');
-- Returns: January 15, 2024

-- Custom formats
SELECT TO_CHAR(NOW(), 'Day, Mon DD YYYY HH24:MI:SS');
-- Returns: Monday, Jan 15 2024 14:30:25

-- Format order dates
SELECT 
    order_id,
    TO_CHAR(order_date, 'MM/DD/YYYY') AS formatted_date,
    TO_CHAR(order_date, 'Day') AS day_name
FROM orders;
                            

Output:

YYYY-MM-DD: 2024-01-15

Month DD, YYYY: January 15, 2024

🔹 TO_DATE() and TO_TIMESTAMP()

Convert string representations to date or timestamp types. These functions parse text into proper date objects, essential when importing data or working with dates stored as strings.

-- Convert string to date
SELECT TO_DATE('2024-01-15', 'YYYY-MM-DD');
-- Returns: 2024-01-15

-- Convert string to timestamp
SELECT TO_TIMESTAMP('2024-01-15 14:30:25', 'YYYY-MM-DD HH24:MI:SS');
-- Returns: 2024-01-15 14:30:25

-- Parse different formats
SELECT TO_DATE('01/15/2024', 'MM/DD/YYYY');
SELECT TO_DATE('15-Jan-2024', 'DD-Mon-YYYY');

-- Convert imported data
SELECT 
    TO_DATE(date_string, 'MM/DD/YYYY') AS proper_date
FROM imported_data;
                            

Output:

TO_DATE: 2024-01-15

🔹 DATE_TRUNC()

Truncate a timestamp to a specified precision like hour, day, month, or year. This function is excellent for grouping data into time buckets or finding the start of time periods.

-- Truncate to day (remove time)
SELECT DATE_TRUNC('day', NOW());
-- Returns: 2024-01-15 00:00:00

-- Truncate to month (first day of month)
SELECT DATE_TRUNC('month', NOW());
-- Returns: 2024-01-01 00:00:00

-- Truncate to year
SELECT DATE_TRUNC('year', NOW());
-- Returns: 2024-01-01 00:00:00

-- Group sales by month
SELECT 
    DATE_TRUNC('month', sale_date) AS month,
    SUM(amount) AS monthly_total
FROM sales
GROUP BY month;
                            

Output:

TRUNC to day: 2024-01-15 00:00:00

TRUNC to month: 2024-01-01 00:00:00

🔹 OVERLAPS

Check if two date ranges overlap. This operator is useful for scheduling systems, booking applications, or any scenario where you need to detect conflicting time periods.

-- Check if date ranges overlap
SELECT (DATE '2024-01-01', DATE '2024-01-15') 
       OVERLAPS 
       (DATE '2024-01-10', DATE '2024-01-20');
-- Returns: true

-- Check if periods don't overlap
SELECT (DATE '2024-01-01', DATE '2024-01-10') 
       OVERLAPS 
       (DATE '2024-01-15', DATE '2024-01-20');
-- Returns: false

-- Find conflicting bookings
SELECT * FROM bookings b1
WHERE EXISTS (
    SELECT 1 FROM bookings b2
    WHERE b1.id != b2.id
    AND (b1.start_date, b1.end_date) 
        OVERLAPS 
        (b2.start_date, b2.end_date)
);
                            

Output:

Overlaps: true

No overlap: false

🧠 Test Your Knowledge

What does CURRENT_DATE return?