Useful Data Tips

SQL Date and Time Functions: A Practical Guide

⏱️ 35 sec read 📊 SQL

Date and time operations are critical for analytics. Here's how to handle them correctly across different SQL databases.

Getting Current Date/Time

-- Current date (no time)
SELECT CURRENT_DATE;

-- Current timestamp with time
SELECT CURRENT_TIMESTAMP;
SELECT NOW();  -- PostgreSQL, MySQL

-- Current time only
SELECT CURRENT_TIME;

Extracting Date Parts

-- Extract year, month, day
SELECT
    EXTRACT(YEAR FROM order_date) as order_year,
    EXTRACT(MONTH FROM order_date) as order_month,
    EXTRACT(DAY FROM order_date) as order_day,
    EXTRACT(DOW FROM order_date) as day_of_week  -- 0=Sunday
FROM orders;

-- Alternative syntax
SELECT
    DATE_PART('year', order_date) as order_year,
    DATE_PART('quarter', order_date) as order_quarter
FROM orders;

Date Arithmetic

Add/Subtract Time

-- PostgreSQL
SELECT order_date + INTERVAL '30 days' as due_date
FROM orders;

-- MySQL
SELECT DATE_ADD(order_date, INTERVAL 30 DAY) as due_date
FROM orders;

-- SQL Server
SELECT DATEADD(day, 30, order_date) as due_date
FROM orders;

Calculate Differences

-- Days between dates
SELECT order_date, ship_date,
    ship_date - order_date as days_to_ship  -- PostgreSQL
FROM orders;

-- MySQL
SELECT DATEDIFF(ship_date, order_date) as days_to_ship
FROM orders;

-- Age/interval
SELECT user_id,
    AGE(CURRENT_DATE, birth_date) as age  -- PostgreSQL
FROM users;

Truncating Dates

-- Group by month
SELECT
    DATE_TRUNC('month', order_date) as order_month,
    COUNT(*) as order_count,
    SUM(total) as monthly_revenue
FROM orders
GROUP BY DATE_TRUNC('month', order_date)
ORDER BY order_month;

-- Available: year, quarter, month, week, day, hour

Formatting Dates

-- PostgreSQL
SELECT TO_CHAR(order_date, 'YYYY-MM-DD') as formatted_date,
       TO_CHAR(order_date, 'Mon DD, YYYY') as readable_date
FROM orders;

-- MySQL
SELECT DATE_FORMAT(order_date, '%Y-%m-%d') as formatted_date
FROM orders;

-- SQL Server
SELECT FORMAT(order_date, 'yyyy-MM-dd') as formatted_date
FROM orders;

Practical Examples

Find Records from Last 30 Days

SELECT *
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days';

Calculate Retention Rate

SELECT
    DATE_TRUNC('month', first_order) as cohort_month,
    COUNT(DISTINCT user_id) as cohort_size,
    COUNT(DISTINCT CASE
        WHEN second_order <= first_order + INTERVAL '30 days'
        THEN user_id
    END) as retained_users
FROM user_orders
GROUP BY cohort_month;

Handle Timezones

-- Convert to specific timezone
SELECT order_timestamp AT TIME ZONE 'UTC' AT TIME ZONE 'America/New_York' as ny_time
FROM orders;

-- Store in UTC, display in local time
SELECT
    created_at as utc_time,
    created_at AT TIME ZONE 'America/Los_Angeles' as pst_time
FROM events;

Best Practice: Always store dates in UTC and convert to local timezones only for display. Use TIMESTAMP WITH TIME ZONE for timezone-aware data. Avoid string comparisons with dates - cast strings to proper date types first.

← Back to SQL Tips