指南

时间戳无效?最快的排查与修复指南

快速自检清单

  • 位数:10=秒,13=毫秒,16=微秒,19=纳秒。
  • 字符:只能是数字,去掉空格/标点/字母。
  • 范围:结果日期要落在合理区间;用 64 位存储。
  • 时区:先解析为 UTC,再转目标时区。
  • DST:若需本地化,用 IANA 时区名避免夏令时缺口。

想立刻验证?打开 Unix Timestamp ConverterBatch Converter

常见报错类型

  • 长度错位:13 位当秒 → 远未来日期。
  • 非数字:隐藏空格、逗号、字母。
  • 超范围:32 位秒级 2038 溢出;负数在部分系统不支持。
  • 时区不明:服务器本地时间与预期 UTC 不一致。
  • DST 影响:落在缺失的那一小时导致解析失败。

校验与规范化

// JS:校验 & 归一化为毫秒
export function normalizeEpoch(raw) {
  const trimmed = raw.trim();
  if (!/^[0-9]+$/.test(trimmed)) throw new Error("仅允许数字");
  const len = trimmed.length;
  if (len === 10) return Number(trimmed) * 1000;
  if (len === 13) return Number(trimmed);
  if (len === 16) return Number(trimmed) / 1000;
  if (len === 19) return Number(trimmed) / 1_000_000;
  throw new Error("长度不合法");
}
# Python:校验并转为 UTC datetime
from datetime import datetime, timezone

def parse_epoch(raw: str) -> datetime:
    if not raw.isdigit():
        raise ValueError("仅允许数字")
    n = len(raw)
    if n == 10:
        ts = int(raw)
    elif n == 13:
        ts = int(raw) / 1000
    elif n == 16:
        ts = int(raw) / 1_000_000
    elif n == 19:
        ts = int(raw) / 1_000_000_000
    else:
        raise ValueError("长度不合法")
    return datetime.fromtimestamp(ts, tz=timezone.utc)
-- PostgreSQL:批量标记精度/异常
SELECT id, ts_raw,
       CASE
         WHEN ts_raw ~ '^[0-9]{10}$' THEN 'seconds'
         WHEN ts_raw ~ '^[0-9]{13}$' THEN 'milliseconds'
         WHEN ts_raw ~ '^[0-9]{16}$' THEN 'microseconds'
         WHEN ts_raw ~ '^[0-9]{19}$' THEN 'nanoseconds'
         ELSE 'invalid'
       END AS ts_precision
FROM events
WHERE ts_raw !~ '^[0-9]{10}$'
   OR ts_raw::numeric > 32503680000; -- > 3000-01-01 视为异常

修复模板

  • 精度修复:按位数缩放到毫秒,再重新解析。
  • 清洗字符:去掉空格、逗号后再走正则校验。
  • 范围兜底:超出合理窗口(如 <2000>2100)直接标记为异常。
  • 时区修复:先以 UTC 解析,再转到目标偏移或 IANA 时区。
  • DST 安全:尽量使用 UTC;若必须本地显示,用 IANA 区而非固定偏移。

FAQ

  • 安全默认值是什么? 先解析为 UTC,再输出目标时区。
  • 如何避免 2038 问题? 全链路使用 64 位整数,避免 32 位秒级存储。
  • 批量清洗怎么做? 正则预过滤 + 位数缩放 + 转换校验;可用 Batch Timestamp Converter

相关工具与指南