Unix 时间戳:苹果和安卓都可以用,基准都是 1970-01-01 00:00:00 UTC。

常见时间基准与单位

  • Unix / POSIX:1970-01-01 00:00:00 UTC 起算,秒或毫秒。
  • iOS 原生时间(NSDate/CFAbsoluteTime):2001-01-01 00:00:00 UTC 起算,单位秒。
  • Android / Java:System.currentTimeMillis() 为毫秒,基于 Unix。
  • Windows FILETIME:1601-01-01 00:00:00 UTC 起算,单位 100ns(1e-7 秒)。
  • .NET DateTime Ticks:0001-01-01 00:00:00 起算,单位 100ns(1 tick = 100ns)。
  • Mac HFS+ 时间:1904-01-01 00:00:00 UTC 起算,单位秒。
  • GPS 时间:1980-01-06 00:00:00 起算,单位秒,和 UTC 有闰秒偏差。

位数与单位快速判断

  • 10 位:秒(1e9 量级)。
  • 13 位:毫秒(1e12 量级)。
  • 16 位:微秒(1e15 量级)。
  • 19 位:纳秒(1e18 量级)。
  • 17 位左右:常见于 100ns 级别(FILETIME / .NET ticks 的缩放结果)。

常用换算

  • iOS (2001) -> Unix 秒:unix = ios + 978307200
  • Unix 秒 -> iOS:ios = unix - 978307200
  • FILETIME -> Unix 秒:unix = (filetime / 10^7) - 11644473600
  • Unix 秒 -> FILETIME:filetime = (unix + 11644473600) * 10^7
  • HFS+ -> Unix 秒:unix = hfs + 2082844800
  • Unix 秒 -> HFS+:hfs = unix - 2082844800
  • GPS -> Unix 秒:unix = gps + 315964800 - leapSeconds

常见差异点

  • 时间戳本身通常是 UTC,显示时区才会影响“看到的时间”。
  • FAT 文件系统保存的是本地时间,没有时区信息;NTFS 保存 UTC。
  • System.nanoTime() 不是时间戳,只是单调计时器,不能拿来换日期。
  • Unix 时间不考虑闰秒,GPS 时间与 UTC 存在偏差。

Q: 978307200 是三十年吗?
不是 30 年,是 31 年(含闰日)。

978307200 表示从 1970-01-01 00:00:00 UTC 到 2001-01-01 00:00:00 UTC 的秒数:

  • 31 × 365 × 86400
  • 8 × 86400
  • = 978,307,200 秒

所以这是 iOS(2001 基准)和 Unix(1970 基准)之间的固定偏移量。