Windows FILETIME 转 Unix 时间戳转换器
把 Windows FILETIME 转换为 Unix 时间。精确公式与大数支持。输出:秒、毫秒、ISO 8601 与可读格式。
自 1601-01-01 UTC 以来的 100 纳秒间隔数
当前时间 — Windows FILETIME—
Unix 时间戳(秒)—
什么是 Windows FILETIME?
FILETIME 是整个 Windows API 中使用的时间戳格式。它是一个 64 位值,记录自 1601 年 1 月 1 日 00:00:00 UTC(Windows 内部使用的格里高利历周期起点)以来经过的 100 纳秒间隔(千万分之一秒)的数量。
- 纪元:1601-01-01 00:00:00 UTC
- 分辨率:100 纳秒刻度(每秒 10,000,000)
- 宽度:64 位无符号整数,常以两个 32 位 DWORD 存储(dwLowDateTime、dwHighDateTime)
- 常见于:NTFS 文件时间、Windows 注册表、Active Directory(如 lastLogonTimestamp、pwdLastSet)以及事件日志
如何将 FILETIME 转换为 Unix 时间戳
FILETIME 纪元(1601)与 Unix 纪元(1970)之间相差 11,644,473,600 秒。把 FILETIME 除以 10,000,000 得到秒,再减去这个偏移。
- Unix seconds = FILETIME / 10000000 − 11644473600
- Unix milliseconds = FILETIME / 10000 − 11644473600000
- 示例:133444736000000000 → 1700000000 秒 → 2023-11-14 22:13:20 UTC
- 反向:FILETIME = (Unix milliseconds + 11644473600000) × 10000
精度与边界情形
当前时刻的 FILETIME 约为 1.3 × 10^17,超过了 JavaScript 数字的安全整数范围(2^53)。本转换器用 BigInt 解析该值,因此不会丢失精度。亚毫秒精度(最后四位)在转换为毫秒 Unix 时间戳时会被丢弃。
- Active Directory 有时存储 0 或 9223372036854775807 表示「从不」——它们是哨兵值,不是真实日期
- FILETIME 始终是 UTC;仅在显示结果时才应用时区
- 本地时间变体(来自 FileTimeToLocalFileTime)已包含偏移——请先将其转换回 UTC
相关时间戳格式转换器
FILETIME 实用提示
现实中 FILETIME 转换容易踩到的几点:
- PowerShell:[DateTime]::FromFileTimeUtc($ft) 是脚本中的标准转换
- Active Directory 常用常量 9223372036854775807(Int64.MaxValue)表示「永不过期」——按哨兵值处理,而非日期
- AD 还用 0 表示「从未设置」;对 0 和 Int64.MaxValue 都要特殊处理
- NTFS 文件时间有三种:创建、最后写入、最后访问——都使用相同的 FILETIME 格式
- 当 FILETIME 被拆成两个 32 位 DWORD 时,转换前先按 (high << 32) | low 合并
FAQ
- 什么是 FILETIME 纪元?
- FILETIME 计数自 1601 年 1 月 1 日 00:00:00 UTC 以来的 100 纳秒间隔,这是 Windows 用于公历的基准日期。
- 为什么要减去 11644473600 秒?
- 这是 1601 年 FILETIME 纪元与 1970 年 Unix 纪元之间的秒数。把 FILETIME 除以 10,000,000 得到自 1601 年起的秒数;减去该偏移即把基准移到 1970 年。
- 如何转换以两个 32 位值存储的 FILETIME?
- 按 FILETIME = (dwHighDateTime × 4294967296) + dwLowDateTime 组合它们,然后照常转换这个 64 位值。