c++oding="utf-8" ?>
std::filesystem::last_write_time 返回的是 std::filesystem::file_time_type,不是 time_t;它基于独立高精度时钟,需用 clock_cast 转 system_clock 或降级为秒级时间戳再转 time_t。

std::filesystem::last_write_time 返回的是 time_t 还是 file_time_type?
返回的是 std::filesystem::file_time_type,不是 time_t。直接强转或传给 std::ctime 会编译失败或结果错误。这是最常踩的坑——误以为它和 C 风格时间一样。
原因在于 C++20 的 std::filesystem 使用独立的时钟类型(通常基于系统高精度时钟),和 std::chrono::system_clock 不兼容,也不能直接用 std::time_t 表示。
- 必须通过
std::filesystem::file_time_type::clock转换到std::chrono::system_clock(需调用std::chrono::clock_cast) - 或者降级为秒级时间戳再转
time_t(更常用、兼容性更好) - C++20 起支持
clock_cast,但部分旧标准库(如 libstdc++
怎么把 last_write_time 转成可读的字符串(如 "2024-05-22 14:30:15")?
推荐用秒级截断 + std::strftime,稳定且跨平台。不要试图用 std::format 直接格式化 file_time_type(C++20 std::format 对文件时间的支持仍不完善)。
#include <filesystem>
#include <chrono>
#include <ctime>
#include <iostream>
namespace fs = std::filesystem;
fs::path p = "test.txt";
if (fs::exists(p)) {
auto ftime = fs::last_write_time(p);
// 截断到秒,转为 time_t
auto s = std::chrono::time_point_cast<:chrono::seconds>(ftime).time_since_epoch().count();
auto ctime = static_cast<:time_t>(s);
char buf[64];
std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&ctime));
std::cout
<ul>
<li>用 <code>time_point_cast<seconds></seconds></code> 是为了丢弃纳秒/百纳秒部分,避免 <code>localtime</code> 处理溢出</li>
<li>
<code>std::localtime</code> 是线程不安全的,生产环境应改用 <code>std::localtime_r</code>(POSIX)或 <code>std::chrono::zoned_time</code>(C++20)</li>
<li>Windows 上注意 <code>std::filesystem</code> 需要 /std:c++20 和启用 Unicode(否则路径含中文可能失败)</li>
</ul>
<h3>为什么在 Windows 上获取的时间比资源管理器显示的慢 1 秒?</h3>
<p>不是代码问题,是 Windows 文件系统(NTFS)本身的精度限制:<code>last_write_time</code> 存储粒度为 100 纳秒,但某些 API 或驱动层会向下取整到最近的秒——尤其当文件由旧工具(如批处理 <code>copy</code>)修改时。</p>
<ul>
<li>用 PowerShell <code>(Get-Item "x.txt").LastWriteTime</code> 对比验证,如果也差 1 秒,就是系统行为,不是 <code>std::filesystem</code> bug</li>
<li>若需更高精度(如判断是否“刚刚”修改),建议用 <code>file_time_type::time_since_epoch()</code> 做纳秒级差值比较,而非转成字符串</li>
<li>Linux(ext4/xfs)通常能保持微秒级精度,但也要注意挂载选项(如 <code>noatime</code> 不影响 <code>last_write_time</code>)</li>
</ul>
<h3>跨平台编译时 missing last_write_time 怎么办?</h3>
<p>常见于没开 C++20 或没链接对应库。GCC 11+、Clang 12+、MSVC 2019 16.10+ 才完整支持 <code>std::filesystem</code>;且 GCC 需要链接 <code>-lstdc++fs</code>(Clang/MSVC 自动处理)。</p>
<ul>
<li>编译命令加 <code>-std=c++20</code>(不能只写 <code>c++17</code>)</li>
<li>GCC 用户务必加 <code>-lstdc++fs</code>,否则链接时报错:undefined reference to <code>std::filesystem::last_write_time</code>
</li>
<li>检查头文件是否用了 <code>#include <filesystem></filesystem></code>(不是 <code><experimental></experimental></code>,后者已废弃)</li>
<li>CMake 中推荐用 <code>target_link_libraries(myapp PRIVATE stdc++fs)</code> 并设置 <code>set(CMAKE_CXX_STANDARD 20)</code>
</li>
</ul>
Windows 下时区、精度、链接选项这三块最容易漏,尤其从旧项目迁移时。别信“只要包含头文件就能用”的直觉。</:time_t></:chrono::seconds></iostream></ctime></chrono></filesystem>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











