What is a Unix timestamp?
The Unix timestamp (Unix time, epoch time) counts the seconds since January 1, 1970, 00:00:00 UTC. It knows nothing about time zones or daylight saving time, which makes it well suited for storing and comparing points in time. It is only converted to local time for display. JavaScript, Java and many APIs work with milliseconds, so a 13-digit number instead of the usual 10 digits. The converter above detects this automatically.
The most important shell commands
| Command | Result |
|---|---|
date +%s | current timestamp in seconds |
date +%s%3N | current timestamp in milliseconds (GNU date) |
date -d @1798761600 | timestamp as a local date |
date -u -d @1798761600 +%FT%TZ | timestamp as ISO 8601 in UTC |
date -d "2027-01-01 01:00" +%s | date (local time) to timestamp |
date -d "3 days ago" +%s | timestamp from three days ago, handy for scripts |
date -r 1798761600 | macOS and BSD: timestamp as a date (there without -d @) |
In a crontab the percent sign has to be escaped: date +\%s. More on this in the Cron Generator.
Timestamps in logs
Some logs write raw timestamps, for example Squid, HAProxy statistics, Fail2ban databases or your own scripts. With GNU awk you can make them readable in one go:
awk '{ $1 = strftime("%F %T", $1); print }' access.logWith journalctl you can filter by timestamp directly: journalctl --since "@1798761600". For kernel messages with readable times there is dmesg -T, but the times shown there are inaccurate after a suspend.
MySQL and MariaDB: FROM_UNIXTIME and UNIX_TIMESTAMP
SELECT FROM_UNIXTIME(1798761600); -- timestamp to date
SELECT UNIX_TIMESTAMP('2027-01-01 00:00:00'); -- date to timestamp
SELECT * FROM wp_options WHERE option_name LIKE '_transient_timeout_%'
AND option_value < UNIX_TIMESTAMP(); -- expired transientsBoth functions use the time zone of the database session (SELECT @@session.time_zone;), not necessarily that of the server or the application. WordPress, for example, stores transient expiration times as timestamps, but posts as dates in local and UTC time (post_date and post_date_gmt).
The year 2038 problem
If the timestamp is stored as a signed 32-bit integer, it runs out on January 19, 2038 at 03:14:07 UTC (value 2147483647). One second later the number wraps around to negative, back to the year 1901. Current 64-bit systems are not affected, but these are:
- Columns of type
TIMESTAMPin MySQL, whose range ends on January 19, 2038. MariaDB extended the range to the year 2106 on 64-bit systems starting with version 11.5. For dates far in the future,DATETIMEis the safe type. - Columns of type
INTinstead ofBIGINTfor timestamps. - Old 32-bit systems, embedded devices and older PHP versions on 32-bit.
Expiration dates of licenses, certificates or long-term subscriptions can cross this limit already today. Test such fields with a date after 2038.