std::filesystem::last_write_time在Windows下精度为100纳秒,但转system_clock会降为毫秒;creation_time未被C++20标准支持,需用Windows API如GetFileInformationByHandle获取。

std::filesystem::last_write_time 返回的是纳秒级,但 Windows 下实际只有 100 纳秒精度
Windows 的 FILETIME 是以 100 纳秒为单位的 64 位整数,std::filesystem::last_write_time 在 MSVC(19.30+)和 libc++(15.0+)中会保留该粒度,但 std::filesystem::file_time_type 的底层时钟通常不直接暴露微秒/纳秒字段。你拿到的 file_time_type 对象本身是“高精度”的,但转换成 std::chrono::system_clock::time_point 会丢失精度——因为 system_clock 在 Windows 上默认只到毫秒。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 别用
std::chrono::system_clock::to_time_t或std::chrono::duration_cast<:chrono::microseconds></:chrono::microseconds>直接转file_time_type,会截断 - 先用
std::chrono::time_point_cast<:chrono::nanoseconds>(tp.time_since_epoch())</:chrono::nanoseconds>提取纳秒偏移量(注意:这是自 epoch 起的纳秒数,不是 UTC 时间戳) - 若需映射到 wall-clock 微秒时间戳(如 Unix timestamp × 1e6),必须走平台原生 API 补齐时区与历法逻辑,
std::filesystem不提供此能力
Windows 下获取创建时间(creation_time)必须绕过 std::filesystem
std::filesystem::last_write_time 是标准支持的,但 std::filesystem::creation_time 并不存在——C++20 标准没定义该函数,所有主流实现(MSVC、GCC、Clang)均不提供。Windows 文件的创建时间只能通过 GetFileInformationByHandle 或 FindFirstFileExW 获取 FILETIME,再手动转为 file_time_type。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
CreateFileW打开文件(带FILE_FLAG_BACKUP_SEMANTICS支持目录) - 调
GetFileInformationByHandle填充BY_HANDLE_FILE_INFORMATION,读取ftCreationTime - 将
FILETIME转为std::filesystem::file_time_type:先转为 100-nanosecond intervals(即((int64_t)ft.dwHighDateTime ),再构造 <code>duration并加到file_time_type::clock::from_time_t(0)对应的 epoch 偏移上(Windows epoch 是 1601-01-01 UTC) - 别依赖
std::filesystem::status或symlink_status的扩展字段——它们不携带创建时间
Linux/macOS 下 creation time 基本不可靠,别硬取
Linux 的 ext4/xfs 默认不记录创建时间(btime),即使内核支持(5.1+)、文件系统启用 ext4 的 inode_v2 或 xfs 的 bigtime,glibc 和 libstdc++ 也未将 btime 暴露给 std::filesystem。macOS 的 APFS 虽存有 birthtime,但 stat 系统调用返回的 st_birthtimespec 不被 libc++ 封装进 file_time_type。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- Linux 上尝试
statx(AT_FDCWD, path.c_str(), AT_STATX_SYNC_AS_STAT, STATX_BTIME, &buf),检查buf.stx_mask & STATX_BTIME;失败就当不存在 - macOS 上用
struct stat sb; stat(path.c_str(), &sb); sb.st_birthtimespec.tv_sec,但注意:st_birthtimespec是非标准扩展,仅限 Apple 平台 - 跨平台代码里,把 creation time 当作“尽力而为”字段,降级为
last_write_time或当前时间 fallback
微秒级时间戳拼接:别用 time_t + tv_usec 组合
很多旧代码习惯用 gettimeofday 或 clock_gettime(CLOCK_REALTIME) 得到 struct timeval,再组合 tv_sec * 1000000LL + tv_usec。但文件时间不是实时钟,且 std::filesystem::file_time_type 和系统实时时钟的 epoch 不同(Windows 是 1601,Unix 是 1970),直接乘加会错乱。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 统一用
std::chrono::time_point_cast<:chrono::microseconds>(tp).time_since_epoch().count()</:chrono::microseconds>获取自file_time_type::clock::epoch()起的微秒数(注意:这不是 Unix timestamp) - 若真要 Unix 微秒时间戳(即 1970-01-01 起的微秒数),Windows 必须用
FileTimeToSystemTime→SystemTimeToTzSpecificLocalTime→ 手动算 UTC 秒数,再乘 1e6 + 微秒部分;Linux/macOS 可用stat的st_mtim.tv_sec/.tv_nsec转换 - 避免在日志或序列化中混用不同 epoch 的数值——同一项目里要么全用
file_time_type原生值,要么全转成 Unix microsecond timestamp
最麻烦的不是怎么取,而是“取出来的值到底代表什么”。Windows creation time 和 Linux btime 语义不同,file_time_type 的 epoch 不统一,跨平台时连“1 秒等于多少个 tick”都要查编译器文档。动手前先确认:你要的到底是文件系统原生时间戳,还是可比对的 wall-clock 微秒值。


















