Choosing the Right MySQL Date/Time Type: DATETIME vs TIMESTAMP vs Unix Timestamp
This article explains why storing dates as strings is inefficient, compares MySQL DATETIME and TIMESTAMP—including storage size, range, timezone handling, and performance—and discusses when to use numeric Unix timestamps or PostgreSQL equivalents for reliable time data management.
In everyday software development, storing time information correctly is essential for business logic and system stability, making the proper choice of MySQL date‑time types crucial.
Don’t Store Dates as Strings
Many beginners initially use VARCHAR to store dates like "YYYY‑MM‑DD HH:MM:SS", but this approach has two major drawbacks:
Space Efficiency : Strings consume more storage than MySQL’s native date‑time types.
Query and Calculation Efficiency :
Complex and Slow Comparisons : String comparison follows lexical order, which is error‑prone and slower than numeric or native date comparisons.
Limited Calculation Functions : You cannot directly use MySQL’s rich date‑time functions without converting the format.
Poor Index Performance : String indexes are less efficient for range queries compared to native date‑time indexes.
DATETIME vs TIMESTAMP Selection
DATETIMEand
TIMESTAMPare the two most common MySQL types for storing date and time values. Both can store values with second precision (MySQL 5.6.4+ supports fractional seconds). Choosing between them depends on several factors.
Timezone Information
DATETIMEstores the literal date‑time value without any timezone information. The exact value you insert is stored as‑is, so the application must handle any timezone conversion.
What problems can arise? If your application needs to support multiple timezones or the server/client timezone may change, using
DATETIMErequires manual conversion, which can lead to display or calculation errors.
TIMESTAMP and Timezones : When storing, MySQL converts the value from the current session timezone to UTC. When querying, it converts the stored UTC value back to the session timezone, allowing the same absolute point in time to be displayed differently across sessions.
Below is a practical demonstration.
Table creation SQL:
<code>CREATE TABLE `time_zone_test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`date_time` datetime DEFAULT NULL,
`time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;</code>Insert a row (assuming the session timezone is UTC+0):
<code>INSERT INTO time_zone_test(date_time, time_stamp) VALUES (NOW(), NOW());</code>Query the data in the same timezone session:
<code>SELECT date_time, time_stamp FROM time_zone_test;</code>Result:
<code>+---------------------+---------------------+
| date_time | time_stamp |
+---------------------+---------------------+
| 2020-01-11 09:53:32 | 2020-01-11 09:53:32 |
+---------------------+---------------------+</code>Now change the session timezone to UTC+8:
<code>SET time_zone = '+8:00';</code>Query again:
<code># TIMESTAMP value automatically converted to UTC+8
+---------------------+---------------------+
| date_time | time_stamp |
+---------------------+---------------------+
| 2020-01-11 09:53:32 | 2020-01-11 17:53:32 |
+---------------------+---------------------+</code>Extended: Common MySQL Timezone Commands
<code># Show current session timezone
SELECT @@session.time_zone;
# Set session timezone
SET time_zone = 'Europe/Helsinki';
SET time_zone = '+00:00';
# Show global timezone
SELECT @@global.time_zone;
# Set global timezone
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';</code>Is a Numeric Timestamp a Better Choice?
In practice, many developers store Unix timestamps using
INTor
BIGINT. This approach shares some advantages of
TIMESTAMP—fast sorting and comparison, easy cross‑system transfer—but sacrifices human readability.
Timestamp definition:
A timestamp counts seconds (or milliseconds) from the epoch "1970‑01‑01 00:00:00 +0:00". It is an absolute value, identical worldwide, and contains no timezone information, so no conversion is needed during transmission; conversion to a readable format occurs only when displaying to users.
Database operations:
<code>-- Convert a datetime string to a Unix timestamp (seconds)
SELECT UNIX_TIMESTAMP('2020-01-11 09:53:32');
-- Convert a Unix timestamp back to datetime
SELECT FROM_UNIXTIME(1578707612);</code>PostgreSQL Has No DATETIME
PostgreSQL uses different type names. The most comparable types are:
TIMESTAMP WITHOUT TIME ZONE– similar to MySQL
DATETIME, stores a literal value without timezone.
TIMESTAMP WITH TIME ZONE(or
TIMESTAMPTZ) – similar to MySQL
TIMESTAMP, stores UTC internally and converts based on session timezone.
For most applications that need an exact point in time,
TIMESTAMPTZis the recommended PostgreSQL choice because it handles timezone complexity robustly.
Summary
Which MySQL type should you use?
DATETIME– no timezone, larger range (up to year 9999), suitable when you control timezone logic yourself.
TIMESTAMP– built‑in timezone handling, stores UTC, ideal for multi‑timezone applications but limited to year 2038.
Numeric Unix timestamp – highest performance for comparisons and cross‑system transfer, but not human‑readable.
Selection Recommendations
Use
TIMESTAMPwhen you need automatic timezone conversion and can accept its range limit.
Use
DATETIMEwhen you need a broader date range or want full control over timezone handling.
Use a numeric timestamp when performance is critical and you can tolerate the loss of readability.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.