Unix Timestamps Explained: Seconds, Milliseconds, UTC, and Log Debugging
Unix Timestamps Explained: Seconds, Milliseconds, UTC, and Log Debugging
A practical guide to Unix timestamps, unit confusion, UTC display, JavaScript milliseconds, and how to read time fields in logs and APIs.
Original workflow visual
Unix Timestamps Explained: Seconds, Milliseconds, UTC, and Log Debugging
Detect unit
Review before moving forward
Convert UTC
Review before moving forward
Compare events
Review before moving forward
Unix time measures elapsed time since the start of 1970 in UTC. A timestamp is not a timezone-aware string; it is a count. The same timestamp represents the same instant everywhere, but it can be displayed differently in Hong Kong, New York, Berlin, or UTC. This distinction is useful: storage can use one universal value while user interfaces display local time.
Many APIs and databases store Unix time in seconds. JavaScript Date methods commonly use milliseconds. Confusing the two moves a date by a factor of one thousand. A seconds timestamp interpreted as milliseconds lands near 1970, while a milliseconds timestamp interpreted as seconds lands far in the future. Magnitude is the first clue: current second-based timestamps have ten digits, while millisecond-based timestamps usually have thirteen.
During debugging, local time can create confusion because every person may see a different display for the same instant. UTC gives the team a shared reference. Local display is still important for user-facing behavior, but incident notes, logs, token claims, database comparisons, and scheduler analysis should include UTC or an explicit timezone. "Yesterday evening" is not a timestamp.
JWT claims such as exp, iat, and nbf usually use seconds. Log platforms may store event time, ingestion time, processing time, and display time separately. A webhook may include the time an event happened, while your system records the time it received the event. When comparing timestamps, identify what event each number represents. Otherwise a correct timestamp can be blamed for a delay that happened elsewhere.
Distributed systems rely on clocks that are usually synchronized but not perfect. A token issued on one server may appear slightly in the future to another server. A scheduled job may compare against local time while a database uses UTC. Small tolerances can be reasonable for authentication and event ordering, but large unexplained differences should be investigated. Do not hide a seconds-versus-milliseconds bug behind a broad tolerance.
A formatted date string may omit seconds, milliseconds, timezone, or offset. That makes it pleasant to read and weaker for debugging. If two events appear to happen at the same minute, millisecond precision may still show the order. If a date string has no timezone, another system may assume local time. Keep the raw timestamp available when precision or ordering matters.
When a timestamp looks wrong, first determine whether it is seconds, milliseconds, microseconds, or nanoseconds. Convert it to UTC. Convert it to the relevant local timezone only after UTC is clear. Check what event the timestamp represents. Compare it with adjacent events in the same unit. Finally, document the expected unit in API docs, database comments, or code types. Most timestamp bugs are ordinary unit and context bugs, not mysterious time problems.
Common Questions
A seconds timestamp may have been interpreted as milliseconds, or the value may be a small duration rather than an absolute timestamp.
Either can work if documented. The important part is consistency and clear naming.
No. It represents an instant. Timezones affect how that instant is displayed.
Compare event time, ingestion time, processing time, and display time separately. A webhook may be created at one moment, received later, processed later, and shown in a local timezone afterward. If those times are mixed together, a delay in the queue can be mistaken for a timestamp conversion bug.
Names such as created_at_ms or expires_at_seconds prevent silent mistakes when values cross language boundaries. JavaScript, databases, APIs, and analytics tools often use different defaults. A clear unit in the field name is boring, but it protects future code from guessing.
Use one known seconds value, one known milliseconds value, and one date near a timezone boundary. Convert all of them to UTC and local time, then compare with expected results. This catches unit mistakes and display assumptions before real logs or token claims are involved.