esc
Developer Developer

Unix Timestamp 4294967295 and the Year 2106 Problem

By helpers.work 6 min read
Unix timestamp 4294967295 shown as 7 February 2106 06:28:15 UTC, the unsigned 32-bit limit, with local times in Los Angeles, New York, London and Tokyo

Unix timestamp 4294967295 is Sunday, 7 February 2106, 06:28:15 UTC. It is the largest number an unsigned 32-bit integer can hold, so it is the last second a 32-bit Unix clock can represent when it has no sign bit.

You will meet this value in two very different situations: as the theoretical Year 2106 problem, and, much more often, as a bogus date caused by reading -1 as an unsigned number.

Unix timestamp 4294967295 at a glance

Format Value
Unix seconds 4294967295 (2³² − 1)
Unix milliseconds 4294967295000
ISO 8601 (UTC) 2106-02-07T06:28:15Z
RFC 1123 Sun, 07 Feb 2106 06:28:15 GMT
Day of week (UTC) Sunday
Hex (32-bit) 0xFFFFFFFF

Try it in the Unix Timestamp Converter.

4294967295 in different time zones

Location Local date and time Offset
Los Angeles 2106-02-06 22:28:15 UTC−08:00
New York 2106-02-07 01:28:15 UTC−05:00
London 2106-02-07 06:28:15 UTC+00:00
Berlin 2106-02-07 07:28:15 UTC+01:00
Kolkata 2106-02-07 11:58:15 UTC+05:30
Tokyo 2106-02-07 15:28:15 UTC+09:00
Sydney 2106-02-07 17:28:15 UTC+11:00

These are projections using today's time-zone rules. Eighty years is plenty of time for countries to change their daylight saving policies, so only the UTC value is certain.

Signed vs unsigned 32-bit time

Unix time range by integer type: signed 32-bit from 1901 to 2038, unsigned 32-bit from 1970 to 2106, and signed 64-bit covering about 292 billion years in each direction

A 32-bit integer has 2³² possible values. How they map to dates depends on whether the type is signed:

Type Minimum Maximum Date range (UTC)
Signed 32-bit -2147483648 2147483647 1901-12-13 → 2038-01-19
Unsigned 32-bit 0 4294967295 1970-01-01 → 2106-02-07
Signed 64-bit about −9.2 × 10¹⁸ about 9.2 × 10¹⁸ ≈ 292 billion years each way

Both 32-bit types cover the same span of about 136 years. The unsigned variant simply shifts the window: it gives up everything before 1970 and gains 68 extra years after 2038. When the counter passes 4294967295, it wraps to 0, and the date jumps back to the Unix epoch.

Is unsigned 32-bit a fix for 2038?

Reinterpreting an existing 32-bit field as unsigned is a tempting, cheap fix for the Year 2038 problem. It keeps the storage size and the binary layout, and it works for every date from 1970 onward.

It has real costs, though:

  • No dates before 1970. Birth dates, historical records and anything using negative timestamps can no longer be represented.
  • Broken differences. Subtracting two unsigned timestamps where the second is later produces a huge positive number instead of a negative duration.
  • Mixed interpretations. If one component reads the field as signed and another as unsigned, dates after 2038 appear correctly in one place and as 1901 in another.

For formats you can change, a signed 64-bit integer is the durable fix. Unsigned 32-bit is best treated as a compatibility measure for formats you cannot change.

Where unsigned 32-bit time appears

  • File formats. Some binary formats store a modification time as a 4-byte Unix seconds field. The gzip header, for example, has a 4-byte MTIME field. Readers that decode such fields as unsigned will handle dates up to 2106.
  • Embedded firmware. Microcontroller code often keeps time in a uint32_t, trading pre-1970 support for a longer future range.
  • Network protocols. NTP uses an unsigned 32-bit seconds counter too, but counts from 1900, so its first era ends on 2036-02-07 06:28:16 UTC. The date and time of day match 2106 almost exactly because 1900 to 1970 is a whole number of days.
  • JavaScript. The unsigned right shift operator >>> 0 converts values to unsigned 32-bit.

Why a date shows 7 February 2106

In practice, a 2106 date in your application is almost never a real future date. The usual cause is -1 read as unsigned.

Many APIs and C functions use -1 to mean "unknown" or "error". For example, time() and mktime() in C return (time_t)-1 on failure. The bit pattern of -1 in 32 bits is 0xFFFFFFFF, which is 4294967295 when read as unsigned:

const unknown = -1

new Date(unknown * 1000).toISOString() // "1969-12-31T23:59:59.000Z"
new Date((unknown >>> 0) * 1000).toISOString() // "2106-02-07T06:28:15.000Z"

The same happens when a signed value is written to a binary field and read back with an unsigned reader, for example readUInt32LE() instead of readInt32LE() in Node.js:

const buf = Buffer.alloc(4)
buf.writeInt32LE(-1)

buf.readInt32LE(0) // -1
buf.readUInt32LE(0) // 4294967295

If you see 2106-02-07 06:28:15 UTC or 1969-12-31 23:59:59 UTC, look for a -1 sentinel. Handle it explicitly before converting, just as you should handle a zero that means "no date".

Converting 4294967295 in code

JavaScript

new Date(4294967295 * 1000).toISOString() // "2106-02-07T06:28:15.000Z"

Python

from datetime import datetime, timezone

datetime.fromtimestamp(4_294_967_295, tz=timezone.utc).isoformat()
# '2106-02-07T06:28:15+00:00'

Shell

date -u -d @4294967295     # GNU/Linux
date -u -r 4294967295      # macOS / BSD

PostgreSQL

SELECT to_timestamp(4294967295) AT TIME ZONE 'UTC';
-- 2106-02-07 06:28:15

Note that this value does not fit in a signed 32-bit INT column. Store Unix seconds in BIGINT.

Summary

Unix timestamp 4294967295 is 2106-02-07 06:28:15 UTC, the unsigned 32-bit limit. Unsigned 32-bit time trades pre-1970 dates for 68 extra years after 2038, which makes it a stopgap, not a fix. In everyday debugging, a 2106 date usually means -1 was read as unsigned.

Inspect suspicious values in the Unix Timestamp Converter, and compare the signed limits in 2147483647 and the Year 2038 problem and -2147483648 and the 1901 limit.

FAQ

Frequently asked questions

What date is Unix timestamp 4294967295?

Unix timestamp 4294967295 is Sunday, 7 February 2106 at 06:28:15 UTC. It is the largest value an unsigned 32-bit integer can hold.

What is the Year 2106 problem?

Systems that store Unix time in an unsigned 32-bit integer can count only up to 4294967295. One second later, the value wraps to 0, which is 1 January 1970.

Why does my app show 7 February 2106?

A value of -1 was almost certainly read as an unsigned 32-bit number. Many APIs use -1 to mean "no value", and reinterpreting it as unsigned gives 4294967295, which is 2106-02-07 06:28:15 UTC.

Is switching to unsigned 32-bit a fix for 2038?

It postpones the overflow to 2106, but it removes all dates before 1970 and breaks code that relies on negative differences. Moving to a signed 64-bit type is the long-term fix.

Try it yourself

Related tools

All tools

More guides in the helpers.work blog

Practical, no-nonsense guides on DNS, email, networking and security — plus 68 free tools to go with them.

Read the blog Browse all tools