Skip to content
Browse tools

Time guide ยท Unix timestamps

One number.
One moment.
Every time zone.

A Unix timestamp is the number of seconds that have passed since midnight UTC on 1 January 1970. It's how databases, logs, JWTs, APIs and operating systems record "when" without arguing about time zones or date formats. Here's how to read one, spot the seconds-vs-milliseconds trap, and convert it in any language. ๐Ÿ‘‡

โ–ธ the same instant, three ways
1718352000                  โ† Unix seconds
1718352000000               โ† Unix milliseconds
2024-06-14T08:00:00Z        โ† ISO 8601, UTC  (13:30 in India, 04:00 in New York)
๐Ÿงญ

Also called: epoch time, POSIX time, Unix time, or just "epoch". The starting point โ€” 1970-01-01T00:00:00Z โ€” is the Unix epoch, and it's timestamp 0. Moments before it are negative numbers.

02 ยท Exactly what it counts

โฑ๏ธ The definition, precisely

Unix time counts seconds since 1970-01-01 00:00:00 UTC, with one important simplification: every day is treated as exactly 86,400 seconds. Leap seconds โ€” the occasional extra second added to UTC to keep it aligned with the Earth's rotation โ€” are simply not counted.

โœ… What that buys you

Date arithmetic is trivial. Midnight UTC on any day is a multiple of 86,400. "One day later" is + 86400. Converting to a calendar date needs no leap-second table.

๐Ÿค What it costs

Unix time isn't a perfect count of elapsed physical seconds. Around a leap second, systems either repeat a second or "smear" it across several hours. For almost all application code, this never matters.

๐Ÿ“Œ Handy reference points

TimestampUTC date & timeWhy it's notable
01970-01-01 00:00:00The epoch
864001970-01-02 00:00:00Exactly one day
10000000002001-09-09 01:46:40First 10-digit timestamp
17672256002026-01-01 00:00:00Start of 2026
21474836472038-01-19 03:14:07Largest signed 32-bit value โ€” see the 2038 problem
99999999992286-11-20 17:46:39Last 10-digit timestamp

03 ยท The most common bug

๐Ÿ”ข Seconds vs milliseconds

Classic Unix tools, C, PHP, Python's time.time(), most SQL functions and JWT claims like exp use seconds. JavaScript's Date, Java's System.currentTimeMillis() and many logging and analytics systems use milliseconds. Mix them up and you get dates in January 1970 or tens of thousands of years in the future.

Digits (for present-day dates)UnitExample
10Seconds1718352000
13Milliseconds1718352000000
16Microseconds1718352000000000
19Nanoseconds1718352000000000000
๐Ÿ•ต๏ธ

The quick test: count the digits. Ten digits is seconds for any date between September 2001 and November 2286; thirteen is milliseconds over the same span. The rule breaks down for dates near 1970, where timestamps are short โ€” so when a value comes from an unfamiliar API, check the docs rather than guessing.

๐Ÿ›

The symptom to recognise: a date showing as 20 January 1970 almost always means seconds were treated as milliseconds (1.7 billion ms is about 20 days). A year in the tens of thousands means the reverse.

04 ยท Where local time fits in

๐ŸŒ Time zones & ISO 8601

A Unix timestamp has no time zone. It identifies a single instant that is the same everywhere on Earth. Time zones only appear when you display that instant: 1718352000 is 08:00 UTC โ€” which is 09:00 in London (British Summer Time), 13:30 in India (UTC+05:30) and 04:00 in New York (UTCโˆ’04:00 in June).

  1. ๐Ÿ’พ Store the instant

    Save timestamps in UTC โ€” as a Unix number or a UTC date-time column. Never store "local time" without its offset.

  2. ๐Ÿ” Compute in UTC

    Durations, comparisons and sorting all work directly on the number. Daylight-saving changes can't break them.

  3. ๐Ÿ–ฅ๏ธ Convert at the edge

    Turn it into local time only when showing it to a person, using their time zone.

๐Ÿ†š Unix timestamp or ISO 8601?

ISO 8601 (and its stricter internet profile, RFC 3339) is the standard text format for dates: 2024-06-14T08:00:00Z, or with an offset, 2024-06-14T13:30:00+05:30. Both lines describe the same moment as 1718352000.

WhatUnix timestampISO 8601 string
Readable by humansNoYes
SizeCompact number~20โ€“30 characters
Carries an offsetNo โ€” always UTC by definitionYes (Z or +05:30)
Unit ambiguitySeconds or milliseconds?None โ€” precision is visible
Sorting & mathsPlain number comparisonSorts as text only if all values use the same offset and format
Typical useDatabases, JWTs, logs, cachesJSON APIs, config, anything a person reads

A common, sensible split: use ISO 8601 with Z in public JSON APIs (see What is JSON?) and Unix numbers internally, where compactness and arithmetic matter.

05 ยท A deadline with a date

๐Ÿ’ฅ The Year 2038 problem

Many older systems store Unix time in a signed 32-bit integer. The largest value that type can hold is 2147483647 โ€” which is 2038-01-19 03:14:07 UTC. One second later, the value overflows and wraps round to -2147483648, which those systems read as 1901-12-13 20:45:52 UTC.

Signed 32-bit
64-bit
32-bitRuns out on 19 January 2038 and jumps back to 1901.
64-bitLasts roughly 292 billion years in either direction.

Modern 64-bit operating systems, languages and databases already use 64-bit time, so most application code is fine. The risk sits in the places people forget:

  • Embedded devices and firmware with 32-bit clocks that will still be in service in 2038.
  • Database columns โ€” MySQL's TIMESTAMP type, for example, has a range that ends at 2038-01-19 03:14:07 UTC. DATETIME or a 64-bit integer column avoids it.
  • File formats and protocols that define a 32-bit time field.
  • Your own code that casts a timestamp to a 32-bit int. Use long / int64.
๐Ÿ“…

It can bite before 2038. Anything that calculates dates in the future โ€” a 20-year mortgage schedule, a long-lived certificate, a far-off expiry date โ€” crosses the limit today.

06 ยท In your code

๐Ÿ› ๏ธ Getting & converting timestamps

โ–ธ JavaScript
Date.now();                                  // milliseconds: 1718352000000
Math.floor(Date.now() / 1000);               // seconds:      1718352000

new Date(1718352000 * 1000).toISOString();   // "2024-06-14T08:00:00.000Z"
Date.parse("2024-06-14T08:00:00Z") / 1000;    // 1718352000
โ–ธ C# / .NET
long secs = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long ms   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

DateTimeOffset when = DateTimeOffset.FromUnixTimeSeconds(1718352000);
// 2024-06-14 08:00:00 +00:00

var ist = TimeZoneInfo.FindSystemTimeZoneById("Asia/Kolkata");
DateTimeOffset local = TimeZoneInfo.ConvertTime(when, ist);   // 13:30 +05:30
โ–ธ Python
import time
from datetime import datetime, timezone

int(time.time())                                        # seconds, now
datetime.fromtimestamp(1718352000, tz=timezone.utc)     # 2024-06-14 08:00:00+00:00
datetime(2024, 6, 14, 8, tzinfo=timezone.utc).timestamp()   # 1718352000.0

# โš ๏ธ a naive datetime (no tzinfo) is treated as *local* time by .timestamp()
โ–ธ SQL
-- PostgreSQL
SELECT extract(epoch FROM now());            -- now, as seconds
SELECT to_timestamp(1718352000);             -- โ†’ timestamptz

-- MySQL
SELECT UNIX_TIMESTAMP();
SELECT FROM_UNIXTIME(1718352000);            -- shown in the session time zone

-- SQL Server
SELECT DATEDIFF_BIG(SECOND, '1970-01-01', SYSUTCDATETIME());
SELECT DATEADD(SECOND, 1718352000, '1970-01-01');

-- SQLite
SELECT strftime('%s', 'now');
SELECT datetime(1718352000, 'unixepoch');
โ–ธ bash
date +%s                            # seconds, now
date +%s%3N                         # milliseconds (GNU date)

date -u -d @1718352000                # โ†’ date, GNU/Linux
date -u -r 1718352000               # โ†’ date, macOS/BSD
date -u -d "2024-06-14T08:00:00Z" +%s   # date โ†’ seconds (GNU)
โšก

Just need the answer? Paste any value into the Timestamp Converter โ€” it detects seconds vs milliseconds and shows UTC, local time and ISO 8601 together. To count days or hours between two dates, use the Date Difference Calculator.

๐Ÿ“Œ Unix time as defined by POSIX: seconds since 1970-01-01T00:00:00Z, excluding leap seconds. Example values on this page were checked with GNU date.

What is a Unix timestamp?
7 min read