Lab 16: Date and Time Functions

Time: 30 minutes | Level: Foundations | DB: MySQL 8 / PostgreSQL 15

Overview

Work with dates and times: NOW/CURRENT_TIMESTAMP, formatting, DATEDIFF/AGE, EXTRACT, DATE_ADD/interval arithmetic, and DATE_TRUNC for grouping.


Step 1: Setup

docker run -d --name mysql-lab -e MYSQL_ROOT_PASSWORD=rootpass mysql:8.0
for i in $(seq 1 30); do docker exec mysql-lab mysql -uroot -prootpass -e "SELECT 1" 2>/dev/null && break || sleep 2; done

docker run -d --name pg-lab -e POSTGRES_PASSWORD=rootpass postgres:15
sleep 10

docker exec mysql-lab mysql -uroot -prootpass << 'EOF'
CREATE DATABASE datelab;
USE datelab;

CREATE TABLE events (
    event_id    INT NOT NULL AUTO_INCREMENT,
    event_name  VARCHAR(100) NOT NULL,
    start_date  DATE NOT NULL,
    start_time  TIME,
    start_ts    TIMESTAMP,
    end_date    DATE,
    category    VARCHAR(30),
    PRIMARY KEY (event_id)
);

INSERT INTO events (event_name, start_date, start_time, start_ts, end_date, category) VALUES
('Product Launch',    '2024-01-15', '09:00:00', '2024-01-15 09:00:00', '2024-01-16', 'Marketing'),
('Team Offsite',      '2024-02-20', '08:30:00', '2024-02-20 08:30:00', '2024-02-22', 'HR'),
('Quarterly Review',  '2024-03-31', '14:00:00', '2024-03-31 14:00:00', '2024-03-31', 'Finance'),
('Tech Conference',   '2024-06-10', '09:00:00', '2024-06-10 09:00:00', '2024-06-12', 'Engineering'),
('Annual Summit',     '2024-09-15', '10:00:00', '2024-09-15 10:00:00', '2024-09-17', 'Executive'),
('Year-End Review',   '2024-12-15', '14:00:00', '2024-12-15 14:00:00', '2024-12-15', 'Finance'),
('Sprint Planning',   '2023-11-01', '10:00:00', '2023-11-01 10:00:00', '2023-11-01', 'Engineering'),
('Budget Planning',   '2023-10-15', '09:00:00', '2023-10-15 09:00:00', '2023-10-17', 'Finance');
EOF

Step 2: NOW() and CURRENT_TIMESTAMP

MySQL:

📸 Verified Output:

PostgreSQL equivalents:


Step 3: DATE_FORMAT (MySQL) and TO_CHAR (PostgreSQL)

MySQL — DATE_FORMAT:

📸 Verified Output:

PostgreSQL — TO_CHAR:


Step 4: DATEDIFF (MySQL) and AGE (PostgreSQL)

MySQL:

📸 Verified Output:

PostgreSQL — AGE function:

📸 Verified Output (PostgreSQL):


Step 5: EXTRACT — Get Date Parts

MySQL and PostgreSQL (same syntax):

📸 Verified Output:

PostgreSQL extras:


Step 6: DATE_ADD (MySQL) and Interval Arithmetic (PostgreSQL)

MySQL:

📸 Verified Output:

PostgreSQL — interval arithmetic:


Step 7: DATE_TRUNC (PostgreSQL)

DATE_TRUNC truncates a timestamp to a specified precision — essential for time-based grouping.

📸 Verified Output (DATE_TRUNC group by month):

MySQL equivalent (GROUP BY month):


Step 8: Capstone — Events Report with Date Intelligence

📸 Verified Output:

Cleanup:


Summary

Function
MySQL
PostgreSQL
Notes

Current datetime

NOW()

NOW()

PG includes timezone

Current date

CURDATE()

CURRENT_DATE

Format datetime

DATE_FORMAT(d, '%Y-%m-%d')

TO_CHAR(d, 'YYYY-MM-DD')

Different format codes

Date difference

DATEDIFF(d2, d1)

d2::date - d1::date

Returns days

Humanized diff

N/A

AGE(d2, d1)

Returns interval

Extract part

EXTRACT(YEAR FROM d)

EXTRACT(YEAR FROM d)

Same syntax

Day name

DAYNAME(d)

TO_CHAR(d, 'Day')

Add interval

DATE_ADD(d, INTERVAL n UNIT)

d + INTERVAL 'n unit'

Subtract interval

DATE_SUB(d, INTERVAL n UNIT)

d - INTERVAL 'n unit'

Truncate to unit

DATE_FORMAT(d, '%Y-%m-01')

DATE_TRUNC('month', d)

PG more powerful

Next: Lab 17 — NULL Handling

Last updated