A Unix timestamp is the number of seconds that have elapsed since January 1, 1970 at 00:00:00 UTC โ known as the Unix epoch. It's the universal language of time in programming, APIs, databases, and security tokens. If you work with 2FA, JWTs, or any token-based authentication, you'll encounter Unix timestamps constantly.
In This Guide
What Is a Unix Timestamp?
Unix time counts seconds continuously from the Unix epoch โ January 1, 1970 at midnight UTC. As of early 2026, the current Unix timestamp is around 1,741,651,200. This simple integer is timezone-agnostic and unambiguous, which is why it became the standard way to represent time in computing.
One key property: Unix time doesn't care about timezones. 1,741,651,200 means the same instant everywhere in the world. This makes it ideal for systems where servers, clients, and databases are in different timezones.
Why TOTP Depends on Unix Time
TOTP (Time-based One-Time Password) uses Unix timestamps as one of its two inputs (the other being the secret key). The algorithm divides the current timestamp by 30 to produce a "time window" number. For example, timestamp 1,741,651,200 รท 30 = window 58,055,040. Every second within the same 30-second window produces the same TOTP code.
Both your authenticator app and the authentication server calculate this window independently. If their clocks differ by more than ~30 seconds, the windows won't match, and your codes will be rejected. This is why clock sync issues cause TOTP failures.
You can see the live TOTP window alongside timestamps using our Unix Timestamp Converter.
Unix Timestamps in JWTs
JSON Web Tokens (JWTs) use Unix timestamps for three standard claims: iat (issued at โ when the token was created), exp (expires โ when the token becomes invalid), and nbf (not before โ the earliest time the token is valid). All three are Unix timestamps in seconds.
A JWT with "exp": 1741737600 will be rejected by the server after that Unix timestamp. Use our timestamp converter to decode when any JWT expires, or use the JWT Decoder to inspect the full payload.
Converting Timestamps
In JavaScript: Date.now() returns milliseconds โ divide by 1000 and round down to get seconds. new Date(timestamp * 1000) converts a seconds timestamp back to a Date object.
In Python: import time; time.time() returns a float of seconds. datetime.utcfromtimestamp(ts) converts back to a datetime.
In the terminal: date -d @1741651200 (Linux) or date -r 1741651200 (macOS) converts a timestamp to a human-readable date. Or just use our browser-based converter.
Common Pitfalls
Seconds vs milliseconds confusion is the most common bug. JavaScript's Date.now() returns milliseconds (13 digits in 2026). Most APIs and security standards expect seconds (10 digits). Mixing these causes tokens that appear to expire 1000x too fast or not at all.
Timezone mistakes: Unix timestamps are always UTC. Converting to a local time is a display concern only โ never store "local" timestamps. Always store UTC, convert for display.
Integer overflow on 32-bit systems: see the Year 2038 problem below.
The Year 2038 Problem
32-bit signed integers can hold values up to 2,147,483,647 โ which corresponds to January 19, 2038 at 03:14:07 UTC. Systems that store Unix timestamps as 32-bit signed integers will overflow at that moment, causing dates to wrap to 1901 or crash. Modern systems use 64-bit integers, which won't overflow for approximately 292 billion years. If you're maintaining legacy systems, this is worth auditing.
How to Convert a Timestamp by Hand
You can convert any Unix timestamp to a date with a calculator and three steps. Take the timestamp 1,704,067,200 as an example.
- Divide by 86,400 (the number of seconds in one day). 1,704,067,200 รท 86,400 = 19,723 exactly. That's the number of days since the epoch, and the exact result tells you the time is midnight UTC.
- Find the date. Count 19,723 days forward from January 1, 1970, accounting for leap years, and you land on January 1, 2024 โ a commonly used "New Year" timestamp.
- Account for the remainder. If the division leaves a remainder, that's the seconds after midnight. Remainder 9,000 seconds = 2 hours 30 minutes, so
1,704,076,200would be 2024-01-01 02:30:00 UTC.
The same logic works backward: to get a timestamp from a date, convert the date to a day count, multiply by 86,400, and add the seconds since midnight. When you see a timestamp like 1,741,737,600 in a JWT payload, this is the method it takes to read it as a human date. For everyday use, an online converter is faster and avoids arithmetic slips.
Practical Tips for Working With Timestamps in Security Code
These habits prevent the most common timestamp-related bugs in authentication and token code:
- Decide on seconds and stay consistent. Use the Unix convention (seconds, 10 digits) everywhere, and convert only at system boundaries like JavaScript's
Date.now(), which returns milliseconds. - Store and compare in UTC. Never persist a "local" timestamp. Convert to the user's timezone only when rendering output such as
2025-03-12T00:00:00Z(ISO 8601), which is the standard format for API responses and logs. - Prefer library functions over manual math. Date-handling libraries implement leap years, daylight saving rules, and ISO 8601 formatting correctly; hand-written date math is where epoch bugs live.
- Test the boundaries. When working with TOTP or token expiry, test exactly at window edges โ a code generated at second 29.9 of a 30-second window must still be accepted by the server's window calculation.
Frequently Asked Questions
What is the difference between a Unix timestamp and ISO 8601?
A Unix timestamp is an integer counting seconds since the epoch (1970-01-01 UTC). ISO 8601 is a human-readable date format like 2025-03-12T00:00:00Z. They describe the same instant and can be converted into each other.
Why do some systems return 10-digit timestamps and others 13-digit?
10-digit values are seconds since the epoch โ the Unix convention. 13-digit values are milliseconds, which JavaScript's Date.now() returns. Confusing the two makes token expiry calculations off by a factor of 1,000.
Do leap seconds affect Unix timestamps?
Unix time ignores leap seconds by definition โ every day is treated as exactly 86,400 seconds. Real-world systems handle leap seconds through smearing, so timestamps remain consistent across applications.
What formats do I use to read a timestamp in code?
In JavaScript, new Date(timestamp * 1000).toISOString() returns an ISO 8601 string. In Python, datetime.datetime.fromtimestamp(ts, tz=timezone.utc) does the same. Both produce the UTC time, which you can then convert for display.
Unix Timestamps in Databases and Logs
Databases store timestamps as integers for a reason: comparing and sorting epoch values is trivial, indexes stay small, and there is no timezone ambiguity to corrupt the ordering. A row written at 09:00 in Tokyo and one written at the same instant in New York share the same integer, so queries like "all sessions after this event" stay correct across servers and regions. Applications usually convert to a human-readable format only at the edge โ in SQL views, API responses, or UI rendering.
Log files follow the same convention. Server logs almost always record UTC, and many log lines include the epoch alongside the formatted date. When you are correlating events across services that log in different timezones, the epoch column is the reliable one; the formatted strings are only trustworthy if you know each server's clock offset. If you build your own logging, store UTC and format for display โ you will thank yourself the first time a customer dispute needs an exact cross-service timeline.
Timezones, DST, and Why Epoch Time Ignores Them
Daylight saving time is a display problem, never a storage problem. The epoch instant for a meeting at 10:00 AM London time on a July day and a January day differ by exactly six months of seconds โ the calendar conversion handles the DST shift, but the integer itself never changes. This is why bugs appear when developers convert to a local timezone, do arithmetic on the result, and convert back: "tomorrow at midnight" computed in a DST-offset zone can land an hour off after the round-trip.
The practical rule: convert once, at the boundary where the user sees the value, and keep offsets explicit. Named timezone databases (like the IANA tz database) handle DST rules correctly for every region; fixed numeric offsets do not, because they ignore when a region changes its clocks. A server at UTC+2 in summer may be UTC+1 in winter โ code that hardcodes the offset produces wrong timestamps for half the year.
Timestamps in HTTP Headers, Cookies, and Signed URLs
Beyond tokens, Unix timestamps appear in places you might not expect. The Expires cookie attribute uses a date string, but services that compute cookie lifetimes usually derive it from epoch arithmetic internally. Signed URLs โ the kind used by cloud storage buckets and download links โ embed an expiration timestamp in the signature: X-Amz-Date and X-Amz-Expires in S3 presigned URLs, for example. If your clock is fast or slow by even a few minutes, those URLs can fail with an "expired" error before their intended time, or remain valid longer than intended.
OAuth flows are the same story: the exp claim on an access token is an epoch value, and a client whose clock drifts can find itself rejected with "token expired" while the token is actually fine. This is why systems that verify signatures should allow an acceptable clock skew window (commonly 30โ60 seconds) and why network time sync on servers is a security control, not just a convenience.