我正在尝试使用 C++20 读取文件的上次修改日期/时间并将其转换为纳秒(我猜微秒也足够了)。
这是我的尝试:
int main() {
std::filesystem::path myFile("D:\\myfile.png");
if (std::filesystem::exists(myFile)) {
std::filesystem::file_time_type ftime = std::filesystem::last_write_time(myFile);
auto epoch = ftime.time_since_epoch();
auto nano = std::chrono::duration_cast<std::chrono::nanoseconds>(epoch).count();
const auto systemTime = std::chrono::clock_cast<std::chrono::system_clock>(ftime);
const auto time = std::chrono::system_clock::to_time_t(systemTime);
std::cout << std::format("ftime: {}\nepoch: {}\nnano: {}\nsystemtime: {}\ntime: {}\n", ftime, epoch, nano, systemTime, time);
}
else {
std::cerr << "File does not exist." << std::endl;
}
return 0;
}
输出为:
ftime: 2021-11-15 08:54:38.5861611
epoch: 132814400785861611[1/10000000]s
nano: -5165303995123390516
systemtime: 2021-11-15 08:54:38.5861611
time: 1636966478
ftime
是文件所示的正确时间epoch
和 nano
是无效日期。systemTime
好像又转换回来了?但在调试器中,systemTime
似乎具有正确的值(“16369664785861611”)time
是最接近的,但不够精确。遗憾的是,我无法理解如何使用
std::chrono
的转换以及正确的语法是什么,所以我希望得到一些帮助来找出我错在哪里。
Windows 文件时间使用的纪元不是 UNIX 纪元。 Windows 文件时间使用 1601 年 1 月 1 日午夜 UTC 的纪元,而不是使用 1970 年 1 月 1 日午夜 UTC 的 UNIX 纪元。
这意味着 Windows 上
std::filesystem::file_time_type
的纪元不是 UNIX 纪元,因此您的 time_since_epoch
调用返回的是自 Windows 文件纪元以来的时间,而不是 UNIX 纪元。
当您执行
clock_cast
时,时间会调整为 UNIX 纪元,因为这就是 std::chrono::system_clock
使用的内容。这意味着获取自 systemTime
time_point
纪元以来的纳秒计数应该会给您想要的答案:
auto timeSinceUnixEpoch = systemTime.time_since_epoch();
uint64_t nanosSinceUnixEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(timeSinceUnixEpoch).count();
请记住,您不会获得完整的纳秒精度,因为 NTFS 以 100 纳秒的精度存储时间。