🧚 Ascolta! Beekeeper Studio è una GUI per database veloce, moderna e open source Scarica
January 13, 2026 Di Matthew Rathbone

Calculating the difference between two dates is one of the most common tasks in database work. Whether you’re tracking project durations, finding overdue invoices, or calculating customer tenure, you need reliable ways to measure time spans. That’s where SQL DATEDIFF and date arithmetic become essential.

Date difference calculations appear everywhere in real applications: aging reports, subscription tracking, SLA monitoring, and countless business analytics scenarios. While the specific function varies between database systems, the core concept remains the same—measuring the gap between two points in time.

Throughout this guide, you’ll find interactive SQL exercises that let you practice date calculations in your browser—no database setup required. Write queries, get instant feedback, and build confidence with date arithmetic.

What is DATEDIFF?

DATEDIFF is a SQL function that calculates the difference between two dates. The exact syntax varies by database system, but the concept is universal: given two dates, return how far apart they are.

The general idea works like this:

-- Conceptual syntax (varies by database)
DATEDIFF(unit, start_date, end_date)
-- or
DATEDIFF(end_date, start_date)

Key points about date difference calculations:

  • Units vary: Some databases let you specify days, months, years, hours, etc.
  • Order matters: The result can be positive or negative depending on which date comes first
  • Database-specific: Each database has its own syntax and functions

Date Arithmetic in Different Databases

Since DATEDIFF syntax varies significantly between databases, here’s how each major system handles it:

SQL Server

-- DATEDIFF(datepart, start_date, end_date)
SELECT DATEDIFF(day, '2024-01-01', '2024-01-15') as days_diff;
-- Returns: 14

SELECT DATEDIFF(month, '2024-01-15', '2024-06-15') as months_diff;
-- Returns: 5

MySQL

-- DATEDIFF(end_date, start_date) - returns days only
SELECT DATEDIFF('2024-01-15', '2024-01-01') as days_diff;
-- Returns: 14

-- For other units, use TIMESTAMPDIFF
SELECT TIMESTAMPDIFF(MONTH, '2024-01-15', '2024-06-15') as months_diff;
-- Returns: 5

PostgreSQL

-- Direct subtraction returns an interval
SELECT '2024-01-15'::date - '2024-01-01'::date as days_diff;
-- Returns: 14

-- Or use AGE() for detailed breakdown
SELECT AGE('2024-06-15', '2024-01-15');
-- Returns: 5 mons

SQLite

SQLite doesn’t have a built-in DATEDIFF function, but you can use Julian day calculations:

-- Subtract Julian days for date difference
SELECT julianday('2024-01-15') - julianday('2024-01-01') as days_diff;
-- Returns: 14.0

-- Cast to integer for whole days
SELECT CAST(julianday('2024-01-15') - julianday('2024-01-01') AS INTEGER);
-- Returns: 14

Basic Date Difference Calculations

Let’s start with the most common scenario: calculating the number of days between two dates.

Days Between Dates

Imagine you’re tracking order fulfillment times. You have an order date and a ship date, and need to know how long fulfillment took:

-- SQL Server
SELECT 
  order_id,
  order_date,
  ship_date,
  DATEDIFF(day, order_date, ship_date) as fulfillment_days
FROM orders;

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

-- SQLite
SELECT 
  order_id,
  order_date,
  ship_date,
  CAST(julianday(ship_date) - julianday(order_date) AS INTEGER) as fulfillment_days
FROM orders;

Try it yourself:

[[ expanded ? '▼' : '▶' ]]

[[ testData.title ]]

Query the projects table to return project_name, start_date, end_date, and calculate duration_days as the number of days between the start and end dates.

Esempio Interattivo ✓ Completato
Colonne attese: [[ col ]]
ℹ️ Questo esercizio reimposta il database ad ogni esecuzione. Scrivi la tua soluzione completa in un'unica sottomissione.
[[ i18n.correct ]] [[ validationResult ? i18n.all_checks_passed : i18n.query_success ]]
[[ detail.message ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.not_quite_right ]] [[ patternError ]] [[ validationResult.error ]] [[ i18n.results_dont_match ]]
[[ detail.passed ? '✓' : '✗' ]] [[ detail.message ]]
[[ i18n.your_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.expected_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.sql_error ]]
[[ error ]]
💡 [[ i18n.hint_label ]] [[ testData.hint ]]
📊 [[ i18n.expected_result_label ]]
[[ col ]]
[[ formatCell(cell) ]]
✨ [[ i18n.solution_label ]]
[[ testData.solution ]]
Tabelle Disponibili
[[ table.name ]]
[[ col ]]
[[ formatCell(cell) ]]

Finding Overdue Records

A common business requirement is finding records that have passed their due date and calculating how overdue they are.

-- Find invoices overdue as of today
-- SQL Server
SELECT 
  invoice_id,
  due_date,
  DATEDIFF(day, due_date, GETDATE()) as days_overdue
FROM invoices
WHERE due_date < GETDATE();

-- MySQL
SELECT 
  invoice_id,
  due_date,
  DATEDIFF(CURDATE(), due_date) as days_overdue
FROM invoices
WHERE due_date < CURDATE();

-- SQLite
SELECT 
  invoice_id,
  due_date,
  CAST(julianday('now') - julianday(due_date) AS INTEGER) as days_overdue
FROM invoices
WHERE due_date < date('now');

Try it yourself:

[[ expanded ? '▼' : '▶' ]]

[[ testData.title ]]

Query the tasks table to find all overdue tasks (where due_date is before ‘2024-03-15’). Return task_name, due_date, and calculate days_overdue showing how many days past the deadline. Order by days overdue descending.

Esempio Interattivo ✓ Completato
Colonne attese: [[ col ]]
ℹ️ Questo esercizio reimposta il database ad ogni esecuzione. Scrivi la tua soluzione completa in un'unica sottomissione.
[[ i18n.correct ]] [[ validationResult ? i18n.all_checks_passed : i18n.query_success ]]
[[ detail.message ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.not_quite_right ]] [[ patternError ]] [[ validationResult.error ]] [[ i18n.results_dont_match ]]
[[ detail.passed ? '✓' : '✗' ]] [[ detail.message ]]
[[ i18n.your_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.expected_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.sql_error ]]
[[ error ]]
💡 [[ i18n.hint_label ]] [[ testData.hint ]]
📊 [[ i18n.expected_result_label ]]
[[ col ]]
[[ formatCell(cell) ]]
✨ [[ i18n.solution_label ]]
[[ testData.solution ]]
Tabelle Disponibili
[[ table.name ]]
[[ col ]]
[[ formatCell(cell) ]]

Calculating Age in Different Units

Sometimes you need the difference in months, years, or other units rather than just days.

Months Between Dates

-- SQL Server - precise months
SELECT DATEDIFF(month, '2024-01-15', '2024-06-20') as months_diff;
-- Returns: 5

-- MySQL
SELECT TIMESTAMPDIFF(MONTH, '2024-01-15', '2024-06-20') as months_diff;
-- Returns: 5

-- PostgreSQL
SELECT EXTRACT(YEAR FROM AGE('2024-06-20', '2024-01-15')) * 12 +
       EXTRACT(MONTH FROM AGE('2024-06-20', '2024-01-15')) as months_diff;

-- SQLite (approximate - dividing days by 30)
SELECT CAST((julianday('2024-06-20') - julianday('2024-01-15')) / 30 AS INTEGER);
-- Returns: 5

Years Between Dates

-- SQL Server
SELECT DATEDIFF(year, '2020-03-15', '2024-06-20') as years_diff;

-- MySQL
SELECT TIMESTAMPDIFF(YEAR, '2020-03-15', '2024-06-20') as years_diff;

-- PostgreSQL
SELECT EXTRACT(YEAR FROM AGE('2024-06-20', '2020-03-15')) as years_diff;

-- SQLite (approximate)
SELECT CAST((julianday('2024-06-20') - julianday('2020-03-15')) / 365 AS INTEGER);

Try it yourself:

[[ expanded ? '▼' : '▶' ]]

[[ testData.title ]]

Query the accounts table to return account_name, created_date, and calculate age_months showing how many complete months old each account is (as of ‘2024-06-01’). Order by age in months descending.

Esempio Interattivo ✓ Completato
Colonne attese: [[ col ]]
ℹ️ Questo esercizio reimposta il database ad ogni esecuzione. Scrivi la tua soluzione completa in un'unica sottomissione.
[[ i18n.correct ]] [[ validationResult ? i18n.all_checks_passed : i18n.query_success ]]
[[ detail.message ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.not_quite_right ]] [[ patternError ]] [[ validationResult.error ]] [[ i18n.results_dont_match ]]
[[ detail.passed ? '✓' : '✗' ]] [[ detail.message ]]
[[ i18n.your_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.expected_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.sql_error ]]
[[ error ]]
💡 [[ i18n.hint_label ]] [[ testData.hint ]]
📊 [[ i18n.expected_result_label ]]
[[ col ]]
[[ formatCell(cell) ]]
✨ [[ i18n.solution_label ]]
[[ testData.solution ]]
Tabelle Disponibili
[[ table.name ]]
[[ col ]]
[[ formatCell(cell) ]]

Working with Date Ranges

Finding records within a certain number of days from a target date is another common pattern.

-- Find all events within 7 days of a target date
-- SQL Server
SELECT event_name, event_date
FROM events
WHERE ABS(DATEDIFF(day, event_date, '2024-04-15')) <= 7;

-- MySQL
SELECT event_name, event_date
FROM events
WHERE ABS(DATEDIFF(event_date, '2024-04-15')) <= 7;

-- SQLite
SELECT event_name, event_date
FROM events
WHERE ABS(julianday(event_date) - julianday('2024-04-15')) <= 7;

Try it yourself:

[[ expanded ? '▼' : '▶' ]]

[[ testData.title ]]

Query the events table to find all events that occurred within 7 days before or after ‘2024-04-15’. Return event_name, event_date, and days_from_target showing the difference (negative for before, positive for after). Order by event_date.

Esempio Interattivo ✓ Completato
Colonne attese: [[ col ]]
ℹ️ Questo esercizio reimposta il database ad ogni esecuzione. Scrivi la tua soluzione completa in un'unica sottomissione.
[[ i18n.correct ]] [[ validationResult ? i18n.all_checks_passed : i18n.query_success ]]
[[ detail.message ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.not_quite_right ]] [[ patternError ]] [[ validationResult.error ]] [[ i18n.results_dont_match ]]
[[ detail.passed ? '✓' : '✗' ]] [[ detail.message ]]
[[ i18n.your_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.expected_results ]]
[[ col ]]
[[ formatCell(cell) ]]
[[ i18n.sql_error ]]
[[ error ]]
💡 [[ i18n.hint_label ]] [[ testData.hint ]]
📊 [[ i18n.expected_result_label ]]
[[ col ]]
[[ formatCell(cell) ]]
✨ [[ i18n.solution_label ]]
[[ testData.solution ]]
Tabelle Disponibili
[[ table.name ]]
[[ col ]]
[[ formatCell(cell) ]]

Practical Examples

Customer Tenure Analysis

Calculate how long customers have been with you:

-- SQLite example
SELECT 
  customer_name,
  signup_date,
  CAST((julianday('now') - julianday(signup_date)) / 365 AS INTEGER) as years_with_us,
  CASE 
    WHEN julianday('now') - julianday(signup_date) < 365 THEN 'New'
    WHEN julianday('now') - julianday(signup_date) < 730 THEN 'Established'
    ELSE 'Loyal'
  END as customer_tier
FROM customers;

SLA Monitoring

Track response times against service level agreements:

-- SQLite example
SELECT 
  ticket_id,
  created_at,
  resolved_at,
  CAST(julianday(resolved_at) - julianday(created_at) AS INTEGER) as resolution_days,
  CASE 
    WHEN julianday(resolved_at) - julianday(created_at) <= 3 THEN 'Within SLA'
    ELSE 'SLA Breach'
  END as sla_status
FROM support_tickets;

Subscription Renewals

Find subscriptions expiring within a certain period:

-- SQLite example - subscriptions expiring in next 30 days
SELECT 
  customer_name,
  subscription_end,
  CAST(julianday(subscription_end) - julianday('now') AS INTEGER) as days_remaining
FROM subscriptions
WHERE julianday(subscription_end) - julianday('now') BETWEEN 0 AND 30
ORDER BY days_remaining;

Common Pitfalls

NULL Date Values

Date difference calculations return NULL if either date is NULL:

-- This returns NULL, not an error
SELECT julianday(NULL) - julianday('2024-01-01');

-- Handle NULLs explicitly
SELECT COALESCE(
  CAST(julianday(end_date) - julianday(start_date) AS INTEGER),
  0
) as duration_days
FROM projects;

Date Format Issues

Ensure your dates are in the correct format:

-- SQLite expects ISO format: YYYY-MM-DD
-- This works:
SELECT julianday('2024-01-15');

-- This might not work as expected:
SELECT julianday('15-01-2024');
SELECT julianday('01/15/2024');

Time Component Surprises

When dates include time components, results might not match expectations:

-- These are technically 0 days apart (same calendar day)
-- but the difference includes the time component
SELECT julianday('2024-01-15 23:59:59') - julianday('2024-01-15 00:00:00');
-- Returns: ~0.999988

-- Strip time for day-only calculations
SELECT julianday(date('2024-01-15 23:59:59')) - julianday(date('2024-01-15 00:00:00'));
-- Returns: 0

Performance Tips

Index Date Columns

If you frequently filter or calculate based on dates, index those columns:

CREATE INDEX idx_orders_order_date ON orders(order_date);
CREATE INDEX idx_orders_ship_date ON orders(ship_date);

Avoid Functions in WHERE Clauses

Functions on columns prevent index usage:

-- Bad: Function on column prevents index use
SELECT * FROM orders
WHERE julianday(order_date) > julianday('2024-01-01');

-- Better: Compare directly
SELECT * FROM orders
WHERE order_date > '2024-01-01';

Pre-calculate for Reporting

For complex date calculations in reports, consider storing calculated values:

-- Add a calculated column or separate table for frequently-needed values
ALTER TABLE orders ADD COLUMN fulfillment_days INTEGER;

UPDATE orders 
SET fulfillment_days = CAST(julianday(ship_date) - julianday(order_date) AS INTEGER)
WHERE ship_date IS NOT NULL;

Working with Date Calculations in Beekeeper Studio

When working with complex date calculations, a powerful SQL editor makes the difference. Beekeeper Studio provides excellent support for writing and testing date queries.

Features that help with date calculations:

  • Query autocompletion: Suggests date functions as you type
  • Result formatting: Displays dates in readable formats
  • Multi-database support: Work with date functions across PostgreSQL, MySQL, SQLite, SQL Server, and more
  • Query history: Save and reuse your date calculation patterns

The free version includes everything you need to master SQL date calculations, making it perfect for both learning and production database work.

Key Takeaways

Calculating date differences is fundamental for database work. Here’s what to remember:

  • DATEDIFF syntax varies by database - learn your specific system’s approach
  • SQLite uses julianday() for date arithmetic since it lacks a native DATEDIFF
  • Order matters - know which date comes first to get positive or negative results
  • Handle NULL values - date calculations with NULL return NULL
  • Watch date formats - use ISO format (YYYY-MM-DD) for consistency
  • Consider time components - use date() function when you need day-only calculations
  • Index date columns - improve performance for date-based queries
  • Test edge cases - leap years, month boundaries, and timezone issues can surprise you

By mastering date difference calculations, you’ll be equipped to handle aging reports, track durations, monitor deadlines, and build time-aware applications. Whether calculating customer tenure or finding overdue tasks, these techniques are essential for real-world database work.

Ready to practice more? Try the interactive examples above, or explore more SQL tutorials to continue building your database expertise.

Beekeeper Studio È Una GUI per Database Gratuita e Open Source

Il miglior strumento per query SQL ed editor che abbia mai usato. Fornisce tutto ciò di cui ho bisogno per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta molti database e funziona benissimo su Windows, Mac e Linux.

La versione Linux di Beekeeper è al 100% completa, senza tagli e senza compromessi sulle funzionalità.

Cosa Dicono Gli Utenti Di Beekeeper Studio

★★★★★
"Beekeeper Studio ha completamente sostituito il mio vecchio workflow con SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
— Alex K., Sviluppatore Database
★★★★★
"Ho provato molte GUI per database, ma Beekeeper trova il perfetto equilibrio tra funzionalità e semplicità. Funziona e basta."
— Sarah M., Ingegnere Full Stack

Pronto a Migliorare il Tuo Workflow con SQL?

download Scarica Gratis