Date and time data types are important because they help track and manage time-based information in databases. This includes things like recording when orders are placed, scheduling events, or calculating the time between two activities. In this article, we will look at differences between how PostgreSQL and MySQL stores and utilizes date and time datatypes.

MySQL and PostgreSQL offer several data types that can be used for handling dates and times. These data types provide the tools to store and manage information like dates of a particular event, timestamps, and even time durations. While they both share some similarities on how they handle date and time, there are key differences in how they handle precision, time zones, and date/time calculations.
Getting date and time data right is key for keeping databases accurate and useful. In this article, we will compare how MySQL and PostgreSQL handle date and time data, their differences, strengths, and which one might work better for your needs. By the end, you’ll have a clearer idea of which database to choose for managing date and time information.
MySQL Date and Time Data Types
MySQL is quite flexible when it comes to accepting date and time values. It provides five main date and time data types, which are, DATE
, DATETIME
, TIMESTAMP
, TIME
, and YEAR
. However, these data types must follow a specific accepted format to ensure the values are correctly stored in the database. Here’s a breakdown of the format MySQL expects for its following date and time values.
Data Type | Expected Format | Example Values | Storage size |
| YYYY-MM-DD | 2025-02-14 | 3 bytes |
| YYYY-MM-DD HH:MM:SS | 2025-02-14 10:30:45 | 8 bytes |
| YYYY-MM-DD HH:MM:SS | 2025-02-14 10:30:45 | 4 bytes |
| HH:MM:SS | 10:30:45 | 3 bytes |
| YYYY | 2025 | 1 byte |
You are also allowed to include fractional seconds (up to 6 digits) into the DATETIME
and TIMESTAMP
values. Values are enclosed in quoted strings during insertion. Here is an example of what this would look like:
1 2 3 4 5 |
CREATE TABLE events ( event_id INT AUTO_INCREMENT PRIMARY KEY, event_time DATETIME NOT NULL, -- Stores exact date and time created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Auto-stores insert time in UTC ); |
Then create a value using an INSERT
statement:
1 |
INSERT INTO events (event_time) VALUES ('2025-02-14 10:30:45.123456'); |
If you insert a value that doesn’t follow the expected format, MySQL handles it based on the sql_mode
setting. In the STRICT_TRANS_TABLES
mode, dates are checked strictly. You can check the setting value using:
1 |
SHOW VARIABLES LIKE 'sql_mode'; |
By default, this will look something like this:
1 |
'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' |
And if there is not a value ‘STRICT_TRANS_TABLES
’ (which there is in my example) then you can set it for your connection using the following statement (which will preserve all other settings):
1 |
set sql_mode = CONCAT(@@sql_mode,',STRICT_TRANS_TABLES'); |
Note: Beware that sql_mode
pertains to more than just date format handling, so check out this article in the MySQL docs before using.
When MySQL encounters an invalid date format, it does the following:
Strict Mode (STRICT_TRANS_TABLES): If strict mode is enabled (default in newer MySQL versions), MySQL rejects invalid dates and throws an error. For example:
1 |
INSERT INTO events (event_time) VALUES ('2025-14-02 10:30:45'); |
MySQL will throw the following error:
SQL Error [1292] [22001]: Data truncation: Incorrect datetime value: ‘2025-14-02 10:30:45’ for column ‘event_time’ at row 1
The error occurred because ‘2025-14-02’ is an invalid date format. In MySQL, a valid DATE format follows YYYY-MM-DD, and the month (14) exceeds the valid range (1-12).
Non-strict mode: If strict mode is disabled, MySQL does not throw an error for invalid dates. Instead, it stores '0000-00-00
‘ for invalid dates instead of rejecting them. Here’s an example:
1 2 |
-- Remove strict mode setting SET sql_mode=(SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES','')); |
Then execute the statement:
1 |
INSERT INTO events (event_time) VALUES ('2025-14-02'); |
You should get back no error message and the data is seemingly stored. But let’s run a SELECT
statement to see how it stored our date value.
1 |
SELECT * FROM events; |
This will return something like:
1 2 3 4 |
event_id|event_time |created_at --------+-------------------+-------------------+ 1|2025-02-14 10:30:45|2025-04-29 11:12:31| 2|0000-00-00 00:00:00|2025-04-29 11:13:58| |
The second row is the one where we had strict mode turned off.
Note that MySQL also allows inserting partial or unknown dates by setting the day or month to 00. This is controlled by the NO_ZERO_IN_DATE
sql mode. (When setting strict mode earlier, you may have seen a warning about a few settings that are going to be a part of strict mode in MySQL. As such, NO_ZERO_IN_DATE is deprecated and will be rolled into strict mode in the future.)
This can be useful for cases where only part of the date is known. Here’s an example of how this works:
1 2 3 4 5 6 7 8 |
-- REMOVE NO_ZERO_IN_DATE setting SET sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_IN_DATE','')); INSERT INTO events (event_time) VALUES ('2025-00-15'); -- Month unknown INSERT INTO events (event_time) VALUES ('2025-02-00'); -- Day unknown select * from events; |
You can see two new rows, each with 00 for a day or month value for event_id
= 3 and 4:
1 2 3 4 5 6 |
event_id|event_time |created_at | --------+-------------------+-------------------+ 1|2025-02-14 10:30:45|2025-04-29 11:12:31| 2|0000-00-00 00:00:00|2025-04-29 11:13:58| 3|2025-00-15 00:00:00|2025-04-29 11:17:45| 4|2025-02-00 00:00:00|2025-04-29 11:17:48| |
Some MySQL functions do not work correctly with 0 values. For example, adding an interval to a 0 date can produce unexpected results. For example:
1 |
SELECT DATE_ADD('2025-00-15', INTERVAL 1 MONTH); |
This returns a NULL
value. So, it is not advisable to use this instead, you can enforce valid dates and disallow 0 values, by enabling strict mode and NO_ZERO_DATE
in sql_mode
.
1 |
set sql_mode = CONCAT(@@sql_mode,',STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE'); |
This ensures that MySQL rejects incomplete dates instead of storing them as 0000-00-00 or allowing 0 for days and months and leaves any other settings intact.
When to Use DATETIME vs. TIMESTAMP
The DATETIME
and TIMESTAMP
data types in MySQL both store date and time values, however, they have distinct differences in their storage and range of values. The DATETIME
data type takes 8 bytes to store a value while TIMESTAMP
uses only 4 bytes, making it more space-efficient.
DATETIME
can store dates from 1000-01-01
to 9999-12-31
, making it suitable for historical records and long-term data while TIMESTAMP
only works from 1970-01-01
to 2038-01-19
, due to its Unix timestamp limitation. If you need to store dates beyond 2038, use the DATETIME
data type.
Note: 2038 is not that far in the future, and if there will be a simple fix is not obvious (at best, if the TIMESTAMP is redefined to include later dates, you may have to convert all of your data, so it may be advised to use DATETIME in future development, especially where future dates may be needed.)
Below is a breakdown of the major differences between the DATETIME
and TIMESTAMP
data type in MySQL:
Feature | DATETIME | TIMESTAMP |
Stores Date & Time? | Yes | Yes |
Time Zone Affected? | No (Stored as-is) | Yes (Stored in UTC, converted to session time zone) |
Storage size | 8 bytes | 4 bytes |
Range | 1000-01-01 00:00:00.000000′ to ‘9999-12-31 23:59:59.499999 | 1970-01-01 00:00:01.000000′ to ‘2038-01-19 03:14:07.499999 |
Best Use Case | When time zone conversion is not needed | When you need timezone-aware timestamps |
Fractional Seconds? | Yes (supports up to 6 decimal places) | Yes (supports up to 6 decimal places) |
Here’s an example with both Data Types:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
CREATE TABLE product ( event_id INT AUTO_INCREMENT PRIMARY KEY, event_name VARCHAR(100), event_time DATETIME, -- Stores exact input created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Adjusts for time zones ); INSERT INTO product (event_name, event_time) VALUES ('Conference', '2025-02-14 10:30:45'), ('Webinar', '2025-03-10 15:00:00'), ('Product Launch', '2025-04-01 09:45:00'); SELECT * FROM product; |
This returns:
1 2 3 4 5 |
event_id|event_name |event_time |created_at | --------+--------------+-------------------+-------------------+ 1|Conference |2025-02-14 10:30:45|2025-04-29 11:30:34| 2|Webinar |2025-03-10 15:00:00|2025-04-29 11:30:34| 3|Product Launch|2025-04-01 09:45:00|2025-04-29 11:30:34| |
In the output, the event_time
column shows the exact date and time you entered while the created_at
column records when the event was added, storing it in UTC and adjusting automatically based on your time zone when retrieved.
So, if you care about time zone conversions, use TIMESTAMP
and if you want a fixed value across all time zones, use DATETIME
.
Handling 2 Digits Years in MySQL
MySQL lets you insert years using just two digits, but it automatically expands them to four digits based on a specific rule:
- If the value is between 00 and 69, MySQL treats it as 2000–2069.
- If the value is between 70 and 99, MySQL treats it as 1970–1999.
This automatic conversion may cause confusion, especially with old or future dates. To avoid mistakes, always use four-digit years (YYYY-MM-DD). Here’s a practical example using our product table created earlier:
1 2 3 4 |
INSERT INTO product (event_time) VALUES ('25-02-14'); INSERT INTO product (event_time) VALUES ('89-12-31'); SELECT event_time FROM product; |
MySQL treated 25-02-14 as ‘2025-02-14’ and also 89-12-31 as ‘1989-12-31’
1 2 3 4 |
event_time | -------------------+ 2025-02-14 00:00:00| 1989-12-31 00:00:00| |
So far, we have covered quite a bit about the Date and Time Data Types in MySQL, but definitely could not cover every detail. For more, check the official documentation on date and time types in the MySQL Documentation.
PostgreSQL Date and Time Data Types
PostgreSQL provides a range of date and time data types for storing simple dates, handling time zones, and managing time intervals. It supports DATE
, TIME
(with time zone), TIME
(without time zone), TIMESTAMP
(with time zone), TIMESTAMP
(without time zone) which can include fractional seconds (up to 6 digits), and INTERVAL
. Here’s a breakdown of the range, storage size, and expected format of the following date and time values.
DataType | Range | Expected Format | Description | Storage Size |
| 4713 BC to 5874897 AD | YYYY:MM:DD | Stores only the calendar date (year, month, day) without a time component. | 4 bytes |
| 00:00:00 to 24:00:00 (24:00:00 is a special case that represents the start of the next day) | HH:MM:SS | Stores only the time of day without any time zone information. | 8 bytes |
| 00:00:00+1559 to 24:00:00-1559 (24:00:00 values represent the start of the next day) | ‘HH:MI:SS+TZ’ | Stores the time of day with an associated time zone offset. | 12 bytes |
| 4713 BC to 294276 AD | YYYY-MM-DD HH:MI:SS | Stores both date and time, but does not include time zone information. | 8 bytes |
| 4713 BC to 294276 AD | YYYY-MM-DD HH:MI:SS+TZ | Stores both date and time, adjusting for time zones automatically based on session settings. | 8 bytes |
| -178 million to +178 million years | quantity unit(e.g., ‘2 days’) | Represents a duration of time, allowing operations like date/time arithmetic. | 16 bytes |
Note: In PostgreSQL, you can control how dates are interpreted by setting the `DateStyle` parameter. The available formats include MDY (month-day-year), DMY (day-month-year), and YMD(year-month-day). This ensures flexibility in handling different regional date formats.
When inserting date and time values in PostgreSQL, they must be enclosed in single quotes. Here’s an example on how you can create a table and insert date and time values in PostgreSQL:
1 2 3 4 5 6 7 8 9 10 11 |
CREATE TABLE events ( event_id SERIAL PRIMARY KEY, event_name VARCHAR(100), event_date DATE, event_time TIME, event_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); INSERT INTO events (event_name, event_date, event_time) VALUES ('Conference', '2025-02-14', '10:30:00'); SELECT * FROM events; |
The output will be as follows:
1 2 3 |
event_id|event_name|event_date|event_time|event_timestamp | --------+----------+----------+----------+-----------------------+ 1|Conference|2025-02-14| 10:30:00|2025-04-29 15:28:59.103| |
If you try to insert the date without enclosing it in a single quote, it will throw an error. Let’s try that:
1 2 |
INSERT INTO events (event_name, event_date, event_time) VALUES ('Conference', 2025-02-14, '10:30:00' ); |
Then you will get an error like the following:
SQL Error [42804]: ERROR: column “event_date” is of type date but expression is of type integer
Hint: You will need to rewrite or cast the expression.
Position: 82
This is because the date expression now looks like an integer mathematical expression of 2024-2-14.
TIMESTAMP WITH vs. WITHOUT TIME ZONE
One of PostgreSQL’s strengths is its ability to handle time zones properly. It offers two types of timestamps. TIMESTAMP WITHOUT TIME ZONE
stores the exact date and time as entered and no automatic time zone conversion, and TIMESTAMP WITH TIME ZONE
converts the stored value to UTC and adjusts it when retrieved based on the session’s time zone. Here’s an example of how both timestamps work:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE TABLE events ( event_id SERIAL PRIMARY KEY, event_name VARCHAR(100), -- Stores exact input with no time zone information event_timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- Adjusts for time zones event_timestamptz TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); INSERT INTO events (event_name, event_timestamp, event_timestamptz) VALUES ('Webinar', '2025-02-14 10:30:00', '2025-02-14 10:30:00'); SELECT event_name, event_timestamp, event_timestamptz FROM events; |
The output should look something like the following:
1 2 3 |
event_name|event_timestamp |event_timestamptz | ----------+-----------------------+-----------------------------+ Webinar |2025-02-14 10:30:00.000|2025-02-14 10:30:00.000 -0500| |
Note that even though the time entered into the event_timestamptz
and event_timestamp
columns looks the same, event_timestamp
is at 10:30, but event_timestamptz
adds the time zone information, so it could be interpreted as 10:30 in the executor’s time zone, or at 5:30 UTC.
Every time you run the INSERT query, it automatically sets the time stamp and adjusts it based on the session’s time zone when retrieved. Meanwhile, event_timestamp
will always stay as the base time 2025-02-14 10:30:00, no matter the session time zone.
If you don’t need time zone adjustments, use TIMESTAMP WITHOUT TIME ZONE
and if your application handles users in different time zones use TIMESTAMP WITH TIME ZONE
.
Special Date And Time Values
PostgreSQL provides predefined constants that make working with dates and times easier. These constants help in retrieving system-generated values without requiring manual input. Here are some of the special date and time values:
Special value | Description |
| Returns only the current date (YYYY-MM-DD). |
| Returns only the current time (HH:MI:SS with optional fractional seconds). |
| Used in place of a specific date value. Represents the current date (similar to CURRENT_DATE). For example: |
| Represents the next day (current date + 1). |
| Represents the previous day (current date – 1). |
| Represents midnight (00:00:00). Equivalent to ’00:00:00′::time. |
| Returns the current date and time. |
| Works the same as |
| Represents a future date that never ends. |
| Represents a past date that has no beginning. |
Note: The CURRENT_DATE()
, CURRENT_TIME()
, CURRENT_TIMESTAMP()
, and NOW()
special date and time values are also available in MySQL and work the same way. But, there are no built-in values for today
, tomorrow
, yesterday
, allballs
, and infinity
like in PostgreSQL.
However, you can work around this by using the largest and smallest possible date values:
- Simulating infinity → Use ‘9999-12-31’, the highest possible date.
- Simulating -infinity → Use ‘0000-00-00’ (if allowed) or ‘1000-01-01’, the lowest supported date. For relative date calculations:
- Today →
CURRENT_DATE()
- Tomorrow →
CURRENT_DATE() + 1
- Yesterday →
CURRENT_DATE() - 1
Here are some examples on using some of these special date and time values in PostgreSQL:
1 |
SELECT CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, NOW(); |
This will return something similar to:

Key difference: CURRENT_TIME
only shows the time, while CURRENT_TIMESTAMP
and NOW()
include both date and time.
The infinity values are useful when you don’t know the exact start or end date of an event. Here’s an example:
1 2 3 4 5 6 7 8 |
CREATE TABLE subscriptions ( user_id SERIAL PRIMARY KEY, start_date DATE DEFAULT CURRENT_DATE, end_date DATE DEFAULT 'infinity' -- No expiration by default ); INSERT INTO subscriptions (user_id) VALUES (1); SELECT * FROM subscriptions; |
This will return:
1 2 3 |
user_id|start_date|end_date| -------+----------+--------+ 1|2025-04-29|infinity| |
The typical use case for the ‘infinity’ and ‘-infinity’ are useful for setting lifelong memberships, permanent bans, or open-ended job contracts.
Let’s try out another example:
1 2 3 4 5 6 7 8 9 10 |
CREATE TABLE events ( event_id SERIAL PRIMARY KEY, event_name TEXT, event_date DATE ); INSERT INTO events (event_name, event_date) VALUES ('Conference', 'today'), -- Stores current date ('Hackathon', 'tomorrow'), -- Stores next day's date ('Workshop', 'yesterday'); -- Stores previous day's date |
Events on today’s date:
1 |
SELECT * FROM events WHERE event_date = 'today'; |
Which as I am finalizing this article is April 28:
1 2 3 |
event_id|event_name|event_date| --------+----------+----------+ 9|Workshop |2025-04-28| |
For earlier than today:
1 |
SELECT * FROM events WHERE event_date < 'today'; |
This returned:
1 2 3 |
event_id|event_name|event_date| --------+----------+----------+ 15|Workshop |2025-04-28| |
And for events in the future:
1 |
SELECT * FROM events WHERE event_date > 'today'; |
Beyond these common built in intervals, you can use the INTERVAL construct for more flexibility
1 2 3 4 5 6 7 |
INSERT INTO events (event_name, event_date) VALUES ('Meetup', CURRENT_DATE + INTERVAL '1 day'), -- Equivalent to 'tomorrow' ('Webinar', CURRENT_DATE - INTERVAL '1 day'), -- Equivalent to 'yesterday' ('Summit', CURRENT_DATE + INTERVAL '1 month'); -- Adds one month select * from events where event_name in ('Meetup','Webinar','Summit') |
Knowing this is the twenty ninth of April, you can see the different values from the INSERT statement in the following output:
1 2 3 4 5 |
event_id|event_name|event_date| --------+----------+----------+ 16|Meetup |2025-04-30| 17|Webinar |2025-04-28| 18|Summit |2025-05-29| |
For more information on the date and time data type, please visit the official PostgreSQL documentation.
MySQL vs PostgreSQL: Comparison of Date and Time Data Types
MySQL and PostgreSQL both offer date and time data types, but there are subtle differences in their flexibility and behaviour. While both databases support DATE, TIME, and TIMESTAMP, MySQL has YEAR as a separate data type, while PostgreSQL does not. PostgreSQL also includes INTERVAL for handling time spans, which MySQL lacks. Here’s a detailed comparison of date and time data type in both databases:
Data Type | MySQL | Range (MySQL) | PostgreSQL | Range (PostgreSQL) | Differences |
Date types |
| Range: 1000-01-01′ to ‘9999-12-31’ |
| Range: 4713 BC’ to ‘5874897 AD’ | Both databases offer |
Datetime types |
| Datetime range: ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’ Timestamp range: ‘1970-01-01 00:00:01′ to ‘2038-01-19 03:14:07’ |
| Range: ‘4713 BC’ to ‘294276 AD’ | PostgreSQL’s |
Time types |
| Range: ‘-838:59:59’ to ‘838:59:59’ | ‘ | Range: ’00:00:00′ to ’24:00:00′ | PostgreSQL’s TIME type has a more conventional range compared to MySQL’s. |
Year types |
| Range: ‘1901’ to ‘2155’ | – | – | MySQL offers a YEAR type specifically for storing year values using 1 byte. PostgreSQL does not have this data type. |
Interval types |
|
|
| Range: Can represent large periods from years to microsecond | PostgreSQL supports |
Note: MySQL has an interval type which is more of an expression/keyword and not a data type. We will see how this works in a bit.
MySQL allows storing invalid dates like ‘0000-00-00’ in non-strict mode, which can lead to unexpected results. But, PostgreSQL enforces strict date validation and does not allow invalid dates. Let’s see this in action:
1 2 3 4 5 6 7 |
CREATE TABLE actions ( user_id SERIAL PRIMARY KEY, start_date DATE DEFAULT CURRENT_DATE, end_date DATE DEFAULT 'infinity' -- No expiration by default ); INSERT INTO subscriptions (start_date) VALUES ('0000-00-00'); |
This input will fail since that is not an allowable value for the DATE
datatype:
SQL Error [22008]: ERROR: date/time field value out of range: “0000-00-00”
Position: 44
Error position: line: 8 pos: 43
One of the differences in date and time data types is how each database handles time zone. PostgreSQL provides TIMESTAMP WITH TIME ZONE (TIMESTAMPTZ),
which automatically converts values to UTC and adjusts them based on the session’s time zone.
MySQL’s TIMESTAMP
also supports automatic time zone conversion, but DATETIME
does not. Instead, it stores the values as inserted.
Date and Time Functions in MySQL and PostgreSQL
Another major difference between both databases is how they handle special dates and time values. Here’s a well detailed table comparing date and time functions in both databases:
Special Value | MySQL Equivalent | PostgreSQL |
|
|
|
|
|
|
|
|
|
| ❌ No direct equivalent | ✅ Supported |
| ❌ No direct equivalent | ✅Used for open-ended ranges |
| ❌ No equivalent | ✅ Used as a midnight shorthand |
While in some cases there are not specific shorthand methods that work across systems ,there are relatively simple ways to get the job done when needed. For example, if you want to store values like ‘today’, ‘tomorrow’, and ‘yesterday’ in MySQL, you can take advantage of the already supported CURRENT_DATE()
function. Here’s how to do this in MySQL:
1 2 3 4 5 6 7 8 9 10 |
CREATE TABLE new_events ( event_id SERIAL PRIMARY KEY, event_name TEXT, event_date DATE ); INSERT INTO new_events (event_name, event_date) VALUES ('Conference', current_date()), -- Stores current date ('Hackathon', current_date() + 1), -- Stores next day's date ('Workshop', current_date() -1); -- Stores previous day's date |
And querying the data in this table, you should get a similar result just like PostgreSQL
1 2 3 4 5 |
event_id|event_name|event_date| --------+----------+----------+ 1|Conference|2025-04-29| 2|Hackathon |2025-04-30| 3|Workshop |2025-04-28| |
Working with Intervals (PostgreSQL vs. MySQL alternative)
PostgreSQL supports INTERVAL
which adds more flexibility and allows you to perform date/time arithmetic directly. It Is a data type that can store time spans. You can add or subtract intervals to dates and timestamps easily.
In MySQL, INTERVAL
is not a data type—it is an expression used for date and time calculations but cannot be stored as a data type. It is used within date arithmetic operations and works with functions like DATE_ADD()
and DATE_SUB(),
or in direct arithmetic expressions. It allows specifying time units (e.g., DAY
, HOUR
, MONTH
).
Here’s an example of how the Interval data type works in PostgreSQL and how it can be handled in MySQL:
PostgreSQL
Using interval, you can add one day to the current timestamp
1 |
SELECT NOW() + INTERVAL '1 day' as Result; -- Adds one day to the current timestamp |
The output of this will be:
1 2 3 |
result | -----------------------------+ 2025-04-30 15:43:41.765 -0400| |
You can also subtract 3 hours from the current timestamp
1 |
SELECT NOW() - INTERVAL '3 hours' as result; -- Subtracts three hours |
Wich will show you 3 hours ago
1 2 3 |
result | -----------------------------+ 2025-04-29 12:44:14.437 -0400| |
You can also add 2 weeks to the current timestamp:
1 |
SELECT NOW() + INTERVAL '2 weeks' as result; -- Adds two weeks |
It also allows you to add values to a specific date too
1 2 |
SELECT '2025-02-14'::DATE + INTERVAL '1 month' as result; -- Adds one month to a specific date |
This, as you can see now gives us 1 month after 2/14:
1 2 3 |
result | -----------------------+ 2025-03-14 00:00:00.000| |
MySQL:
MySQL does not have a built-in INTERVAL
type. Instead, it provides the DATE_ADD()
and DATE_SUB()
functions to achieve similar results. Here’s how we can do this in MySQL. To add one day to the current timestamp using DATE_ADD():
1 |
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY); -- Adds one day |
This will return the following (again, this is mid afternoon on 4/29):
1 2 3 |
DATE_ADD(NOW(), INTERVAL 1 DAY)| -------------------------------+ 2025-04-30 15:46:28| |
To subtract 3 hours from the current timestamp using DATE_SUB():
1 |
SELECT DATE_SUB(NOW(), INTERVAL 3 HOUR); -- Subtracts three hours |
To add two weeks to the current timestamp:
1 |
SELECT DATE_ADD(NOW(), INTERVAL 2 WEEK); -- Adds two weeks |
87weaTo add one month to a particular date:
1 |
SELECT DATE_ADD('2025-02-14', INTERVAL 1 MONTH); -- Adds one month to a specific date |
Just like in the last section:
1 2 3 |
DATE_ADD('2025-02-14', INTERVAL 1 MONTH)| ----------------------------------------+ 2025-03-14 | |
For more detailed information on INTERVAL in MySQL, refer to the MySQL 8.4 Reference Manual on Expression
Key Takeaway
Both MySQL and PostgreSQL provide similar core data types: DATE
, TIME, TIMESTAMP
, and DATETIME
(MySQL) or TIMESTAMP WITH/WITHOUT TIME ZONE
(PostgreSQL).
However, PostgreSQL includes an additional INTERVAL as a data type, allowing direct arithmetic operations for storing time spans, while MySQL uses INTERVAL
only as an expression inside DATE_ADD()
and DATE_SUB()
functions.
PostgreSQL also has built-in time zone support with TIMESTAMP WITH TIME ZONE
, automatically adjusting for session settings while MySQL lacks true time zone-aware timestamps, its TIMESTAMP
type stores values in UTC but requires manual conversion when retrieving data.
PostgreSQL supports special values like ‘infinity’, ‘-infinity’, ‘today’, ‘tomorrow’, ‘yesterday’, and ‘allballs’ (00:00:00). MySQL does not support the following but can use maximum and minimum date values as a workaround.
If your application relies heavily on time zones and intervals, PostgreSQL is more robust. If you need simpler date-time storage and don’t require complex time zone logic, MySQL works fine. PostgreSQL is also stricter in enforcing valid date formats, while MySQL allows more flexibility (sometimes at the cost of unexpected behavior).
Load comments