← Back to Blog

Unix Timestamp Conversion Explained: Seconds, Milliseconds & Time Zones

What is a Unix Timestamp?

A Unix timestamp is the number of seconds (or milliseconds) elapsed since 1970-01-01 00:00:00 UTC (the epoch). It is an absolute instant independent of time zone — the same moment yields the same timestamp number whether you are in Beijing, London, or New York.

Representing time as a single integer lets you store, compare, and subtract moments like ordinary numbers, free from the complexity of human calendars.

Seconds vs Milliseconds

The most common bug in practice is mixing units:

Form Digits Example (same instant) Common source
Seconds 10 digits 1700000000 Linux date +%s, MySQL UNIX_TIMESTAMP(), most backend APIs
Milliseconds 13 digits 1700000000000 JavaScript Date.now(), Java System.currentTimeMillis()

Rule of thumb: 13-digit value ÷ 1000 ≈ 10-digit value. If the frontend passes a 13-digit value that the backend stores as seconds, the time jumps tens of thousands of years into the future. A good converter should auto-detect seconds vs milliseconds by digit count.

Time Zones and Local Display

The timestamp is an absolute UTC instant. When you see 2023-11-15 06:13:20 on a page, that is the UTC instant rendered in your local time zone:

const ts = 1700000000          // seconds
const d = new Date(ts * 1000)  // note ×1000 to milliseconds
console.log(d.toString())      // local: Wed Nov 15 2023 06:13:20 GMT+0800
console.log(d.toISOString())   // UTC: 2023-11-14T22:13:20.000Z

Always store and transmit in UTC; format for the user's time zone only at display time. This is the only rule that keeps cross-timezone systems sane.

Daylight Saving Time (DST) Pitfalls

In regions with DST, two days a year have a "nonexistent hour" or a "repeated hour". Calendar-based arithmetic (e.g. "add 24 hours") drifts by one hour on DST transition days. The correct approach: do arithmetic on the timestamp (UTC integer), then format — never add/subtract on local wall-clock time.

Leap Seconds

Unix time increments at a fixed 86400 seconds per day and deliberately ignores leap seconds. The OS/NTP smooths leap seconds at a lower layer, transparent to almost all applications. Only extreme-precision domains (financial matching, satellite timing) need special handling.

Correct Conversion Across Languages

JavaScript (milliseconds → readable, watch the unit):

const sec = 1700000000
const d = new Date(sec * 1000)           // seconds → milliseconds
const iso = d.toISOString()              // UTC string
const local = d.toLocaleString('en-US')  // local-time string

Python:

from datetime import datetime, timezone
ts = 1700000000
print(datetime.fromtimestamp(ts, tz=timezone.utc))  # be explicit about UTC

Go:

import "time"
t := time.Unix(1700000000, 0)  // seconds; use time.UnixMilli for milliseconds

Best Practices

  1. Store in UTC: Use TIMESTAMP (UTC) or an integer timestamp — never a "local time" column.
  2. Transmit timestamps or ISO 8601: Avoid tz-less strings like 2023-11-15 06:13:20.
  3. Format at display time per user tz: Use Intl.DateTimeFormat, not hand-built strings.
  4. Agree on units explicitly: Document seconds vs milliseconds; let the converter auto-detect as a fallback.
  5. Never do math on wall-clock time: Differences and schedules belong on the integer timestamp.

Frequently Asked Questions

10 位和 13 位时间戳有什么区别?

10 位是秒级(Unix epoch 秒),13 位是毫秒级。同一时刻 13 位值 ≈ 10 位值 × 1000。JavaScript 的 Date.now() 返回毫秒,很多后端接口用秒,混用会差 1000 倍。

为什么同一时间戳在不同时区显示不同?

时间戳本身是 UTC 绝对时刻,与时区无关;显示出的日期时间是按你所在时区渲染的结果。转换工具应允许选择目标时区再展示。

前端和后端的时区要对齐吗?

不需要在「时区」上对齐,而要在「使用 UTC 存储、本地展示」上对齐。数据库和接口统一传 UTC(或时间戳),展示层按用户时区格式化,避免服务器时区漂移导致错乱。

闰秒会影响时间戳吗?

Unix 时间戳按固定 86400 秒/天线性递增,不感知闰秒;闰秒由 NTP/操作系统在底层平滑处理。业务系统一般无需特殊处理,但金融高频场景要知悉此差异。

2038 年问题还存在吗?

32 位有符号整数存秒级时间戳会在 2038-01-19 溢出。现代语言(64 位)已规避,但老系统、嵌入式设备、部分 C 库仍可能踩坑,跨系统传时间建议用 64 位或 ISO 8601 字符串。

← Back to Blog