From e442f4f502ad0f8d7625ea6defccc9ff2f991713 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 21 Oct 2024 12:49:08 +0200 Subject: [PATCH] chrono: add to_system() variants for Windows Signed-off-by: Simon Rozman --- include/stdex/chrono.hpp | 89 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/include/stdex/chrono.hpp b/include/stdex/chrono.hpp index b22ad23ba..77c06817a 100644 --- a/include/stdex/chrono.hpp +++ b/include/stdex/chrono.hpp @@ -99,6 +99,49 @@ namespace stdex { } #endif +#ifdef _WIN32 + /// + /// Converts time point to SYSTEMTIME + /// + static void to_system(_In_ time_point tp, _Out_ SYSTEMTIME& t) + { + uint8_t day, month; + int32_t year; + to_dmy(tp, &day, &month, &year); + t.wDay = day; + t.wMonth = month; + if (year > WORD_MAX) _Unlikely_ + throw std::range_error("year too big"); + t.wYear = static_cast(year); + t.wDayOfWeek = static_cast(day_of_week(tp) + 1) % 7; + t.wHour = 0; + t.wMinute = 0; + t.wSecond = 0; + t.wMilliseconds = 0; + } + + /// + /// Returns time point from FILETIME + /// + static void to_system(_In_ time_point tp, _Out_ FILETIME& t) noexcept + { + uint64_t x = (tp.time_since_epoch().count() - 2305814) * 864000000000; // Adjust epoch and convert 1-day interval to 100 ns + t.dwHighDateTime = static_cast(x >> 32); + t.dwLowDateTime = static_cast(x & 0xffffffff); + } + + /// + /// Returns time point from DATE + /// + static void to_system(_In_ time_point tp, _Out_ DATE& t) + { + SYSTEMTIME st; + to_system(tp, st); + if (!SystemTimeToVariantTime(&st, &t)) + throw std::invalid_argument("failed to convert date to VARIANT_DATE"); + } +#endif + /// /// Returns time point from calendar day, month and year /// @@ -277,6 +320,52 @@ namespace stdex { date.tm_isdst = 0; } +#ifdef _WIN32 + /// + /// Converts time point to SYSTEMTIME + /// + static void to_system(_In_ time_point tp, _Out_ SYSTEMTIME& t) + { + uint8_t day, month, hour, minute, second; + uint16_t millisecond; + int32_t year; + to_dmy(tp, + &day, &month, &year, + &hour, &minute, &second, &millisecond); + t.wDay = day; + t.wMonth = month; + if (year > WORD_MAX) _Unlikely_ + throw std::range_error("year too big"); + t.wYear = static_cast(year); + t.wDayOfWeek = (static_cast(aosn_date::day_of_week(to_date(tp))) + 1) % 7; + t.wHour = hour; + t.wMinute = minute; + t.wSecond = second; + t.wMilliseconds = millisecond; + } + + /// + /// Returns time point from FILETIME + /// + static void to_system(_In_ time_point tp, _Out_ FILETIME& t) noexcept + { + uint64_t x = (tp.time_since_epoch().count() - 199222329600000) * 10000; // Adjust epoch and convert 1 ms interval to 100 ns + t.dwHighDateTime = static_cast(x >> 32); + t.dwLowDateTime = static_cast(x & 0xffffffff); + } + + /// + /// Returns time point from DATE + /// + static void to_system(_In_ time_point tp, _Out_ DATE& t) + { + SYSTEMTIME st; + to_system(tp, st); + if (!SystemTimeToVariantTime(&st, &t)) + throw std::invalid_argument("failed to convert date to VARIANT_DATE"); + } +#endif + /// /// Returns aosn_date::time_point from time point ///