Unix Timestamp Converter
Unix timestamps to dates and back, in any time zone, down to nanoseconds
Right now
Also reads 0x hex, 0o octal and 0b binary.
An offset written into the text, Z or +02:00, always wins over this setting.
Converted
Zone is this device, currentlyUTC.
As an integer
Counted from elsewhere
Where it falls
Convert a whole column
Values are read with the unit and zone set above. Lines that are already dates convert the other way, so a mixed column still comes out matched line for line.
A Unix timestamp is one integer: seconds elapsed since midnight UTC on 1 January 1970. No time zone, no separators, no argument about which end the year goes on. That is the entire appeal, and it is why anything handing a time to anything else tends to hand over one of these.
0 1970-01-01 00:00:00 UTC
86400 1970-01-02 00:00:00 UTC
1000000000 2001-09-09 01:46:40 UTC
1786752000 2026-08-15 00:00:00 UTC
2147483647 2038-01-19 03:14:07 UTC
-86400 1969-12-31 00:00:00 UTCNegative values work and mean before 1970. There is nothing special about the epoch beyond it having been a convenient round date when Unix was written.
Telling seconds from milliseconds
A lot of software stores milliseconds instead, because milliseconds are what Date.now() and System.currentTimeMillis() hand back. Go and Rust reach for nanoseconds, Postgres and Python for microseconds. A bare integer does not say which it is, and reading one as another moves you by a factor of a thousand or a billion. Counting the digits settles it for any date you are realistically going to be given.
10 digits seconds 1786752000 Aug 2026
13 digits milliseconds 1786752000000 Aug 2026
16 digits microseconds 1786752000000000 Aug 2026
19 digits nanoseconds 1786752000000000000 Aug 2026The same gap repeats every three orders of magnitude, and that gap is what makes detection safe instead of a guess. The boundary between seconds and milliseconds is 1011: read as seconds that is the year 5138, and read as milliseconds it is March 1973. Nothing real lands in between, and the boundaries between the other units work the same way.
Nanoseconds do not survive a JavaScript number
A double holds integers exactly up to 253, which is 9,007,199,254,740,992. A nanosecond timestamp for today is around 1.79 × 1018, roughly two hundred times past that, where the gap between one representable number and the next has widened to 256. Put a nanosecond timestamp through a float and the last few digits are whatever happened to be nearest, and it will look entirely plausible while being wrong.
Everything on this page is carried as an exact integer of nanoseconds and only converted to a date at the last moment, so the nanosecond readout is the value you gave it, digit for digit.
Dates that move when you add a time to them
new Date('2026-08-14') midnight UTC
new Date('2026-08-14T00:00') midnight localSame parser, same date, different instant, and the only thing that changed is whether a time was present. The specification really does say this. In London in August those two are an hour apart; in Auckland they are twelve, which is enough to land on a different day and produce a bug report nobody can reproduce.
This tool does not use that parser. It pulls the fields out of what you typed and applies the zone sitting right next to the box, so nothing moves without you seeing it. A trailing Z or an explicit offset like +02:00 wins over the picker, because at that point the string already says what it means.
An offset is not a time zone
+01:00 tells you what the clock read. Europe/London tells you which clock. Only one of the two can answer what the offset will be next March. A zone is a rulebook with a history in it: the UK ran on UTC+1 all year in 1968 through 1971, and Samoa skipped 30 December 2011 entirely when it moved across the date line.
Picking a named zone here uses the browser's own copy of that database, which is why converting into America/New_York gives you EST in January and EDT in July without being told. On the day the clocks go back, one local hour happens twice; this tool resolves it to the first occurrence, which is what almost every library does.
Everyone else counts from somewhere else
| Format | Counts | From |
|---|---|---|
| Unix | Seconds | 1970-01-01 |
| NTP | Seconds | 1900-01-01 |
| Windows FILETIME | 100 ns | 1601-01-01 |
| .NET ticks | 100 ns | 0001-01-01 |
| Apple absolute | Seconds | 2001-01-01 |
| Excel serial | Days | 1899-12-30 |
The constants worth remembering are 11,644,473,600 seconds between 1601 and 1970 turns a FILETIME into a Unix timestamp, and 2,208,988,800 between 1900 and 1970 for NTP. NTP's seconds field is 32 bits, so it runs out on 7 February 2036, two years ahead of the more famous deadline.
The Excel origin looks wrong. It is not a typo. Excel believes 1900 was a leap year, because Lotus 1-2-3 did and compatibility mattered more in 1985 than correctness. Serial 60 is 29 February 1900, a day that never happened, and shifting the origin back to 30 December 1899 is what makes every date after that come out right anyway. Dates before 1 March 1900 are off by one and always will be.
Reading it in hex, and what 32 bits costs
1786752000 is 0x6A7FAC00. Seeing a timestamp in hex is mostly a matter of recognising one in a memory dump or a packet: a 32-bit field starting 0x6 is a date between January 2021 and July 2029, which is a good enough tell to go on.
32-bit signed -2147483648 to 2147483647 1901-12-13 to 2038-01-19
32-bit unsigned 0 to 4294967295 1970-01-01 to 2106-02-07
64-bit signed ... past the life of the sun2147483647 is the largest signed 32-bit integer. One second later a 32-bit time_t rolls over to negative and the date comes out as December 1901. Anything still keeping time in 32 bits has that deadline: older embedded firmware, a handful of file formats, and more legacy C than anyone enjoys admitting.
Leap seconds are not in the count
Unix time defines every day as exactly 86,400 seconds. The Earth declines to cooperate, so when a leap second is inserted the count repeats or stretches one to stay aligned with days. Twenty seven have gone in since 1972.
What that costs you: subtracting two timestamps does not give you elapsed seconds if a leap second fell between them. For a row in a database this never matters. For anything measuring a duration across years it does, and TAI is what you actually want.
ISO weeks belong to the year holding their Thursday
Week 1 of an ISO year is the week containing the first Thursday of January, which means the last days of December can sit in week 1 of the following year and the first days of January can sit in week 52 or 53 of the previous one. 1 January 2027 is a Friday, so it falls in week 53 of 2026.
This is why a weekly report keyed on the calendar year and the ISO week number loses or duplicates a week roughly every seven years. The ISO week readout here carries its own year for exactly that reason.
Rounding, and dates that do not exist
The seconds readout truncates instead of rounding, matching what date +%s and Postgres EXTRACT(EPOCH ...) both do. Timestamp 1.999 is second 1.
Invalid calendar dates get rejected here instead of rolled forward. 2026-02-30 reports an error, where most date constructors quietly hand you 2 March and let you find out later.