C++17でファイルのタイムスタンプを取得する
c++17においてstd::filesystemが追加され、boostに頼らなくてもよくなったので使ってみた。boost::filesystemはコンパイルが必要なので、標準になったのはいいものの糞仕様にはまったので、メモ。
環境はMicrosoft Visual Studio Community 2019 Version 16.7.5
- utils.h
#pragma once #include <chrono> #include <filesystem> #include <string> // std::filesystem::file_time_typeのtime_since_epoch()を調整するバイアス。 extern const std::chrono::system_clock::time_point gEpochTimeBias; std::string timestamp(const std::filesystem::path& path, const std::string& fmt = "%Y-%m-%d %H:%M:%S");
- utils.cpp
#include <sstream> #include "utils.h" using namespace std; // std::filesystem::file_time_typeのtime_since_epoch()が369年ずれるので、調整するバイアス。 // c++20になれば解決しているといいね。 const chrono::system_clock::time_point gEpochTimeBias = chrono::time_point_cast<chrono::system_clock::duration>( chrono::system_clock::now() - filesystem::file_time_type::clock::now().time_since_epoch()); string timestamp(const filesystem::path& path, const string& fmt) { filesystem::file_time_type time_ftt = filesystem::last_write_time(path); chrono::time_point sctp = chrono::time_point_cast<chrono::system_clock::duration>(time_ftt.time_since_epoch() + gEpochTimeBias); const time_t time_tt = chrono::system_clock::to_time_t(sctp); struct tm time_tm; localtime_s(&time_tm, &time_tt); stringstream ss; ss << put_time(&time_tm, fmt.c_str()); return ss.str(); }
- main.cpp
#include <iostream> #include "utils.h" using namespace std; int main() { string path = "utils.h"; string time_tm = timestamp(path); cout << time_tm << endl; }