为什么需要在代码中把日期转 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.