Time Utilities

Timestamp Converter

Convert Unix timestamps to date time and back.

Current time
---Milliseconds
---Seconds

Timestamp → Date & time

Date & time → Timestamp

What is Timestamp Converter?

Timestamp converter transforms between Unix timestamps (seconds/milliseconds since 1970-01-01) and human-readable date/time formats. Essential for debugging, logging, and cross-system time synchronization.

Features

  • Live Clock: Shows current timestamp in real-time
  • Two-way Conversion: Timestamp ↔ Date/Time
  • Multiple Formats: Local time, ISO 8601, UTC
  • Relative Time: Shows time difference from now

Use Cases

  • API Development: Parse and generate timestamps
  • Debugging: Convert log timestamps to readable dates
  • Database Queries: Work with time-based data
  • Scheduling: Calculate future dates and durations

Unix time counts seconds from 1970-01-01T00:00:00Z. This tool turns a second or millisecond timestamp into local time, ISO 8601, RFC 7231 UTC and relative text, and converts a datetime-local reading back into seconds and milliseconds. Use it when reading log lines, API payloads or database rows that store time as a bare number.

Ten digits or thirteen: the unit is a switch, not a guess

The unit is set by a manual toggle that defaults to milliseconds, which multiplies the input by 1000 only when you pick seconds. The same digits 1700000000 resolve to 1970-01-20T16:13:20Z on the millisecond setting and to 2023-11-14T22:13:20Z on the second setting. Input passes through parseInt(value, 10), which reads digits only up to the first non-digit character: a pasted ISO date such as 2023-11-14 collapses to 2023, i.e. 00:33:43 on 1970-01-01, a decimal fraction is truncated instead of rejected, and scientific notation keeps only its mantissa (1.7e12 becomes 1). No error is raised in any of those cases, so confirm the leading digits against a plausible year before trusting a result that sits in January 1970.

Why the four result rows disagree

All four rows describe one instant, but at different precision and under different conventions. toISOString() always renders UTC with a Z suffix and exactly three fractional digits, so 123 ms survives as .123Z. toUTCString() emits the HTTP-date form of RFC 7231 ending in GMT, with no fractional seconds, so those same 123 ms vanish from that row. The local row uses a fixed zh-CN pattern, YYYY/MM/DD HH:mm:ss in 24-hour form, independent of the interface language, so an English page still shows slashes and no AM/PM, and the reading shifts with your system zone. The relative row keeps only the largest non-zero unit and never rolls up to months or years: 400 days prints as a day count.

The reverse direction is anchored in local time

A datetime-local field carries no offset, and ECMAScript parses an offset-less date-time string as local time, so a typed 22:13:20 means that wall clock in the browser zone; on a UTC+8 machine the seconds output is 8 hours earlier than the same digits read as UTC. Seconds come from Math.floor(getTime() / 1000), rounding any remainder toward negative infinity, so -500 ms yields -1 rather than 0. The field has a one-second step, so the millisecond row is always a multiple of 1000. When a moment has to cross zones, keep the ISO string with its offset and convert that instead of re-typing the clock reading at the other end.

Worked example

Reading a log line that carries milliseconds

Input
1700000000123
Output
2023-11-14T22:13:20.123Z

Left on the default millisecond unit, the 13 digits give the ISO row above. The UTC row prints the same instant as Tue, 14 Nov 2023 22:13:20 GMT, losing the .123, and the seconds row shows 1700000000 because the division by 1000 is floored.

Limits and pitfalls

  • The unit is never inferred from digit count: a 10-digit value left on the millisecond toggle resolves to January 1970 instead of your date.
  • Only seconds and milliseconds are accepted. Microsecond (16-digit) values land around year 55840, and nanosecond (19-digit) values fall outside the Date range and return an invalid-timestamp error.
  • The relative row is recomputed only when the input changes, not on the once-per-second clock tick, so a page left open keeps an increasingly stale "ago" figure.
  • The local row is locked to a zh-CN pattern in the browser time zone; there is no control for another offset or format.
  • Inputs beyond the ECMAScript Date range of plus or minus 8.64e15 milliseconds error out instead of clamping to the boundary.

Related tools

When one instant is the whole answer, and when this shape is the wrong one

What you are holdingWhat this page does with itWhere it belongs instead
One count lifted out of a log line or an API responsePaste it, choose seconds or milliseconds, and four rows appear together: the browser clock face, ISO with three decimals, RFC 9110 GMT and a relative phrase. There is a single input box, so a second value replaces the first instead of joining it.A CSV column of 50,000 epochs cannot go through a one-value box: gawk -F, '{print strftime("%FT%TZ", $3, 1)}' walks the whole file, and pandas.to_datetime(col, unit="s") states the unit once and converts every row. Come back here when you are checking rows one at a time.
The result has to be pasted into an HTTP date headerThe UTC row already is the IMF-fixdate of RFC 9110 — Tue, 14 Nov 2023 22:13:20 GMT, 29 characters, seconds truncated to whole — but it is the one result row with no copy button, so the text is selected by hand.Generate the header rather than retyping it: date -u -d @1700000000 "+%a, %d %b %Y %H:%M:%S GMT" under GNU coreutils, date -u -r 1700000000 "+%a, %d %b %Y %H:%M:%S GMT" on macOS, or email.utils.formatdate(1700000000, usegmt=True) in Python. Each emits English day and month names with no fractional seconds.
The input is an ISO string that carries an offset, such as 2023-11-14T22:13:20+09:00The reverse panel is a datetime-local field, whose value format has no room for an offset, and the forward panel runs the same string through parseInt, keeping only 2023.The ISO 8601 parser passes the text to new Date() unchanged and returns both the millisecond count and the floored second count, so +09:00 decides the instant. Strings with a zone suffix go there; bare digit counts come here.
The clock face must be in a named zone, not the one the reading machine reportsNothing on the panel names a zone. The same digits read 2023/11/15 06:13:20 on a UTC+8 laptop and 2023/11/14 22:13:20 on a UTC one, while the ISO row comes out byte-identical on both.The timezone converter takes an explicit from and to pair (UTC, Asia/Shanghai, Asia/Tokyo, America/New_York and six more) and prints the target zone from a fixed reading. Move over as soon as the zone must be stated in the answer rather than inherited from the reader.
The question is calendar work: weekday tallies, or what date sits 30 days outEvery row describes the same instant. The relative row counts up to whole days and stops, and the panel has no add, subtract or difference field.The date calculator answers difference in days, weekday counts and offsets from a base date, clamping month lengths itself. This page is only useful first, to turn each endpoint into a number.
You are deciding how the instant gets storedThe ISO row is the storable one: always UTC, exactly 24 characters for any year printed with four digits, and its byte order equals chronological order, so a plain string comparison sorts correctly.A BIGINT column of 13-digit milliseconds sorts and indexes without parsing and survives any change of format; keep ISO text for logs, headers and human reading. The local row is the one never to persist — it names no zone and has no fixed width.

The same digits under each unit setting, and where each setting stops

InputMilliseconds (default)Seconds
1 (1 digit)1970-01-01T00:00:00.001Z1970-01-01T00:00:01.000Z
86400000 (8 digits)1970-01-02T00:00:00.000Z1972-09-27T00:00:00.000Z
2147483647 (2^31 - 1)1970-01-25T20:31:23.647Z2038-01-19T03:14:07.000Z
4294967295 (2^32 - 1)1970-02-19T17:02:47.295Z2106-02-07T06:28:15.000Z
9999999999 (largest 10-digit value)1970-04-26T17:46:39.999Z2286-11-20T17:46:39.000Z
253402300799 (last whole second of year 9999)1978-01-11T21:31:40.799Z9999-12-31T23:59:59.000Z
8640000000000000 (8.64e15)+275760-09-13T00:00:00.000ZInvalid timestamp
-500 (negative)1969-12-31T23:59:59.500Z1969-12-31T23:51:40.000Z

Both right-hand columns are the ISO row, i.e. what toISOString() prints: UTC, three fractional digits, and a signed six-digit year once the year passes 9999. Reading N as seconds is the same code path as reading N times 1000 as milliseconds, which is why 8640000000000000 fails in the last column: the multiplication leaves the ECMAScript Date range before any parsing happens, and a NaN from new Date(ms) is what prints the error instead of a clamped boundary value.

Frequently Asked Questions

What exactly is a Unix timestamp?
The number of seconds elapsed since 1970-01-01 00:00:00 UTC, deliberately ignoring leap seconds. It is timezone-neutral, which is why servers and APIs use it to exchange points in time.
Why does my timestamp convert to 1970 or throw an error?
You are probably mixing units: JavaScript Date uses milliseconds while many APIs return seconds. 1,700,000,000 is seconds (November 2023); 1,700,000,000,000 is milliseconds. This tool has an explicit seconds/milliseconds toggle (milliseconds by default) — check which one your input uses.
How do I convert timestamps in my own code?
JavaScript: Math.floor(Date.now() / 1000) for seconds, new Date(ts * 1000) to convert back. Python: time.time() for seconds, datetime.fromtimestamp(ts, tz=timezone.utc) to convert back.

Content reviewed: