A while ago, I managed to do this, to go from filesystem to system clocks, thanks to SO:
int64_t toUSsecSinceEpochUTC(std::filesystem::file_time_type ftime) {
// see https://stackoverflow.com/a/35282833/103724
using namespace std::chrono;
auto sys_now = system_clock::now();
auto fil_now = decltype(ftime)::clock::now(); // i.e. C++20's file_clock
auto sys_ftime = time_point_cast<system_clock::duration>(ftime - fil_now + sys_now);
auto sys_ftime_usec = time_point_cast<microseconds>(sys_ftime);
return sys_ftime_usec.time_since_epoch().count();
}
But now I want to do the reverse, and I'm struggling... here's my feeble attempt:
std::filesystem::file_time_type fromUSsecSinceEpochUTC(int64_t usec_utc) {
std::filesystem::file_time_type ftime;
using namespace std::chrono;
auto sys_now = system_clock::now();
auto fil_now = decltype(ftime)::clock::now(); // i.e. C++20's file_clock
std::chrono::microseconds usec(usec_utc);
ftime = ????
return ftime;
}
MSVC2019 complains on auto res = sys_now - usec + fil_now;
with
error C2676: binary '+': 'std::chrono::time_point<std::chrono::system_clock,std::chrono::duration<std::chrono::system_clock::rep,std::chrono::system_clock::period>>' does not define this operator or a conversion to a type acceptable to the predefined operator
i.e. the code from https://stackoverflow.com/a/35282833/103724 between steady and system clocks does not appear to work for the filesystem clock. Although it could be just me not following.
Any <chrono>
expert who might be able to help?
To fill out fromUSsecSinceEpochUTC
you would:
std::filesystem::file_time_type
fromUSsecSinceEpochUTC(int64_t usec_utc) {
std::filesystem::file_time_type ftime;
using namespace std::chrono;
auto sys_now = system_clock::now();
auto fil_now = decltype(ftime)::clock::now(); // i.e. C++20's file_clock
microseconds usec(usec_utc);
time_point<system_clock, microseconds> tp_sys{usec};
return tp_sys - sys_now + fil_now;
}
That being said, the relationship between the epoch of system_clock
and file_clock
is going to be a constant. I believe the Windows file_clock
epoch is 1601-01-01 00:00:00 UTC. The difference between that and the system_clock
epoch (1970-01-01 00:00:00 UTC) is 13,4774 days or 3'234'576h
.
This knowledge allows you to write conversions (for Windows) without calls to now()
.
std::filesystem::file_time_type
to_file_time(std::chrono::system_clock::time_point sys_tp)
{
using namespace std::literals;
return std::filesystem::file_time_type{sys_tp.time_since_epoch() + 3'234'576h};
}
std::chrono::system_clock::time_point
to_sys_time(std::filesystem::file_time_type f_tp)
{
using namespace std::literals;
return std::chrono::system_clock::time_point{f_tp.time_since_epoch() - 3'234'576h};
}
Above I've taken advantage of the a-prior knowledge that file_clock::duration
is the same type as system_clock::duration
on Windows. Add casts as necessary or desired.