Unix timestamps, explained
A Unix timestamp is a number that points to one instant in time. It does that by counting how much time has passed since the Unix epoch: January 1, 1970 at 00:00:00 UTC.
That sounds simple until the same number shows up in an API response, a database row, a JavaScript debugger, and a log file with different lengths. One system stores seconds. Another stores milliseconds. A user expects local time. A server prints UTC. A daylight saving change lands in the middle of a schedule. Suddenly one number can create a very real bug.
This guide explains what Unix timestamps count, why seconds and milliseconds get confused, how timezones fit in, where databases and APIs use timestamps, and how to convert a timestamp without losing the meaning of the instant it represents.
What a Unix timestamp is
The classic Unix timestamp is the number of seconds since the Unix epoch.
The epoch is:
1970-01-01 00:00:00 UTC
So this timestamp:
0
means exactly that epoch instant.
This timestamp:
60
means 60 seconds later:
1970-01-01 00:01:00 UTC
The key word is UTC. A timestamp does not store Cairo time, New York time, Dubai time, or local wall-clock time. It stores an instant. You can display that instant in any timezone, but the timestamp itself is not a timezone label.
That distinction is the thing that keeps timestamp work sane.
Seconds versus milliseconds
Most Unix timestamps you see in backend systems are in seconds. Many timestamps you see in JavaScript are in milliseconds.
That one difference creates a lot of broken dates.
A seconds timestamp around the present day is 10 digits:
1717243200
A milliseconds timestamp around the present day is 13 digits:
1717243200000
They point to the same instant if the longer one is just the shorter one multiplied by 1000.
The common mistake is feeding milliseconds to a tool that expects seconds, or seconds to code that expects milliseconds. The result is usually absurd. A date may land thousands of years in the future, or back near January 1970.
A quick check helps:
- 10 digits usually means seconds
- 13 digits usually means milliseconds
- if the date looks wildly wrong, check the unit before blaming the timezone
This is not a perfect rule because very old or far-future dates can have different lengths, but for normal web and app work it catches the usual error fast.
UTC, local time, and display time
A timestamp represents one instant. Local time is how that instant is shown to a person in a place.
For example, the same timestamp might display as noon in UTC and 3:00 PM in Cairo during a +03:00 offset. The instant did not change. Only the display changed.
This matters when you store and compare data.
Good habits:
- store the instant in a neutral form, often UTC or an epoch timestamp
- store a timezone separately when the timezone is part of the user intent
- convert to local time only for display or for calendar rules that really depend on local time
The phrase "9 AM" is not an instant by itself. It needs a date and a timezone. The phrase "1717243200" is an instant, and then you can ask what local clock time that instant maps to.
Daylight saving time traps
Daylight saving time is where timestamp bugs become calendar bugs.
A Unix timestamp is not confused by daylight saving time. It counts elapsed seconds from the epoch. The trouble starts when a human schedule uses local wall-clock time.
Some local times happen twice when clocks move back. Some local times do not happen at all when clocks move forward. A job scheduled for 2:30 AM local time can become ambiguous or invalid on transition days.
That is why recurring schedules need a clearer rule than "add 24 hours" in many cases. If a user says "every day at 9 AM in Cairo," that is a wall-clock rule. If a system says "run every 86,400 seconds," that is an elapsed-time rule. They are close on ordinary days, but they are not the same idea.
Database and API usage
Timestamps show up in several common places.
APIs use them for fields such as created_at, expires_at, issued_at, and updated_at. Security formats use them too. JWT claims like iat, nbf, and exp are commonly represented as epoch seconds.
Databases may store time as native timestamp columns, integer epoch seconds, integer epoch milliseconds, or text strings in ISO 8601 format. Each choice can work, but the team needs to know what was picked.
Integer timestamps are compact and easy to compare. Native timestamp types can be better for database date operations and indexing. ISO 8601 strings are readable and common in JSON. The bad option is not one specific format. The bad option is mixing formats without naming the unit and timezone policy.
Use field names and docs that remove doubt. expires_at may be readable but vague. expires_at_unix_seconds is harder to misunderstand.
A worked conversion example
Take this timestamp:
1717243200
It is 10 digits, so treat it as seconds first.
Start from the epoch:
1970-01-01 00:00:00 UTC
Move forward 1,717,243,200 seconds. The UTC result is:
2024-06-01 12:00:00 UTC
Now display the same instant in Cairo during a +03:00 offset:
2024-06-01 15:00:00 Africa/Cairo
If another system gives you this instead:
1717243200000
that is the same instant in milliseconds. Divide by 1000 to get the seconds value:
1717243200000 / 1000 = 1717243200
The lesson is not only the conversion. It is the habit: identify the unit first, convert the instant in UTC, then choose the display timezone.
Try it in your browser
Our Unix Timestamp Converter helps you move between epoch values and human-readable dates without writing a quick script every time.
Use it when you need to:
- check whether a timestamp is seconds or milliseconds
- convert an API field into a readable date
- compare UTC and local display times
- debug JWT expiration and issued-at claims
- sanity-check database values before changing code
It runs in your browser, so quick checks stay on your device.
Common mistakes
Mixing seconds and milliseconds. This is the most common timestamp bug. Count the digits and check the API docs.
Treating a timestamp as local time. The timestamp points to an instant. Local time is a display choice.
Dropping the timezone from user intent. A meeting at 9 AM needs a timezone. A timestamp alone is not enough to rebuild the original scheduling rule.
Adding 24 hours for every daily schedule. That may be fine for elapsed intervals. It is not always right for wall-clock schedules across daylight saving changes.
Using vague field names. A name like time or date makes future debugging harder. Name the unit or document it close to the field.
FAQ
Classic Unix timestamps are seconds since the epoch. Many platforms also use epoch milliseconds, so you always need to check the expected unit.
No. It represents an instant. You can display that instant in any timezone.
JavaScript Date values are commonly represented as milliseconds since the epoch. That is why JavaScript timestamps often have 13 digits instead of 10.
Yes, many systems use negative values for instants before the epoch. Support can vary in older tools and databases.
Either can work. Pick one policy, document the unit and timezone behavior, and keep API fields consistent.
Related guides
- Cron expressions, explained - useful when a timestamp bug starts as a scheduling bug.
- JWTs, explained - JWT time claims often use Unix timestamps.
- Working with JSON, explained - many timestamps reach apps inside JSON payloads.