Unix Timestamp Converter

Current Unix Timestamp

0

What Unix Time Actually Counts (Seconds, Milliseconds, Nanoseconds)

Unix time is a single integer: the count of seconds since the epoch, 1970-01-01T00:00:00Z. The date itself is arbitrary — early Unix at Bell Labs needed a zero point that fit in a 32-bit value at reasonable resolution, and the start of 1970 was a convenient recent round number. Negative values are perfectly legal and denote instants before 1970; -86400 is the last day of 1969. Because the count is anchored to UTC, two machines in Seoul and São Paulo generating a timestamp at the same instant produce the same number: the timestamp identifies a moment, never a wall-clock reading. The classic bug family here is unit confusion, because ecosystems disagree on resolution. POSIX time(), most databases, and JWT claims use seconds; JavaScript's Date.now() and Java's System.currentTimeMillis() return milliseconds; many APIs and databases use microseconds; Go's UnixNano and much of the observability world use nanoseconds. Mix them up and dates land in 1970 (treated ms as s, dividing away almost everything) or in the year 56,000+ (treated s as ms). Digit count is the fastest diagnostic for current-era values: 10 digits are seconds (1751414400 is July 2025... in seconds), 13 are milliseconds, 16 microseconds, 19 nanoseconds. A related trap is float precision: passing timestamps through JSON as floating point works for seconds but corrupts nanosecond values, since a 64-bit double has only 53 bits of integer precision — one reason high-resolution APIs pass timestamps as strings.
Same instant, four resolutions:
1751414400            seconds       (10 digits)
1751414400000         milliseconds  (13 digits)  Date.now()
1751414400000000      microseconds  (16 digits)
1751414400000000000   nanoseconds   (19 digits)  Go UnixNano

// The two classic unit bugs (JavaScript):
new Date(1751414400)        // 1970-01-21 — seconds fed as ms
new Date(1751414400 * 1000) // 2025-07-02 — correct

Leap Seconds: The Lie Inside Every Timestamp

Unix time claims to count seconds since 1970, but that is not literally true. Earth's rotation is irregular, so UTC occasionally inserts a leap second (27 of them since 1972) to stay aligned with astronomical time. Unix time simply pretends these do not exist: every day is exactly 86,400 seconds by definition. During an inserted leap second, the clock reads 23:59:60 in UTC, but the Unix counter cannot express that instant — implementations either repeat a second or freeze, meaning two different real-world instants can share one timestamp, and an interval measured across a leap second is off by one. This is not academic. The June 2012 leap second crashed Linux systems industry-wide via a livelock in the kernel's timer code, taking down airline reservation systems among others; the end-of-2016 leap second caused a production incident at Cloudflare, where code subtracted timestamps and got a negative duration it could not handle. The lesson generalizes: never assume that wall-clock timestamps taken later are larger. For measuring durations, use a monotonic clock (performance.now() in JS, CLOCK_MONOTONIC in POSIX, time.monotonic() in Python), which is immune to leap seconds, NTP steps, and manual clock changes. Large operators route around the problem with leap smearing — Google and AWS stretch each second slightly across a 24-hour window so the leap second disappears into microscopic slowdown. And the endgame is retirement: the 2022 General Conference on Weights and Measures resolved to stop inserting leap seconds by 2035. Until then, timestamps remain an excellent identifier of moments and a subtly unreliable ruler for durations.

The Year 2038 Problem Is Already Here

A signed 32-bit integer tops out at 2,147,483,647. As a Unix timestamp that is 2038-01-19T03:14:07Z; one second later, the value wraps negative and a vulnerable system suddenly believes it is 1901-12-13. Twelve years out, this sounds like tomorrow's problem — but any code that computes future dates crosses the boundary decades early. A 20-year mortgage schedule crossed it in 2018; 15-year certificate expiries and long TTLs cross it today. Systems have already produced real 2038 bugs years before the date itself. The fix — 64-bit time_t — has been standard on new platforms for years, and a 64-bit second counter is safe for about 292 billion years. The residue lives at the edges: embedded and IoT devices with 32-bit ABIs that will still be running in 2038, old file formats and network protocols with 32-bit time fields, and databases. MySQL's TIMESTAMP column type is the famous survivor: it stores 32-bit epoch seconds and historically cannot represent times after 2038-01-19 (use DATETIME, which has no such limit). The Linux kernel added 64-bit time syscalls for 32-bit architectures in version 5.6 (2020), and glibc followed with a _TIME_BITS=64 build option; ext4 extended its timestamps to 2446 and XFS to 2486. Two adjacent overflows are worth knowing. Systems that "fixed" 2038 by reinterpreting the same 32 bits as unsigned bought time until 2106-02-07 — a deferral, not a solution. And the millisecond world has its own cliff: 32-bit millisecond counters (common in embedded uptime clocks) wrap every 49.7 days, a bug pattern famous from Windows 95 and, later, a Boeing 787 generator-control directive requiring reboots.
2^31 - 1 = 2147483647  →  2038-01-19T03:14:07Z  (signed 32-bit)
+1 second              →  -2147483648  =  1901-12-13T20:45:52Z

2^32 - 1 = 4294967295  →  2106-02-07T06:28:15Z  (unsigned 32-bit)
2^63 - 1 (64-bit)      →  ~292 billion years    (safe)

-- MySQL: TIMESTAMP is 32-bit, DATETIME is not
CREATE TABLE t (
  ts TIMESTAMP,   -- max 2038-01-19 03:14:07 UTC
  dt DATETIME     -- max 9999-12-31 23:59:59
);

Timezones and DST: Where Timestamp Bugs Are Born

A Unix timestamp is an absolute instant; a timezone is a presentation rule. Keeping those two roles separate is the single most effective defense against date bugs: store and transmit UTC timestamps, and convert to local time only at the display edge. The moment a "timestamp" has silently passed through a local-time interpretation — a naive datetime in Python, a DATETIME column filled with server-local time, a datetime-local form input — the same value means different instants on different machines. Daylight saving time is why local time is treacherous even within one timezone. When clocks spring forward, an hour of local time simply does not exist (in US Eastern, 2:30 AM on the March switch date is invalid); when they fall back, an hour occurs twice, and "1:30 AM" is ambiguous without knowing which pass it was. Scheduling code hits both cases: a daily 02:30 job misfires or double-fires twice a year, and naive "add 24 hours" arithmetic drifts on transition days, because those days are 23 or 25 hours long. Two more rules keep you out of trouble. First, an offset is not a timezone: +09:00 tells you how to render one instant, but only an IANA zone name like Asia/Seoul or America/Sao_Paulo carries the full DST and political history — and that history changes, which is why the tzdata package updates several times a year (Brazil abolished DST in 2019; Egypt reinstated it in 2023). Second, know your language's parsing quirks: in JavaScript, new Date('2026-07-02') is parsed as UTC midnight while new Date('2026-07-02T00:00') is parsed as local time — a one-character difference that produces the classic off-by-one-day bug for any user east or west of Greenwich.
// JavaScript parsing quirk (machine in UTC+9):
new Date('2026-07-02')        // date-only → parsed as UTC
  .toString()                 // Thu Jul 02 2026 09:00 GMT+0900
new Date('2026-07-02T00:00')  // date-time → parsed as LOCAL
  .toString()                 // Thu Jul 02 2026 00:00 GMT+0900

// Same string minus one 'T00:00' = 9 hours apart.

// DST gap: 2:30 AM does not exist on spring-forward day
// America/New_York, 2026-03-08: 01:59:59 → 03:00:00

ISO 8601 and RFC 3339: Timestamps for Humans and Sorters

When a timestamp must be readable, the answer is the ISO 8601 family: 2026-07-02T09:30:00+09:00. In practice what APIs implement is RFC 3339, a deliberately small profile of ISO 8601 for internet use. The full ISO standard permits things you never see in APIs — week dates like 2026-W27-4, ordinal dates like 2026-183, truncated forms, basic format without dashes. RFC 3339 cuts all of that: full year-month-day, the T separator, and a mandatory UTC offset, with Z as shorthand for +00:00. If you are designing an API, "RFC 3339 with Z" is the highest-interoperability choice; JavaScript's toISOString() and Python's datetime.isoformat() both emit conformant output. The killer feature of the format is that lexicographic order equals chronological order — but only when every value uses the same offset and the same field width. Sorting mixed-offset strings alphabetically is wrong (a +09:00 morning sorts after a Z-suffixed afternoon it precedes), which is one more argument for normalizing everything to Z. This sortability is why log files, S3 object keys, and backup names conventionally start with a UTC ISO timestamp. Details that bite: RFC 3339 allows -00:00 (historically used to mean "offset unknown", unlike +00:00 which asserts UTC); fractional seconds are optional and variable-width, so parsers must accept .5, .500, and .500000; and the date-only string 2026-07-02 is not a timestamp at all — as the previous section showed, different parsers attach different midnights to it. When exchanging instants between systems, send either an integer epoch value or a full RFC 3339 string with explicit offset; anything less specific is an invitation for two systems to disagree.
Last updated:

About this tool

A Unix timestamp converter translates between integer seconds since 1970-01-01 UTC (the Unix epoch) and human-readable date/time formats. Timestamps appear everywhere in code — JWT iat/exp claims, database created_at columns, log lines, file mtimes — and a quick converter saves you from doing the math in your head every time.

How to use

  1. Read the live "now" timestamp at the top of the page.
  2. Type a Unix timestamp into the input — the human date below updates instantly.
  3. Or pick a date with the picker — the Unix value updates instantly.
  4. Click Now to grab the current timestamp.
  5. Copy whichever representation you need into your code, log query, or test fixture.

Common use cases

  • Converting a Stripe charge’s created field into a human date.
  • Decoding the iat / exp claim of a JWT to debug expiration issues.
  • Translating a log file timestamp into your local time zone.
  • Producing a Unix timestamp for an "expires in N seconds" cache entry.
  • Filling out a database test fixture with a known date.
  • Sanity-checking that a server clock matches the expected epoch.

Frequently asked questions

Q. Are timestamps in seconds or milliseconds?

A. Both are common. Unix tools and most databases use seconds; JavaScript Date.now() returns milliseconds. A 13-digit number is almost always milliseconds; 10 digits is seconds.

Q. What about time zones?

A. Unix timestamps are always UTC by definition. Display formatting is what introduces local time — store UTC, show local.

Q. Will Unix timestamps overflow in 2038?

A. Signed 32-bit timestamps overflow on 2038-01-19. Modern systems use 64-bit timestamps and are safe for billions of years.

Q. Why do JWT exp values look strange?

A. They are seconds since the epoch. iat is when the token was issued; exp is when it expires. Both are in UTC.