Truncating a date in MySQL removes the time portion or lower-level units (hour, minute, second) from a DATETIME/TIMESTAMP value, returning only the desired higher-level component such as DATE, month, or year.
Reporting, grouping, and partitioning often require dates without time. Truncating ensures that 2023-10-07 10:23 and 2023-10-07 18:55 become the same key (2023-10-07
) for accurate counts and aggregates.
Use the built-in DATE()
function: DATE(datetime_col)
.It strips hours, minutes, and seconds, returning a DATE value while keeping the original time zone intact.
SELECT DATE(order_date) AS order_day FROM Orders;
produces 2023-10-07
even if order_date
stored a full timestamp.
Apply DATE_FORMAT()
with format specifiers, then cast back to DATE for math safety.
DATE_FORMAT(order_date,'%Y-%m-01')
→ first day of month.DATE_FORMAT(order_date,'%Y-01-01')
→ first day of year.
DATE()
is fastest; CAST(datetime AS DATE)
gives the same result.DATE_FORMAT()
offers flexible patterns but returns VARCHAR unless wrapped in DATE()
or STR_TO_DATE()
.
Applying a function to a column in WHERE or JOIN disables B-tree indexes on that column. Instead, compute the truncated value once and store it, or create a generated column indexed for look-ups.
• Prefer DATE()
for daily roll-ups.
• Use generated columns for indexed searches.
• Store timestamps in UTC; present in local time.
• Avoid truncating in WHERE; compare with range bounds instead.
.
Yes. DATE() is a lightweight wrapper and slightly quicker, but both use the same internal routine. Choose DATE() for readability.
Absolutely. DATE(timestamp_col) works identically because TIMESTAMP is a date-time type. The function ignores the time zone conversion layer and returns a pure DATE.
Create a generated column such as order_day DATE AS (DATE(order_date)) STORED
, then add an index on it. Your queries can filter on order_day without touching order_date.