std::filesystem::creation_time 不存在于C++20标准中,Windows下需用GetFileTime获取创建时间,Linux/macOS无可靠创建时间支持,应降级使用last_write_time。

std::filesystem::last_write_time 只能获取修改时间,不是创建时间
Windows 上的文件创建时间(creation time)在 C++ 标准库中 std::filesystem 并未提供对应接口。C++20 的 std::filesystem::last_write_time、std::filesystem::last_access_time 都有定义,但 std::filesystem::creation_time **根本不存在** —— 这是标准遗漏,不是你用错了。
常见误判:看到某些编译器(如 MSVC)头文件里有未公开的 __creation_time 成员,或网上抄来的“扩展版 filesystem”,实际调用会触发未定义行为或编译失败。
Windows 下必须用 GetFileTime + FILETIME 转换
要拿到真实创建时间,得绕过 std::filesystem,直接调 Windows API。核心步骤是:CreateFileW 打开句柄 → GetFileTime 获取 FILETIME → 转成 std::chrono::file_clock::time_point(如果需与 std::filesystem 时间类型对齐)。
-
GetFileTime返回三个时间:lpCreationTime(创建)、lpLastAccessTime(访问)、lpLastWriteTime(修改),注意顺序 - 返回的
FILETIME是 100 纳秒为单位的自 1601-01-01 UTC 的计数,不能直接当time_t用 - 若目标是兼容
std::filesystem::last_write_time的返回类型(即file_clock::time_point),需用std::chrono::file_clock::from_sys或手动转换(推荐前者,但注意 Windows 的file_clock实现可能不精确) - 务必检查
CreateFileW返回是否为INVALID_HANDLE_VALUE,且GetFileTime返回TRUE,否则时间值不可信
跨平台代码别硬塞 creation_time,优先降级处理
Linux/macOS 没有“创建时间”概念(ext4/xfs 有 crtime 但非 POSIX 标准,APFS 有但不可靠),stat 结构体里只有 st_mtime、st_atime、st_ctime(后者是状态变更时间,不是创建时间)。强行封装一个跨平台 creation_time 函数,大概率在非 Windows 平台返回错误值或抛异常。
立即学习“C++免费学习笔记(深入)”;
更务实的做法:
- 明确业务是否真强依赖创建时间(例如日志归档、审计合规);如果不是,用
last_write_time更稳妥 - 若必须支持,Windows 走
GetFileTime,其他平台 fallback 到last_write_time并加注释说明“非真正创建时间” - 避免在模板或泛型逻辑里假设
creation_time存在,会导致 Linux CI 编译失败或运行时 panic
一个小而完整的 Windows 创建时间读取示例
#include <windows.h>
#include <filesystem>
#include <chrono>
<p>std::optional<std::filesystem::file_time_type> get_creation_time(const std::filesystem::path& p) {
HANDLE h = CreateFileW(p.c_str(), GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (h == INVALID_HANDLE_VALUE) return std::nullopt;</p><pre class="brush:php;toolbar:false;">FILETIME ft_create, ft_access, ft_write;
if (!GetFileTime(h, &ft_create, &ft_access, &ft_write)) {
CloseHandle(h);
return std::nullopt;
}
CloseHandle(h);
// FILETIME → uint64_t → 100ns ticks since 1601 → convert to file_clock
uint64_t ft_int = (static_cast<uint64_t>(ft_create.dwHighDateTime) << 32) |
ft_create.dwLowDateTime;
// Windows file_clock epoch is 1601-01-01 UTC, same as FILETIME
auto tp = std::chrono::file_clock::time_point(
std::chrono::duration_cast<std::chrono::file_clock::duration>(
std::chrono::nanoseconds(ft_int * 100)
)
);
return tp;}
注意:std::chrono::file_clock 在 MSVC 中已映射到 Windows FILETIME,但 GCC/Clang on Windows 可能尚未完全实现,此时应改用 system_clock + 时区校正,或直接返回 FILETIME 原始值供上层判断。
最常被忽略的一点:NTFS 卷上的创建时间在文件复制、移动、解压等操作中可能被重置(取决于工具实现),它并不像修改时间那样具有强语义保证。别把它当唯一可信的时间戳用。


















