time/FileTime: add ChronoToFileTime()

This commit is contained in:
Max Kellermann 2021-08-10 16:09:03 +02:00
parent 45354a421c
commit d7e7adb496
2 changed files with 53 additions and 0 deletions

View File

@ -53,6 +53,21 @@ ToInt64(FILETIME ft) noexcept
return ToUint64(ft); return ToUint64(ft);
} }
constexpr FILETIME
ToFileTime(uint_least64_t t) noexcept
{
FILETIME ft{};
ft.dwLowDateTime = DWORD(t);
ft.dwHighDateTime = DWORD(t >> 32);
return ft;
}
constexpr FILETIME
ToFileTime(int_least64_t t) noexcept
{
return ToFileTime(uint_least64_t(t));
}
/* "A file time is a 64-bit value that represents the number of /* "A file time is a 64-bit value that represents the number of
100-nanosecond intervals" 100-nanosecond intervals"
https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times */ https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times */
@ -104,6 +119,40 @@ FileTimeToChrono(FILETIME ft) noexcept
return unix_epoch + sys_duration; return unix_epoch + sys_duration;
} }
constexpr FILETIME
ToFileTime(FileTimeDuration d) noexcept
{
return ToFileTime(d.count());
}
constexpr FILETIME
UnixEpochDurationToFileTime(FileTimeDuration d) noexcept
{
/**
* 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 ToFileTime(d + windows_unix_delta);
}
inline FILETIME
ChronoToFileTime(std::chrono::system_clock::time_point tp) noexcept
{
/* this is guaranteed to be 0 in C++20 */
const auto unix_epoch = std::chrono::system_clock::from_time_t(0);
const auto since_unix_epoch = tp - unix_epoch;
const auto ft_since_unix_epoch =
std::chrono::duration_cast<FileTimeDuration>(since_unix_epoch);
return UnixEpochDurationToFileTime(ft_since_unix_epoch);
}
constexpr std::chrono::seconds constexpr std::chrono::seconds
DeltaFileTimeS(FILETIME a, FILETIME b) noexcept DeltaFileTimeS(FILETIME a, FILETIME b) noexcept
{ {

View File

@ -49,4 +49,8 @@ TEST(Time, FileTimeToChrono)
ASSERT_EQ(stat(".", &st), 0); ASSERT_EQ(stat(".", &st), 0);
ASSERT_EQ(std::chrono::system_clock::to_time_t(tp), st.st_mtime); ASSERT_EQ(std::chrono::system_clock::to_time_t(tp), st.st_mtime);
const auto ft2 = ChronoToFileTime(std::chrono::system_clock::from_time_t(st.st_mtime));
const auto tp2 = FileTimeToChrono(ft2);
ASSERT_EQ(std::chrono::system_clock::to_time_t(tp2), st.st_mtime);
} }