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

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
MTIMEfield. 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
>>> 0converts 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.