Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
MySQL provides a full suite of date and time functions. The main types you’ll work with are DATE (date only), TIME (time only), DATETIME (date + time, no timezone), and TIMESTAMP (date + time, stored in UTC, displayed in session timezone). See Timestamps and Time Zones in MySQL for timezone handling details.

Getting the Current Date and Time

NOW() is evaluated once at the start of a statement — all rows in the same INSERT get the same timestamp. SYSDATE() is evaluated each time it’s called.

Formatting Dates

DATE_FORMAT converts a date or datetime to a string using a format string:
Common format specifiers:

Parsing Strings to Dates

STR_TO_DATE converts a string to a date using the same format specifiers:
Returns NULL if the string doesn’t match the format.

Date Arithmetic

DATE_ADD / DATE_SUB — add or subtract an interval:
Interval units: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR. Shorthand with + and - operators:
DATEDIFF — days between two dates:
DATEDIFF only counts days, not time. For time-aware differences, use TIMESTAMPDIFF:
TIMESTAMPDIFF(unit, from, to) — note that from comes before to.

Extracting Date Parts

EXTRACT / YEAR / MONTH / DAY:
DAYOFWEEK / DAYOFYEAR / WEEK:

Truncating to a Period

To group data by month, week, or day, truncate the datetime to the period boundary:

Unix Timestamps

Common Patterns

Records from the last 30 days:
Records from the current month:
Age from a birthdate:

Frequently Asked Questions

What’s the difference between NOW() and SYSDATE()?

NOW() returns the timestamp when the statement began executing — all rows in a single INSERT or UPDATE get the same value. SYSDATE() returns the actual clock time at the moment it’s called, so rows inserted in a loop get different values. For audit timestamps where consistency within a transaction matters, NOW() is almost always the right choice.

Why does DATE_ADD with INTERVAL 1 MONTH behave oddly at month-end?

MySQL clamps to the last valid day. DATE_ADD('2024-01-31', INTERVAL 1 MONTH) returns 2024-02-29 (leap year) or 2024-02-28. This is expected behavior — there’s no “31st of February.” If you need predictable month arithmetic, truncate to the start of the month first.

Troubleshooting

See also