On this page
Syntax
CURRENT_DATECURRENT_DATE()CURDATE()CAST(GETDATE() AS DATE) | Parameter | Type | Required | Description |
|---|---|---|---|
(none) |
n/a | no | CURRENT_DATE takes no arguments. In ANSI SQL it is used as a keyword with no parentheses. |
How it works
CURRENT_DATE is the ANSI SQL function for "today". It returns a DATE value (year, month and day) and, unlike NOW(), it carries no hours, minutes or seconds. It is the natural building block for reports such as "orders placed today" or "invoices due this week".
Support differs by engine. PostgreSQL and MySQL both implement the ANSI keyword CURRENT_DATE (MySQL also accepts CURRENT_DATE() and the alias CURDATE()). SQLite has no CURRENT_DATE function call but does expose CURRENT_DATE as a special keyword, and DATE('now') is the idiomatic form. SQL Server has no CURRENT_DATE at all: use CAST(GETDATE() AS DATE) (or CAST(SYSDATETIME() AS DATE)).
The value reflects the clock and time zone of the database server, not the client. In PostgreSQL CURRENT_DATE honours the session time zone, while in MySQL it follows the session time_zone setting. Because a date rolls over at midnight, running the same query either side of midnight (or in a different time zone) can return a different day, so store timestamps carefully and be explicit about UTC when it matters. See all SQL functions for related date and time helpers.
Examples
Get today's date
SELECT CURRENT_DATE AS today;
today ---------- 2026-07-05
Filter rows created today
-- created_at is a DATE column here
SELECT id, customer_id, total
FROM orders
WHERE created_at = CURRENT_DATE;
id | customer_id | total ----+-------------+------- 91 | 12 | 40.00 92 | 34 | 15.50
Compute days until a due date
SELECT id,
due_date,
due_date - CURRENT_DATE AS days_left
FROM invoices
WHERE status = 'open'
ORDER BY days_left;
id | due_date | days_left ---+------------+---------- 7 | 2026-07-06 | 1 3 | 2026-07-10 | 5 9 | 2026-07-20 | 15
Per-engine equivalents for today
-- PostgreSQL / MySQL (ANSI)
SELECT CURRENT_DATE;
-- MySQL alias
SELECT CURDATE();
-- SQL Server (no CURRENT_DATE)
SELECT CAST(GETDATE() AS DATE);
-- SQLite
SELECT DATE('now');
today ---------- 2026-07-05
Rows created today from a DATETIME column
-- created_at stores a full timestamp, so use a range
SELECT COUNT(*) AS orders_today
FROM orders
WHERE created_at >= CURRENT_DATE
AND created_at < CURRENT_DATE + INTERVAL '1' DAY;
orders_today
------------
37Common mistakes
-- created_at is a DATETIME. This only matches rows
-- stamped at exactly midnight, missing the rest of today.
SELECT *
FROM orders
WHERE created_at = CURRENT_DATE;
Right
-- Use a half-open range so every time today is included
SELECT *
FROM orders
WHERE created_at >= CURRENT_DATE
AND created_at < CURRENT_DATE + INTERVAL '1' DAY;
Comparing a DATETIME column directly to CURRENT_DATE compares against midnight, so later rows from today are silently dropped. Filter with a range from CURRENT_DATE up to (but not including) tomorrow.
-- Fails on SQL Server: CURRENT_DATE does not exist
SELECT CURRENT_DATE;
Right
-- SQL Server: cast the current timestamp to DATE
SELECT CAST(GETDATE() AS DATE);
SQL Server has no CURRENT_DATE. Use CAST(GETDATE() AS DATE) or CAST(SYSDATETIME() AS DATE). See NOW() for the cross-dialect timestamp equivalents.
-- Assumes the server clock matches the user's zone.
-- Near midnight this can report the wrong day.
SELECT *
FROM events
WHERE event_date = CURRENT_DATE;
Right
-- Be explicit about the time zone you mean, e.g. UTC
SELECT *
FROM events
WHERE event_date = (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')::date;
CURRENT_DATE uses the database server time zone, not the client. If users span zones, decide on a canonical zone (often UTC) and convert explicitly, or the date can roll over at the wrong moment.
Performance
CURRENT_DATE itself is trivially cheap: it is evaluated once per statement, not once per row, so there is no per-row cost to referencing it in a WHERE clause.
The real performance question is whether your filter can use an index. A predicate like created_at >= CURRENT_DATE AND created_at < CURRENT_DATE + INTERVAL '1' DAY is sargable and can use an index on created_at. Wrapping the column in a function, such as CAST(created_at AS DATE) = CURRENT_DATE, usually defeats the index and forces a full scan.
For repeated "today" reporting on large tables, keeping the range form lets the optimiser do an index range scan. See the indexing guide for why sargable predicates matter.
Interview questions
What is the difference between CURRENT_DATE and NOW()?
CURRENT_DATE returns only the date (no time), while NOW() returns a full timestamp with date and time. Use CURRENT_DATE when the time of day is irrelevant.
How do you get today's date in SQL Server, which has no CURRENT_DATE?
Cast the current timestamp to DATE: CAST(GETDATE() AS DATE) or CAST(SYSDATETIME() AS DATE). SQL Server does not implement the ANSI CURRENT_DATE keyword.
SELECT CAST(GETDATE() AS DATE) AS today;
How do you select all rows created today when the column is a DATETIME?
Use a half-open range instead of equality: created_at >= CURRENT_DATE AND created_at < CURRENT_DATE + INTERVAL '1' DAY. Comparing a DATETIME straight to CURRENT_DATE only matches rows stamped at midnight.
SELECT * FROM orders
WHERE created_at >= CURRENT_DATE
AND created_at < CURRENT_DATE + INTERVAL '1' DAY;
Is CURRENT_DATE affected by time zones?
Yes. It reflects the database server clock and its time zone, not the client. Near midnight, or across regions, that can yield a different calendar day, so convert to a canonical zone such as UTC when it matters.
What is CURDATE() and how does it relate to CURRENT_DATE?
In MySQL CURDATE() is an alias for CURRENT_DATE; both return today's date. MySQL also accepts CURRENT_DATE() with parentheses. Other engines do not have CURDATE().