Milliseconds to date
Convert milliseconds to human readable date. Enter timestamp in milliseconds (e.g. 1704067200000).
Adding exactly 24 hours of milliseconds lands you at 13:00, not 12:00
A day is 86,400,000 milliseconds, except on the two days a year when it is not. Add that to noon on the spring transition and the clock reads 13:00; do it on the autumn one and it reads 11:00. The arithmetic is correct — a calendar day and 24 hours are simply different things twice a year.
How it works
- Converts millisecond timestamps to dates and back, in UTC and local time.
- Shows the unit breakdown, since millisecond values are hard to read at a glance.
- Flags the boundary where a Date stops being valid, which fails quietly rather than loudly.
1 second = 1,000 ms 1 hour = 3,600,000 ms 1 minute = 60,000 ms 1 day = 86,400,000 ms JavaScript Date range = ±8,640,000,000,000,000 ms → +275760-09-13 and −271821-04-20 one millisecond beyond → Invalid Date
Worked example
Adding one day of milliseconds across each daylight-saving transition, and the range boundary.
- start 28 March 2026, 12:00 — add 86,400,000 ms → 29 March, 13:00
- start 24 October 2026, 12:00 — add 86,400,000 ms → 25 October, 11:00
- 8,640,000,000,000,000 ms → +275760-09-13, the maximum
- one millisecond more → Invalid Date
- that Invalid Date is still an object, and getTime() returns NaN
Neither transition returns you to 12:00, because the calendar day was 23 or 25 hours long. And the range failure is worse than an exception: Invalid Date passes instanceof Date, so it flows onward and turns every later calculation into NaN.
Reading the result
- Use calendar arithmetic when you mean 'the same time tomorrow' and millisecond arithmetic when you mean '24 hours from now'. They agree on 363 days a year, which is exactly why the disagreement is so rarely caught in testing.
- Invalid Date is the dangerous failure mode because it is not an error. It is a Date object whose getTime() is NaN, and NaN propagates silently through every subsequent operation until something far downstream renders as blank or zero.
- The range limit is ±100,000,000 days from the epoch, which is generous enough that hitting it almost always means a bad multiplication rather than a genuine date — most often seconds passed where milliseconds were expected, inflating the value a thousandfold.
- Milliseconds fit comfortably inside the safe integer range, so unlike nanoseconds they can live in an ordinary number without losing digits. This is the practical reason most APIs settled on milliseconds rather than something finer.
Common questions
- Why is my date one hour out after adding a day?
- You crossed a daylight-saving transition. Adding 86,400,000 ms adds exactly 24 hours, but that calendar day had 23 or 25. If you wanted the same wall-clock time, add one day using calendar arithmetic rather than a fixed millisecond count.
- What does Invalid Date mean?
- The value fell outside ±8,640,000,000,000,000 ms or could not be parsed. It is not an exception — it is a Date object whose getTime() is NaN, so it keeps flowing through your code and quietly turns later arithmetic into NaN too.