chrono: finish AOsn date and time-stamp implementations
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
55d39b1566
commit
e28c61e431
@ -14,28 +14,19 @@
|
|||||||
namespace stdex {
|
namespace stdex {
|
||||||
namespace chrono
|
namespace chrono
|
||||||
{
|
{
|
||||||
struct aosn_clock
|
///
|
||||||
|
/// AOsn date
|
||||||
|
///
|
||||||
|
struct aosn_date
|
||||||
{
|
{
|
||||||
using rep = int64_t;
|
using rep = int32_t;
|
||||||
using period = std::ratio<1, 1'000'000>; // 1 microsecond
|
using period = std::ratio<86400>; // 1 day
|
||||||
using duration = std::chrono::duration<rep, period>;
|
using duration = std::chrono::duration<rep, period>;
|
||||||
using time_point = std::chrono::time_point<aosn_clock>;
|
using time_point = std::chrono::time_point<aosn_date>;
|
||||||
static constexpr bool is_steady = false;
|
static constexpr bool is_steady = false;
|
||||||
|
|
||||||
static constexpr rep f_second = 1000; // number of milliseconds per second
|
|
||||||
static constexpr rep f_minute = 60; // number of seconds per minute
|
|
||||||
static constexpr rep f_hour = 60; // number of minutes na hour
|
|
||||||
static constexpr rep f_day = 24; // number of hours na day
|
|
||||||
static constexpr rep f_week = 7; // number of days per week
|
|
||||||
|
|
||||||
static constexpr rep second = f_second; // number of milliseconds per second
|
|
||||||
static constexpr rep minute = f_minute * second; // number of milliseconds per minute
|
|
||||||
static constexpr rep hour = f_hour * minute; // number of milliseconds per hour
|
|
||||||
static constexpr rep day = f_day * hour; // number of milliseconds per day
|
|
||||||
static constexpr rep week = f_week * day; // number of milliseconds per week
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Gets current time
|
/// Gets current date
|
||||||
///
|
///
|
||||||
static time_point now() noexcept
|
static time_point now() noexcept
|
||||||
{
|
{
|
||||||
@ -50,23 +41,64 @@ namespace stdex {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t now_jul(_Out_opt_ uint32_t* hour = nullptr) noexcept
|
///
|
||||||
|
/// Returns time_t from time point
|
||||||
|
///
|
||||||
|
static __time64_t to_time_t(_In_ const time_point tp) noexcept
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
return static_cast<__time64_t>(tp.time_since_epoch().count()) * 86400 - 210866803200;
|
||||||
SYSTEMTIME t;
|
|
||||||
GetSystemTime(&t);
|
|
||||||
duration tp = from_system(t).time_since_epoch();
|
|
||||||
#else
|
|
||||||
struct timespec t;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t);
|
|
||||||
duration tp = from_system(t).time_since_epoch();
|
|
||||||
#endif
|
|
||||||
if (hour)
|
|
||||||
*hour = (uint32_t)(tp.count() % day);
|
|
||||||
return (uint32_t)(tp.count() / day);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t gre2jul(_In_ uint8_t day, _In_ uint8_t month, _In_ int32_t year) noexcept
|
///
|
||||||
|
/// Returns time point from time_t
|
||||||
|
///
|
||||||
|
static time_point from_time_t(_In_ __time64_t t) noexcept
|
||||||
|
{
|
||||||
|
return time_point(duration(static_cast<rep>((t + 210866803200) / 86400)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
///
|
||||||
|
/// Returns time point from SYSTEMTIME
|
||||||
|
///
|
||||||
|
static time_point from_system(_In_ const SYSTEMTIME& t) noexcept
|
||||||
|
{
|
||||||
|
return from_dmy(static_cast<uint8_t>(t.wDay), static_cast<uint8_t>(t.wMonth), static_cast<int32_t>(t.wYear));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from FILETIME
|
||||||
|
///
|
||||||
|
static time_point from_system(_In_ const FILETIME& t) noexcept
|
||||||
|
{
|
||||||
|
uint64_t x = ((static_cast<uint64_t>(t.dwHighDateTime)) << 32) | t.dwLowDateTime;
|
||||||
|
return time_point(duration(static_cast<rep>(x / 86400000 + 2305814))); // Convert from 100 ns to 1-day interval and adjust epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from DATE
|
||||||
|
///
|
||||||
|
static time_point from_system(_In_ DATE t)
|
||||||
|
{
|
||||||
|
SYSTEMTIME st;
|
||||||
|
if (!VariantTimeToSystemTime(t, &st))
|
||||||
|
throw std::invalid_argument("failed to convert date from VARIANT_DATE");
|
||||||
|
return from_system(st);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
///
|
||||||
|
/// Returns time point from struct timespec
|
||||||
|
///
|
||||||
|
static time_point from_system(_In_ const struct timespec& t) noexcept
|
||||||
|
{
|
||||||
|
return from_time_t(t.tv_sec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from calendar day, month and year
|
||||||
|
///
|
||||||
|
static time_point from_dmy(_In_ uint8_t day, _In_ uint8_t month, _In_ int32_t year) noexcept
|
||||||
{
|
{
|
||||||
int32_t mtmp, ytmp;
|
int32_t mtmp, ytmp;
|
||||||
if (month > 2) {
|
if (month > 2) {
|
||||||
@ -77,19 +109,20 @@ namespace stdex {
|
|||||||
mtmp = month + 9;
|
mtmp = month + 9;
|
||||||
ytmp = year - 1;
|
ytmp = year - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ctmp = (ytmp / 100);
|
int32_t ctmp = (ytmp / 100);
|
||||||
int32_t dtmp = ytmp - (100 * ctmp);
|
int32_t dtmp = ytmp - (100 * ctmp);
|
||||||
int32_t result1 = 146097L * ctmp / 4;
|
int32_t result1 = 146097L * ctmp / 4;
|
||||||
int32_t result2 = (1461 * dtmp) / 4;
|
int32_t result2 = (1461 * dtmp) / 4;
|
||||||
int32_t result3 = (153 * mtmp + 2) / 5;
|
int32_t result3 = (153 * mtmp + 2) / 5;
|
||||||
|
return time_point(duration(static_cast<int32_t>(result1) + day + result2 + 1721119L + result3));
|
||||||
return (int32_t)result1 + day + result2 + 1721119L + result3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jul2gre(_In_ int32_t jul, _Out_opt_ uint8_t* day, _Out_opt_ uint8_t* month, _Out_opt_ int32_t* year) noexcept
|
///
|
||||||
|
/// Returns calendar day, month and year from time point
|
||||||
|
///
|
||||||
|
static void to_dmy(_In_ const time_point tp, _Out_opt_ uint8_t* day, _Out_opt_ uint8_t* month, _Out_opt_ int32_t* year) noexcept
|
||||||
{
|
{
|
||||||
int32_t mtmp = jul - 1721119L;
|
int32_t mtmp = tp.time_since_epoch().count() - 1721119L;
|
||||||
int32_t yr = (4 * mtmp - 1) / 146097L;
|
int32_t yr = (4 * mtmp - 1) / 146097L;
|
||||||
mtmp = 4 * mtmp - 1 - 146097L * yr;
|
mtmp = 4 * mtmp - 1 - 146097L * yr;
|
||||||
int32_t da = mtmp / 4;
|
int32_t da = mtmp / 4;
|
||||||
@ -100,43 +133,112 @@ namespace stdex {
|
|||||||
da = 5 * da - 3 - 153 * mo;
|
da = 5 * da - 3 - 153 * mo;
|
||||||
da = (da + 5) / 5;
|
da = (da + 5) / 5;
|
||||||
yr = 100 * yr + mtmp;
|
yr = 100 * yr + mtmp;
|
||||||
|
|
||||||
if (mo < 10)
|
if (mo < 10)
|
||||||
mo += 3;
|
mo += 3;
|
||||||
else {
|
else {
|
||||||
mo -= 9;
|
mo -= 9;
|
||||||
yr++;
|
yr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (day) *day = static_cast<uint8_t>(da);
|
if (day) *day = static_cast<uint8_t>(da);
|
||||||
if (month) *month = static_cast<uint8_t>(mo);
|
if (month) *month = static_cast<uint8_t>(mo);
|
||||||
if (year) *year = yr;
|
if (year) *year = yr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __time64_t to_time_t(_In_ const time_point& tp) noexcept
|
///
|
||||||
|
/// Returns day-of-week from time point (0 = Mon, 1 = Tue...)
|
||||||
|
///
|
||||||
|
static uint8_t day_of_week(_In_ const time_point tp)
|
||||||
{
|
{
|
||||||
return tp.time_since_epoch().count() / second - 210866803200;
|
return static_cast<uint8_t>(tp.time_since_epoch().count() % 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns day-of-week from calendar day, month and year (0 = Mon, 1 = Tue...)
|
||||||
|
///
|
||||||
|
static uint8_t day_of_week(_In_ uint8_t day, _In_ uint8_t month, _In_ int32_t year)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(from_dmy(day, month, year).time_since_epoch().count() % 7);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// AOsn timestamp
|
||||||
|
///
|
||||||
|
struct aosn_timestamp
|
||||||
|
{
|
||||||
|
using rep = int64_t;
|
||||||
|
using period = std::ratio<1, 1'000'000>; // 1 microsecond
|
||||||
|
using duration = std::chrono::duration<rep, period>;
|
||||||
|
using time_point = std::chrono::time_point<aosn_timestamp>;
|
||||||
|
static constexpr bool is_steady = false;
|
||||||
|
|
||||||
|
static constexpr rep f_second = 1000; // number of milliseconds per second
|
||||||
|
static constexpr rep f_minute = 60; // number of seconds per minute
|
||||||
|
static constexpr rep f_hour = 60; // number of minutes per hour
|
||||||
|
static constexpr rep f_day = 24; // number of hours per day
|
||||||
|
static constexpr rep f_week = 7; // number of days per week
|
||||||
|
|
||||||
|
static constexpr rep p_second = f_second; // number of milliseconds per second
|
||||||
|
static constexpr rep p_minute = f_minute * p_second; // number of milliseconds per minute
|
||||||
|
static constexpr rep p_hour = f_hour * p_minute; // number of milliseconds per hour
|
||||||
|
static constexpr rep p_day = f_day * p_hour; // number of milliseconds per day
|
||||||
|
static constexpr rep p_week = f_week * p_day; // number of milliseconds per week
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets current timestamp
|
||||||
|
///
|
||||||
|
static time_point now() noexcept
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
FILETIME t;
|
||||||
|
GetSystemTimeAsFileTime(&t);
|
||||||
|
return from_system(t);
|
||||||
|
#else
|
||||||
|
time_t t;
|
||||||
|
time(&t);
|
||||||
|
return from_time_t(t);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time_t from time point
|
||||||
|
///
|
||||||
|
static __time64_t to_time_t(_In_ const time_point tp) noexcept
|
||||||
|
{
|
||||||
|
return tp.time_since_epoch().count() / p_second - 210866803200;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from time_t
|
||||||
|
///
|
||||||
static time_point from_time_t(_In_ __time64_t t) noexcept
|
static time_point from_time_t(_In_ __time64_t t) noexcept
|
||||||
{
|
{
|
||||||
return time_point(duration(((rep)t + 210866803200) * second));
|
return time_point(duration((static_cast<rep>(t) + 210866803200) * p_second));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
///
|
||||||
|
/// Returns time point from SYSTEMTIME
|
||||||
|
///
|
||||||
static time_point from_system(_In_ const SYSTEMTIME& t) noexcept
|
static time_point from_system(_In_ const SYSTEMTIME& t) noexcept
|
||||||
{
|
{
|
||||||
return time_point(duration(
|
return from_dmy(
|
||||||
((rep)gre2jul((uint8_t)t.wDay, (uint8_t)t.wMonth, (int32_t)t.wYear)) * day +
|
static_cast<uint8_t>(t.wDay), static_cast<uint8_t>(t.wMonth), static_cast<int32_t>(t.wYear),
|
||||||
((rep)t.wHour * hour + (rep)t.wMinute * minute + (rep)t.wSecond * second + t.wMilliseconds)));
|
static_cast<uint8_t>(t.wHour), static_cast<uint8_t>(t.wMinute), static_cast<uint8_t>(t.wSecond), static_cast<uint16_t>(t.wMilliseconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from FILETIME
|
||||||
|
///
|
||||||
static time_point from_system(_In_ const FILETIME& t) noexcept
|
static time_point from_system(_In_ const FILETIME& t) noexcept
|
||||||
{
|
{
|
||||||
rep x = (((rep)t.dwHighDateTime) << 32) | t.dwLowDateTime;
|
rep x = ((static_cast<rep>(t.dwHighDateTime)) << 32) | t.dwLowDateTime;
|
||||||
return time_point(duration(x / 10000 + 199222329600000)); // Convert from 100 ns to 1 ms interval and adjust epoch
|
return time_point(duration(x / 10000 + 199222329600000)); // Convert from 100 ns to 1 ms interval and adjust epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from DATE
|
||||||
|
///
|
||||||
static time_point from_system(_In_ DATE t)
|
static time_point from_system(_In_ DATE t)
|
||||||
{
|
{
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
@ -145,11 +247,60 @@ namespace stdex {
|
|||||||
return from_system(st);
|
return from_system(st);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
///
|
||||||
|
/// Returns time point from struct timespec
|
||||||
|
///
|
||||||
static time_point from_system(_In_ const struct timespec& t) noexcept
|
static time_point from_system(_In_ const struct timespec& t) noexcept
|
||||||
{
|
{
|
||||||
return from_time_t(t.tv_sec) + t.tv_nsec / 1000;
|
return from_time_t(t.tv_sec) + t.tv_nsec / 1000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns aosn_date::time_point from time point
|
||||||
|
///
|
||||||
|
static aosn_date::time_point to_date(_In_ time_point tp) noexcept
|
||||||
|
{
|
||||||
|
return aosn_date::time_point(aosn_date::duration(static_cast<aosn_date::rep>(tp.time_since_epoch().count() / p_day)));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from aosn_date::time_point
|
||||||
|
///
|
||||||
|
static time_point from_date(_In_ aosn_date::time_point date) noexcept
|
||||||
|
{
|
||||||
|
return time_point(duration(static_cast<rep>(date.time_since_epoch().count()) * p_day));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns time point from calendar day, month, year and time
|
||||||
|
///
|
||||||
|
static time_point from_dmy(
|
||||||
|
_In_ uint8_t day, _In_ uint8_t month, _In_ int32_t year,
|
||||||
|
_In_ uint8_t hour, _In_ uint8_t minute, _In_ uint8_t second, _In_ uint16_t millisecond) noexcept
|
||||||
|
{
|
||||||
|
return time_point(duration(
|
||||||
|
(static_cast<rep>(aosn_date::from_dmy(day, month, year).time_since_epoch().count()) * p_day) +
|
||||||
|
(static_cast<rep>(hour) * p_hour + static_cast<rep>(minute) * p_minute + static_cast<rep>(second) * p_second + millisecond)));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns calendar day, month, year and time from time point
|
||||||
|
///
|
||||||
|
static void to_dmy(_In_ const time_point tp,
|
||||||
|
_Out_opt_ uint8_t* day, _Out_opt_ uint8_t* month, _Out_opt_ int32_t* year,
|
||||||
|
_Out_opt_ uint8_t* hour, _Out_opt_ uint8_t* minute, _Out_opt_ uint8_t* second, _Out_opt_ uint16_t* millisecond) noexcept
|
||||||
|
{
|
||||||
|
aosn_date::to_dmy(to_date(tp), day, month, year);
|
||||||
|
int32_t u = static_cast<int32_t>(tp.time_since_epoch().count() % p_day);
|
||||||
|
if (millisecond) *millisecond = static_cast<uint16_t>(u % f_second);
|
||||||
|
u = u / f_second;
|
||||||
|
if (second) *second = static_cast<uint8_t>(u % f_minute);
|
||||||
|
u = u / f_minute;
|
||||||
|
if (minute) *minute = static_cast<uint8_t>(u % f_hour);
|
||||||
|
u = u / f_hour;
|
||||||
|
if (hour) *hour = static_cast<uint8_t>(u);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user