Date and time functions extract calendar parts, perform temporal arithmetic and format values, with substantial syntax and time-zone differences between databases.
A monthly report should include the intended calendar period without losing records at its boundaries. Begin with the temporal meaning and stored type, then choose an engine-specific function. Text formatting alone is not a substitute for correct date arithmetic.
This reference adds detail to the main course. You can read it independently: the small database below supplies every table and row used in the examples. Start with the question each query answers, then compare the returned values with the data rather than memorising a line of syntax.
Set up the practice database
Run this setup once in a new practice database, before the examples. It uses four customers and six sales. Ana has two sales, Ben has one, Cara has two, and Dev has none.
Sale 106 has no customer link; sale 104 has an unknown amount. These deliberate test cases expose missing information and unmatched relationships.
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(40) NOT NULL,
city VARCHAR(40),
manager_id INTEGER
);
CREATE TABLE sales (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
amount DECIMAL(10,2),
status VARCHAR(20) NOT NULL,
created_on DATE NOT NULL
);
INSERT INTO customers (id,name,city,manager_id) VALUES
(1,'Ana','Leeds',NULL),(2,'Ben','Leeds',1),
(3,'Cara','Porto',1),(4,'Dev',NULL,2);
INSERT INTO sales (id,customer_id,amount,status,created_on) VALUES
(101,1,10,'paid','2026-01-01'),
(102,1,30,'pending','2026-01-02'),
(103,2,20,'paid','2026-01-02'),
(104,3,NULL,'pending','2026-02-01'),
(105,3,20,'paid','2026-02-02'),
(106,NULL,5,'paid','2026-02-03');An amount of zero would be a known value. The NULL amount here means the value is unknown. A customer with no matching sale differs from a sale whose customer_id is NULL.
The primary keys identify individual records even when amounts or cities repeat. Dates use year-month-day format. The examples specify sorting whenever order matters; insertion order alone does not guarantee display order.
How SQL date and time functions works
Separate a date, a time of day and a timestamp. The sample created_on values are dates, so they have no saved clock time or time-zone offset. An application event timestamp may require an instant in time, a local wall-clock representation, or both. A calendar month in the user’s time zone can start at a different instant from the same month in UTC. Define that reporting zone before grouping events into days or months.
Use half-open ranges for periods: created_on >= '2026-01-01' AND created_on < '2026-02-01' includes all January dates. The same pattern is safer for timestamps than BETWEEN with a final midnight or an invented last fractional second. It also leaves the column unwrapped by a date-extraction function, which can help a normal index satisfy a range filter. Type and parameter handling should be appropriate for the engine rather than relying on ambiguous regional date strings.
Extracting years, months and other parts
Extracting a year or month can be useful for labels and grouping. PostgreSQL uses EXTRACT, MySQL offers YEAR and MONTH as well as EXTRACT, SQL Server uses DATEPART and related functions, and SQLite commonly uses strftime. These are dialect choices, not one universal function spelling. Formatting a date as a month name produces text and may have locale-dependent behaviour; retain a chronological key when those labels need sorting.
Adding a month is not always the same as adding thirty days. End-of-month dates and leap years require the engine’s documented calendar rules. Timestamp differences can count elapsed duration or crossed calendar boundaries, depending on the function. SQL Server DATEDIFF counts boundaries rather than simply returning fractional elapsed units. PostgreSQL intervals, MySQL DATE_ADD, SQL Server DATEADD and SQLite modifiers have distinct syntax. Test the boundary dates relevant to the actual application, including daylight-saving changes when working with local times.
MySQL, PostgreSQL, SQL Server and SQLite
The shown date range is suitable for these sample date values in all four systems. SQLite has no dedicated native date storage type; its date functions work with supported text, Julian-day or Unix-time representations as specified. Use strftime in SQLite, EXTRACT in PostgreSQL, and documented dialect functions in MySQL and SQL Server for parts and arithmetic.
Check the engine-specific syntax and version requirements in SQLite date and time functions, PostgreSQL temporal functions.
Practice task and worked solution
Return the February sales using a half-open range ending at March 1. Keep the saved date values in the output.
Try the task before reading its worked solution. The supplied rows make the expected answer checkable by hand.
SELECT id,created_on FROM sales
WHERE created_on >= '2026-02-01'
AND created_on < '2026-03-01' ORDER BY id;id | created_on
104 | 2026-02-01
105 | 2026-02-02
106 | 2026-02-03The three February rows lie on or after the included start and before the excluded next-month start. This includes the first day correctly and would exclude a March 1 row. Because the sample field is date-only, no timezone conversion is implied by this query.
Change the January filter’s upper bound from exclusive February 1 to inclusive February 1 and predict that sale 104 now enters. Restore the half-open form and compare January and February as adjacent nonoverlapping ranges. In a separate timestamp example, place a value at noon on the final day to show why an upper midnight cutoff is not a full-day boundary.
SQL Date and Time Functions: Ranges, Parts and Time Zones Syntax
SQL date and time functions
SELECT id,created_on FROM sales
WHERE created_on >= '2026-01-01'
AND created_on < '2026-02-01' ORDER BY id;SQL Date and Time Functions: Ranges, Parts and Time Zones Summary
- Distinguish dates, times of day and timestamps; only some timestamp types record a time zone.
- Filter a period with
>=its start and<the next period's start, which works for dates and timestamps. - Extracting parts uses different functions:
EXTRACTin PostgreSQL,YEARin MySQL,DATEPARTin SQL Server andstrftimein SQLite. - Calendar arithmetic must allow for month lengths and leap years; a month isn't always 30 days.
- Store dates in a proper date type or ISO text, never in a local display format.
SQL Date and Time Functions: Ranges, Parts and Time Zones Examples
Each example shows the code, the output it produces and what each part does.
All sales in January 2026
The lower boundary is included and the next month’s beginning is excluded. Sales 101 through 103 fall in January. Sale 104 begins February and is outside the range. No date-part function is needed for this period filter.
SELECT id,created_on FROM sales
WHERE created_on >= '2026-01-01'
AND created_on < '2026-02-01' ORDER BY id;id | created_on
101 | 2026-01-01
102 | 2026-01-02
103 | 2026-01-02Common SQL Date and Time Functions: Ranges, Parts and Time Zones Mistakes
BETWEEN on timestamps and sorting month names
Filtering a timestamp with BETWEEN January 1 and January 31 can exclude most of January 31 when the upper value represents midnight. Use a lower-inclusive, next-period-exclusive range. Another mistake is sorting formatted month names alphabetically, which is not calendar order.
SQL Date and Time Functions: Ranges, Parts and Time Zones in Real Projects
Period boundaries in a monthly dashboard
A monthly sales dashboard should document its calendar zone and whether its stored field is a date or an event instant. Compute period boundaries consistently and parameterise them. When a report combines historical and live timestamps, check that both are interpreted with the same timezone policy.
Store the reporting timezone and period boundary policy with a timestamp-based report. Keep a typed chronological key when displaying month names, because alphabetical label order is not date order. A month boundary should be computed as a calendar boundary in the intended zone rather than a fixed number of seconds copied from another reporting environment.
SQL Date and Time Functions: Ranges, Parts and Time Zones FAQ
Can I store dates as arbitrary display text?
No. Text such as 05/01/2026 makes validation and ordering difficult and is ambiguous between countries. Use the engine's temporal type, or in SQLite a consistent supported representation such as ISO YYYY-MM-DD text, which sorts correctly.
Is one month thirty days?
No. Calendar-month arithmetic must account for varying month lengths and leap years. Use the database's interval or date functions, such as date(created_on, '+1 month') in SQLite or created_on + INTERVAL '1 month' in PostgreSQL, rather than adding 30 days.
Does a date contain a timezone?
No. A date-only value identifies a calendar day; timestamp and zone semantics depend on the chosen database type. PostgreSQL's TIMESTAMPTZ records an exact moment, while a plain TIMESTAMP or DATETIME stores wall-clock time without a zone.
How do I get today's date in SQL?
Use CURRENT_DATE in PostgreSQL, MySQL and SQLite, and CAST(GETDATE() AS DATE) in SQL Server. For the current date and time, use CURRENT_TIMESTAMP, which works almost everywhere. Remember that "today" depends on the session's or server's time zone.
How do I add days to a date?
Use date arithmetic: created_on + INTERVAL '7 days' in PostgreSQL, DATE_ADD(created_on, INTERVAL 7 DAY) in MySQL, DATEADD(day, 7, created_on) in SQL Server and date(created_on, '+7 days') in SQLite. The dates and times lesson has more examples.
SQL Date and Time Functions: Ranges, Parts and Time Zones Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which sale ids fall in the February half-open range?
SQL Date and Time Functions: Ranges, Parts and Time Zones Quiz
2 questions to check what you learned.
Which range safely expresses a full calendar month?
- At or after its start and before the next month starts
- Strictly after the month starts and through its last midnight
- Any timestamp between the first and last date names, regardless of clock time
Which SQLite function commonly extracts formatted date parts?
- DATEPART
- strftime
- EXTRACT