CMD Guide
HomeDatabasesSQL Fundamentals

Date Functions

MySQL date/time functions, with outputs you can trust

Dates are a common source of silently-wrong reports, so here are the core functions with verified results. "Now" comes in three resolutions:

NOW()      -- 2024-03-09 14:32:05   (date + time)
CURDATE()  -- 2024-03-09            (date only)
CURTIME()  -- 14:32:05              (time only)

Formatting: DATE_FORMAT(date, format)

The format string uses % specifiers. The case matters — %m is a zero-padded month number, %M is the month name:

SpecifierMeansExample (2024-03-09)
%Y / %yyear 4-digit / 2-digit2024 / 24
%m / %Mmonth number / name03 / March
%d / %Dday number / ordinal09 / 9th
%H:%i:%shour:min:sec14:32:05
%Wweekday nameSaturday
DATE_FORMAT('2024-03-09', '%d/%m/%Y')      -- '09/03/2024'
DATE_FORMAT('2024-03-09', '%W, %M %D %Y')  -- 'Saturday, March 9th 2024'

Arithmetic: differences and offsets

DATEDIFF('2024-03-10', '2024-03-01')          -- 9   (arg1 - arg2, in days)
DATE_ADD('2024-03-09', INTERVAL 7 DAY)        -- '2024-03-16'
DATE_SUB('2024-03-09', INTERVAL 1 MONTH)      -- '2024-02-09'
TIMESTAMPDIFF(YEAR, '1990-05-01', '2024-03-09') -- 33   (whole years)
YEAR('2024-03-09'), MONTH(...), DAY(...)      -- 2024, 3, 9

Cross-engine map (MySQL ↔ Postgres)

TaskMySQLPostgreSQL
Current timestampNOW(), CURRENT_TIMESTAMPsame
Format for displayDATE_FORMAT(ts, '%Y-%m')to_char(ts, 'YYYY-MM')
Truncate to day/monthDATE(ts), DATE_FORMAT(ts,'%Y-%m-01')date_trunc('day', ts), date_trunc('month', ts)
Add intervalDATE_ADD(ts, INTERVAL 7 DAY)ts + INTERVAL '7 days'
Difference in daysDATEDIFF(a,b)a::date - b::date
Extract yearYEAR(ts)EXTRACT(YEAR FROM ts)

date_trunc is the Postgres workhorse for grouping ("orders per month"): group by date_trunc('month', created_at) rather than formatting to a string.

TIMESTAMP vs TIMESTAMPTZ (and MySQL's DATETIME)

-- Postgres: store instants as timestamptz
created_at TIMESTAMPTZ NOT NULL DEFAULT now();

-- Filter a UTC day correctly (half-open):
WHERE created_at >= TIMESTAMPTZ '2024-03-09 00:00:00+00'
  AND created_at <  TIMESTAMPTZ '2024-03-10 00:00:00+00';

DST and "add one day" traps

Civil time is not uniform. In US zones that observe DST, "add 24 hours" and "add 1 calendar day" diverge on spring-forward/fall-back nights. DATE_ADD(ts, INTERVAL 1 DAY) / Postgres ts + INTERVAL '1 day' follow calendar arithmetic on timestamp types in ways that can jump wall clocks; for absolute durations prefer interval hours on timestamptz and convert for display only. Never implement "business day" logic as raw hour arithmetic without a calendar library.

Pitfalls

Takeaways


Re-authored for correctness and cross-engine depth for this guide (the prior version had a repeated DATE_FORMAT error; timezone/DST/Postgres map added). Per the MySQL date-and-time functions reference and PostgreSQL datetime docs. See also: WHERE Clause, Indexes (sargability), SQL Fundamentals semantic gotchas (timezone deep dive).

🎯 STRICT STANDOUT: Why / worked / when-not / failure / drills — Date Functions

Why this concept exists (judgment chain)

Date bugs are silent: wrong format case, non-sargable YEAR(col), wall-clock vs absolute time, DST “add one day.” Cross-engine maps and half-open ranges are production hygiene, not trivia.

Worked example with numbers or traced steps

DATE_FORMAT('2024-03-09','%d/%m/%Y') → 09/03/2024
DATEDIFF('2024-03-10','2024-03-01') → 9 calendar days
Sargable year filter:
  created >= '2024-01-01' AND created < '2025-01-01'
  -- not WHERE YEAR(created)=2024
Postgres events: TIMESTAMPTZ + date_trunc('month', created_at)
DST: INTERVAL '1 day' ≠ 24 hours on spring-forward nights.

When NOT to use / named alternative

Do not store local wall times as UTC without documenting zone. Do not GROUP BY DATE_FORMAT strings when date_trunc/DATE keeps order and type. Avoid business-day logic with raw hour arithmetic — use a calendar library. Prefer TIMESTAMPTZ for events; TIMESTAMP-without-tz only for zone-free civil schedules.

Failure / ops fingerprint

Fingerprint: index ignored on YEAR(created); reports off by one day near DST; MySQL TIMESTAMP converting via session time_zone unexpectedly. Ops: set DB and app to UTC; half-open ranges in all daily jobs; monitor session time_zone drift.

Hostile-panel drills (defend the decision)

Q1. %m vs %M in MySQL DATE_FORMAT?
Model answer: %m is zero-padded month number (03); %M is month name (March). Case changes meaning.

Q2. Why half-open ranges for a day?
Model answer: >= start AND < next_day includes full day, avoids 23:59:59 leap/precision bugs, stays sargable.

Q3. TIMESTAMP vs TIMESTAMPTZ in Postgres?
Model answer: TIMESTAMP is wall-clock without zone; TIMESTAMPTZ stores absolute instants (UTC internally). Prefer TIMESTAMPTZ for “when did this happen.”

🤖 Don't fully get this? Learn it with Claude

Stuck on Date Functions? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Date Functions** (Databases) and want to truly understand it. Explain Date Functions from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Date Functions** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Date Functions** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Date Functions** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes