将 std::filesystem::file_time_type 转换为纪元纳秒?

问题描述 投票:0回答:1

我正在尝试使用 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
的转换以及正确的语法是什么,所以我希望得到一些帮助来找出我错在哪里。

c++ casting c++-chrono
1个回答
0
投票

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 纳秒的精度存储时间。

© www.soinside.com 2019 - 2024. All rights reserved.