# Unix Timestamps Explained: Seconds vs Milliseconds, Time Zones and 2038

A Unix timestamp is the number of seconds since **1970-01-01 00:00:00 UTC**, an instant known as the Unix epoch. `1700000000` is 14 November 2023, 22:13:20 UTC. It's a single number with no time zone, no format and no ambiguity — which is why APIs, databases, logs and JWTs all use it.

## Seconds or milliseconds?

The most common timestamp bug is mixing the two. JavaScript counts milliseconds; most other systems count seconds. Count the digits:

| Digits | Unit | Example |
|---|---|---|
| 10 | seconds | `1700000000` |
| 13 | milliseconds | `1700000000000` |
| 16 | microseconds | `1700000000000000` |

Feed seconds to something expecting milliseconds and you land in January 1970:

```js
new Date(1700000000).toISOString();         // "1970-01-20T16:13:20.000Z" — wrong
new Date(1700000000 * 1000).toISOString();  // "2023-11-14T22:13:20.000Z"
```

Going the other way, the classic symptom is a date tens of thousands of years in the future.

## Getting and converting timestamps

**JavaScript**:

```js
Date.now();                        // milliseconds
Math.floor(Date.now() / 1000);     // seconds
new Date(seconds * 1000);          // timestamp → Date
Math.floor(date.getTime() / 1000); // Date → seconds
```

**Python**:

```python
import time
from datetime import datetime, timezone

int(time.time())                                   # seconds
datetime.fromtimestamp(1700000000, tz=timezone.utc)  # → aware datetime
int(datetime.now(timezone.utc).timestamp())        # datetime → seconds
```

Pass `tz=timezone.utc` — without it, `fromtimestamp` converts to the machine's local time.

**PostgreSQL**:

```sql
SELECT extract(epoch FROM now())::bigint;  -- seconds
SELECT to_timestamp(1700000000);           -- → timestamptz
```

**MySQL**:

```sql
SELECT UNIX_TIMESTAMP();             -- seconds
SELECT FROM_UNIXTIME(1700000000);    -- → DATETIME in the session time zone
```

**Shell**:

```bash
date +%s                 # now, in seconds
date -u -d @1700000000   # GNU/Linux: timestamp → date
date -u -r 1700000000    # macOS/BSD
```

For quick one-off conversions, use the [timestamp to date](/convert/unix-timestamp-to-date) and [date to timestamp](/convert/date-to-unix-timestamp) converters.

## Time zones

A timestamp has no time zone — it names an instant, and that instant is the same everywhere. Time zones only appear when you **display** it: `1700000000` is 22:13 in London and 17:13 in New York, but it's one moment.

That's why storing timestamps (or `timestamptz` in PostgreSQL) is safer than storing local date strings. Convert to the user's zone at the edge, when you render:

```js
new Date(1700000000 * 1000).toLocaleString("en-US", { timeZone: "America/New_York" });
// "11/14/2023, 5:13:20 PM"
```

## JWTs use seconds

The `exp`, `iat` and `nbf` claims in a JSON Web Token are seconds, not milliseconds. Comparing them with `Date.now()` directly makes every token look expired decades ago — or valid until the year 55,000:

```js
const expired = payload.exp * 1000 < Date.now();
```

Paste a token into the [JWT decoder](/tools/security/jwt-decoder) to see its claims as dates.

## Leap seconds

Unix time pretends every day has exactly 86,400 seconds. When a leap second is inserted, Unix time repeats a second instead of counting it. For almost all application code this doesn't matter — just don't use timestamp differences for precise scientific timing.

## The year 2038 problem

A signed 32-bit integer can hold values up to 2,147,483,647. As a Unix timestamp, that's **2038-01-19 03:14:07 UTC**; one second later, a 32-bit counter wraps to a negative number and the date jumps back to 1901.

Modern operating systems and languages use 64-bit timestamps, which last for billions of years. The risk is in the corners: `INT` database columns, binary file formats and protocols with 32-bit fields, and older embedded devices. MySQL's `TIMESTAMP` type has the same limit — use `DATETIME` or a `BIGINT` for dates past 2038. If you're designing a schema today, use 64-bit integers for anything that holds a timestamp.
