Skip to content
Laviyx Learn

Try

SQL course menu

SQL Date Functions: Current Date, Extract Year and Month, Add Days, Date Differences

Learn how to work with dates in SQL: get today's date, extract the year or month, add and subtract intervals, calculate the days between dates, filter date ranges, and group by month, in MySQL, PostgreSQL, SQL Server and SQLite.

Beginner9 min readUpdated
On this page

Dates are everywhere in real data: when an order was placed, when someone joined, when a subscription ends. SQL can extract parts of dates, do date arithmetic, and group by periods. Date functions are also the least standard part of SQL, so this lesson shows each idea in the major databases.

The example tables#

employees

namehire_date
Asha2021-03-15
Ravi2019-07-01
Meera2018-01-10
John2022-11-20
Priya2020-05-04

orders

order_idamountorder_date
1012502026-01-05
1021202026-02-11
1035602026-02-20
104902026-03-02

Today's date and time#

PostgreSQLMySQLSQL ServerSQLite
Current dateCURRENT_DATECURRENT_DATECAST(GETDATE() AS DATE)date('now')
Current date and timeCURRENT_TIMESTAMP / NOW()NOW()GETDATE() / SYSDATETIME()datetime('now')

CURRENT_TIMESTAMP is standard SQL and works almost everywhere.

Filtering by date#

Dates in ISO format ('YYYY-MM-DD') can be compared directly:

SQLRun
SELECT order_id, order_date
FROM orders
WHERE order_date BETWEEN '2026-02-01' AND '2026-02-28';
Output
order_id | order_date
---------+-----------
102      | 2026-02-11
103      | 2026-02-20

Extracting the year, month or day#

PostgreSQL / standardMySQLSQL ServerSQLite
YearEXTRACT(YEAR FROM d)YEAR(d)YEAR(d)strftime('%Y', d)
MonthEXTRACT(MONTH FROM d)MONTH(d)MONTH(d)strftime('%m', d)
DayEXTRACT(DAY FROM d)DAY(d)DAY(d)strftime('%d', d)

In SQLite:

SQLRun
SELECT name,
       hire_date,
       strftime('%Y', hire_date) AS hire_year,
       strftime('%m', hire_date) AS hire_month
FROM employees
ORDER BY hire_date;
Output
name  | hire_date  | hire_year | hire_month
------+------------+-----------+-----------
Meera | 2018-01-10 | 2018      | 01
Ravi  | 2019-07-01 | 2019      | 07
Priya | 2020-05-04 | 2020      | 05
Asha  | 2021-03-15 | 2021      | 03
John  | 2022-11-20 | 2022      | 11

The same in PostgreSQL: EXTRACT(YEAR FROM hire_date) AS hire_year.

Grouping by month#

A monthly revenue report is one of the most common queries in business:

SQLRun
-- SQLite
SELECT strftime('%Y-%m', order_date) AS month,
       SUM(amount) AS revenue
FROM orders
GROUP BY month
ORDER BY month;
Output
month   | revenue
--------+--------
2026-01 | 250
2026-02 | 680
2026-03 | 90

Equivalent "month" expressions:

DatabaseMonth bucket
PostgreSQLDATE_TRUNC('month', order_date)
MySQLDATE_FORMAT(order_date, '%Y-%m')
SQL ServerFORMAT(order_date, 'yyyy-MM') or DATETRUNC(month, order_date) (2022+)
SQLitestrftime('%Y-%m', order_date)

Adding and subtracting time#

A due date 30 days after each order:

SQLRun
-- SQLite
SELECT order_id,
       order_date,
       date(order_date, '+30 days') AS due_date
FROM orders;
Output
order_id | order_date | due_date
---------+------------+-----------
101      | 2026-01-05 | 2026-02-04
102      | 2026-02-11 | 2026-03-13
103      | 2026-02-20 | 2026-03-22
104      | 2026-03-02 | 2026-04-01
Database30 days later
PostgreSQLorder_date + INTERVAL '30 days'
MySQLDATE_ADD(order_date, INTERVAL 30 DAY)
SQL ServerDATEADD(day, 30, order_date)
SQLitedate(order_date, '+30 days')

Use negative values (or - / DATE_SUB) to go back in time.

Difference between two dates#

How many days each employee has worked, measured from 23 October 2026:

SQLRun
-- SQLite
SELECT name,
       hire_date,
       CAST(julianday('2026-10-23') - julianday(hire_date) AS INTEGER) AS days_employed
FROM employees
ORDER BY days_employed DESC;
Output
name  | hire_date  | days_employed
------+------------+--------------
Meera | 2018-01-10 | 3208
Ravi  | 2019-07-01 | 2671
Priya | 2020-05-04 | 2363
Asha  | 2021-03-15 | 2048
John  | 2022-11-20 | 1433

In practice you would use the current date instead of a fixed one:

DatabaseDays between d and today
PostgreSQLCURRENT_DATE - d
MySQLDATEDIFF(CURRENT_DATE, d)
SQL ServerDATEDIFF(day, d, GETDATE())
SQLitejulianday('now') - julianday(d)

Time zones#

Store timestamps in UTC (or in a TIMESTAMP WITH TIME ZONE column) and convert to the user's local time only when displaying. Mixing local times from different places in one column makes comparisons and durations wrong.

Common mistakes#

Practice#

Practice exercise

Count how many employees were hired in each year from 2019 onwards, sorted by year. Write it for SQLite, then name the year function you would use in PostgreSQL.

Show hint

Filter with hire_date >= '2019-01-01', extract the year with strftime('%Y', ...), and group by it.

Show solution
SQLRun
SELECT strftime('%Y', hire_date) AS year,
       COUNT(*) AS hires
FROM employees
WHERE hire_date >= '2019-01-01'
GROUP BY year
ORDER BY year;
Output
year | hires
-----+------
2019 | 1
2020 | 1
2021 | 1
2022 | 1

In PostgreSQL, use EXTRACT(YEAR FROM hire_date) (and GROUP BY 1 or repeat the expression). Meera, hired in 2018, is excluded by the WHERE clause.

Key takeaway#

Finished this lesson?