time/FileTime: preserve the FILETIME resolution
Don't truncate the FILETIME to second resolution to pass it to std::chrono::system_clock::from_time_t(); instead, calculate the offset between the FILETIME epoch and the std::system_clock::time_point epoch, and use that to initialize the time_point directly.
This commit is contained in:
parent
9fc3c60910
commit
45354a421c
@ -71,17 +71,37 @@ FileTimeToChronoDuration(FILETIME ft) noexcept
|
|||||||
return FileTimeDuration(ToInt64(ft));
|
return FileTimeDuration(ToInt64(ft));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr time_t
|
/**
|
||||||
FileTimeToTimeT(FILETIME ft) noexcept
|
* Calculate a std::chrono::duration specifying the duration between
|
||||||
|
* the unix epoch and the given FILETIME.
|
||||||
|
*/
|
||||||
|
constexpr auto
|
||||||
|
FileTimeToUnixEpochDuration(FILETIME ft) noexcept
|
||||||
{
|
{
|
||||||
return (ToInt64(ft) - 116444736000000000) / 10000000;
|
/**
|
||||||
|
* The number of days between the Windows FILETIME epoch
|
||||||
|
* (1601-01-01T00:00) and the Unix epoch (1970-01-01T00:00).
|
||||||
|
*/
|
||||||
|
constexpr int_least64_t windows_unix_days = 134774;
|
||||||
|
constexpr int_least64_t windows_unix_hours = windows_unix_days * 24;
|
||||||
|
|
||||||
|
constexpr FileTimeDuration windows_unix_delta{std::chrono::hours{windows_unix_hours}};
|
||||||
|
|
||||||
|
return FileTimeToChronoDuration(ft) - windows_unix_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::chrono::system_clock::time_point
|
inline std::chrono::system_clock::time_point
|
||||||
FileTimeToChrono(FILETIME ft) noexcept
|
FileTimeToChrono(FILETIME ft) noexcept
|
||||||
{
|
{
|
||||||
// TODO: eliminate the time_t roundtrip, preserve sub-second resolution
|
/* this is guaranteed to be 0 in C++20 */
|
||||||
return std::chrono::system_clock::from_time_t(FileTimeToTimeT(ft));
|
const auto unix_epoch = std::chrono::system_clock::from_time_t(0);
|
||||||
|
|
||||||
|
const auto windows_duration = FileTimeToUnixEpochDuration(ft);
|
||||||
|
const auto sys_duration =
|
||||||
|
std::chrono::duration_cast<std::chrono::system_clock::duration>
|
||||||
|
(windows_duration);
|
||||||
|
|
||||||
|
return unix_epoch + sys_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::chrono::seconds
|
constexpr std::chrono::seconds
|
||||||
|
Loading…
Reference in New Issue
Block a user