← 全部文章

在 JavaScript、Python、SQL、Go 中把日期转换为 Epoch

面向开发者的实战教程,讲解如何在 JavaScript、Python、SQL、Go 和 shell 中把日期与时区转换为 Unix epoch。涵盖时区感知与朴素解析、DST gap,以及秒与毫秒的选择。

为什么需要在代码中把日期转 Epoch

大多数应用以 Unix 整数存储时间戳,但接收到的日期是字符串 — 表单里的日历值、CSV 里的日期列、按特定时区格式化的 webhook 字段。把这些字符串在代码里转成 epoch,数据库才能排序,服务才能比较,API 才能接受。本文按 JavaScript、Python、SQL、Go、shell 分别给出地道写法,以及每个团队迟早都会遇到的时区 bug。

JavaScript:Date、getTime 与带时区的输入

JavaScript 内部以毫秒存储时间。Date.UTC 接受 UTC 墙上时间并返回毫秒 epoch;带显式偏移量的 ISO 8601 字符串可用 new Date(iso).getTime();除以 1000 得到秒。

  • Date.UTC(2026, 0, 1, 0, 0, 0) → 1767225600000 (month is zero-indexed)
  • new Date('2026-01-01T08:00:00-05:00').getTime() → 1767265200000
  • Math.floor(Date.now() / 1000) → current Unix seconds
  • Wall-clock in a non-UTC zone needs a zone-aware library (Luxon, date-fns-tz, Temporal)

Python:datetime.timestamp 与 calendar.timegm

Python 的 datetime 对象通过 .timestamp() 转 epoch — 但前提是它必须是 timezone-aware。一个 naive datetime 会被当作本机本地时间解释,这是线上 epoch 出错最常见的原因。

  • datetime(2026, 1, 1, tzinfo=timezone.utc).timestamp() → 1767225600.0
  • calendar.timegm(struct_time) → seconds (UTC-only)
  • datetime.now(ZoneInfo('America/New_York')).timestamp() → zone-aware now
  • Avoid datetime.fromisoformat(s).timestamp() when s has no offset

SQL:EXTRACT EPOCH、UNIX_TIMESTAMP、UNIX_SECONDS

每个主流数据库都提供把时间戳列转成 epoch 整数的函数。一定要明确处理列的时区:TIMESTAMP WITH TIME ZONE 与 TIMESTAMP WITHOUT TIME ZONE 传给这些函数的行为差别很大。

  • PostgreSQL: EXTRACT(EPOCH FROM ts) → seconds (double)
  • MySQL: UNIX_TIMESTAMP(ts) → seconds, naive ts read in session timezone
  • BigQuery: UNIX_SECONDS(ts) / UNIX_MILLIS(ts) — TIMESTAMP only
  • SQLite: strftime('%s', ts) → seconds as string, cast to integer

Go 和 shell:time.Unix 与 date +%s

Go 用包含偏移量的 layout 解析,然后调用 .Unix() 得秒、.UnixMilli() 得毫秒。shell 里 GNU date -d 能解析常见日期串,BSD / macOS 的 date -j -f 则必须显式指定格式串。

  • Go: t, _ := time.Parse(time.RFC3339, "2026-01-01T00:00:00Z"); t.Unix()
  • Go: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
  • GNU date: date -d "2026-01-01 00:00:00 UTC" +%s
  • macOS date: date -j -u -f "%Y-%m-%d %H:%M:%S" "2026-01-01 00:00:00" +%s

FAQ

How do I convert time to epoch time?
Choose the date, clock time, and timezone, then convert that instant to Unix seconds or milliseconds. If the timezone is missing, the result may be off by hours.
Is timestamp to epoch the same as date to epoch?
Usually yes. It means converting a readable timestamp or date-time string into an epoch number.
Should I send epoch seconds or milliseconds to an API?
Follow the API documentation. If it says Unix timestamp, it often means seconds, but JavaScript-oriented APIs may expect milliseconds.
Why does the same date give a different epoch in different timezones?
Because a local wall-clock time only identifies an instant once a timezone is attached. 2026-01-01 00:00 is 1767225600 in UTC but 1767243600 in New York — five hours later in real time. Set the timezone before converting.