时间戳与进制转换的那些坑:从 Unix 秒到本地时间的正确姿势

时间戳看着简单,真要算对时区、对齐单位、避开 2038,坑不少。这篇把常见陷阱和工具用法捋一遍。

一、Unix 时间戳:单位比你想的多

Unix 时间戳是"从 1970-01-01 00:00:00 UTC 起经过的秒数"。但"单位"是第一个坑:

  • 秒(s):最常见,2038 年前 32 位有符号整数够用;
  • 毫秒(ms) :很多语言/接口默认毫秒(JavaScript 的 Date.now() 返回的就是毫秒);
  • 微秒 / 纳秒:高精度场景。

翻车现场:把毫秒当成秒,时间直接跳到几万年后;把秒当毫秒,时间停在 1970 年初。拿到时间戳第一件事是确认单位。

2038 问题 :32 位有符号 time_t 最大值对应 2038-01-19,之后溢出回负。现代 64 位系统已躲过,但老设备、嵌入式、某些数据库字段仍是 32 位,长期归档数据要当心。

二、时区:UTC 还是本地

时间戳本质是 UTC,转成"几点"必须选时区:

  • UTC:全球统一,适合存储和日志,无歧义;
  • 本地时间:给人看,但涉及夏令时(DST)会麻烦------同一本地时刻在切换日可能不存在或重复。

坑:默认用"本地时区"解析,服务器在 UTC、客户端在北京,显示差 8 小时;或者日志里混了本地时间,事后对账对不上。建议存储用 UTC,展示按需转本地,全程带时区信息。

三、进制:不止是"程序员炫技"

进制转换看着基础,实际高频出现在:

  • 文件权限 :chmod 755 的 755 是八进制(rwxr-xr-x);
  • 颜色值 :#FF8800 是十六进制;
  • IP / 子网掩码 、内存地址 、位运算调试全靠十六进制。

Python 里互相转换很直接:

python 复制代码
import datetime, time

ts_sec = 1760000000
print(datetime.datetime.fromtimestamp(ts_sec))          # 本地
print(datetime.datetime.utcfromtimestamp(ts_sec))       # UTC

# 进制互转
n = 255
print(hex(n), oct(n), bin(n))          # 0xff 0o377 0b11111111
print(int("ff", 16), int("377", 8))    # 255 255

四、时间差计算

算"两个时刻差多久",别手搓相减再除 86400(忽略闰秒、时区)。用语言自带的 duration 类型或成熟库,避免"差一天其实是 23 小时"的夏令时误差。批量算工期、倒计时、日志跨度,先想清楚要的是"日历差"还是"绝对时长"。

五、工具层面

零散的"时间戳 ↔ 时间""进制互转""两个时间点差多少"这类操作,我平时固定用 7aa7工具箱 里的"进制时间戳"和"时间差计算"模块:粘贴一个值就能看到秒/毫秒/各时区的对应,不用每次开 Python。工具不止它一家,但这类高频小操作,一个离线、随时能开、不联网的工具箱最顺手。

六、小结

  • 时间戳先确认单位 (秒/毫秒)和时区(UTC/本地);
  • 长期数据警惕 2038 与 32 位溢出;
  • 进制转换在权限、颜色、IP、调试里天天用,掌握 int(x, base) 即可;
  • 时间差用库别手搓,注意夏令时。

你被时间戳坑过最离谱的一次是什么?(比如"时间显示成 1970 年")评论区见。