stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
chrono.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023 Amebis
4*/
5
6#pragma once
7
8#include "sal.hpp"
9#include <stdint.h>
10#ifdef _WIN32
11#include <windows.h>
12#endif
13#include <chrono>
14#include <stdexcept>
15
16namespace stdex {
17 namespace chrono
18 {
20 {
21 using rep = int64_t;
22 using period = std::ratio<1, 1'000'000>; // 1 microsecond
23 using duration = std::chrono::duration<rep, period>;
24 using time_point = std::chrono::time_point<aosn_clock>;
25 static constexpr bool is_steady = false;
26
27 static constexpr rep f_second = 1000; // number of milliseconds per second
28 static constexpr rep f_minute = 60; // number of seconds per minute
29 static constexpr rep f_hour = 60; // number of minutes na hour
30 static constexpr rep f_day = 24; // number of hours na day
31 static constexpr rep f_week = 7; // number of days per week
32
33 static constexpr rep second = f_second; // number of milliseconds per second
34 static constexpr rep minute = f_minute * second; // number of milliseconds per minute
35 static constexpr rep hour = f_hour * minute; // number of milliseconds per hour
36 static constexpr rep day = f_day * hour; // number of milliseconds per day
37 static constexpr rep week = f_week * day; // number of milliseconds per week
38
42 static time_point now() noexcept
43 {
44#ifdef _WIN32
45 FILETIME t;
46 GetSystemTimeAsFileTime(&t);
47 return from_system(t);
48#else
49 time_t t;
50 time(&t);
51 return from_time_t(t);
52#endif
53 }
54
55 static inline int32_t now_jul(_Out_opt_ uint32_t* hour = nullptr) noexcept
56 {
57#ifdef _WIN32
58 SYSTEMTIME t;
59 GetSystemTime(&t);
60 duration tp = from_system(t).time_since_epoch();
61#else
62 struct timespec t;
63 clock_gettime(CLOCK_REALTIME, &t);
64 duration tp = from_system(t).time_since_epoch();
65#endif
66 if (hour)
67 *hour = (uint32_t)(tp.count() % day);
68 return (uint32_t)(tp.count() / day);
69 }
70
71 static int32_t gre2jul(_In_ uint8_t day, _In_ uint8_t month, _In_ int32_t year) noexcept
72 {
73 int32_t mtmp, ytmp;
74 if (month > 2) {
75 mtmp = month - 3;
76 ytmp = year;
77 }
78 else {
79 mtmp = month + 9;
80 ytmp = year - 1;
81 }
82
83 int32_t ctmp = (ytmp / 100);
84 int32_t dtmp = ytmp - (100 * ctmp);
85 int32_t result1 = 146097L * ctmp / 4;
86 int32_t result2 = (1461 * dtmp) / 4;
87 int32_t result3 = (153 * mtmp + 2) / 5;
88
89 return (int32_t)result1 + day + result2 + 1721119L + result3;
90 }
91
92 static void jul2gre(_In_ int32_t jul, _Out_opt_ uint8_t* day, _Out_opt_ uint8_t* month, _Out_opt_ int32_t* year) noexcept
93 {
94 int32_t mtmp = jul - 1721119L;
95 int32_t yr = (4 * mtmp - 1) / 146097L;
96 mtmp = 4 * mtmp - 1 - 146097L * yr;
97 int32_t da = mtmp / 4;
98 mtmp = (4 * da + 3) / 1461;
99 da = 4 * da + 3 - 1461 * mtmp;
100 da = (da + 4) / 4;
101 int32_t mo = (5 * da - 3) / 153;
102 da = 5 * da - 3 - 153 * mo;
103 da = (da + 5) / 5;
104 yr = 100 * yr + mtmp;
105
106 if (mo < 10)
107 mo += 3;
108 else {
109 mo -= 9;
110 yr++;
111 }
112
113 if (day) *day = static_cast<uint8_t>(da);
114 if (month) *month = static_cast<uint8_t>(mo);
115 if (year) *year = yr;
116 }
117
118 static __time64_t to_time_t(_In_ const time_point& tp) noexcept
119 {
120 return tp.time_since_epoch().count() / second - 210866803200;
121 }
122
123 static time_point from_time_t(_In_ __time64_t t) noexcept
124 {
125 return time_point(duration(((rep)t + 210866803200) * second));
126 }
127
128#ifdef _WIN32
129 static time_point from_system(_In_ const SYSTEMTIME& t) noexcept
130 {
131 return time_point(duration(
132 ((rep)gre2jul((uint8_t)t.wDay, (uint8_t)t.wMonth, (int32_t)t.wYear)) * day +
133 ((rep)t.wHour * hour + (rep)t.wMinute * minute + (rep)t.wSecond * second + t.wMilliseconds)));
134 }
135
136 static time_point from_system(_In_ const FILETIME& t) noexcept
137 {
138 rep x = (((rep)t.dwHighDateTime) << 32) | t.dwLowDateTime;
139 return time_point(duration(x / 10000 + 199222329600000)); // Convert from 100 ns to 1 ms interval and adjust epoch
140 }
141
142 static time_point from_system(_In_ DATE t)
143 {
144 SYSTEMTIME st;
145 if (!VariantTimeToSystemTime(t, &st))
146 throw std::invalid_argument("failed to convert date from VARIANT_DATE");
147 return from_system(st);
148 }
149#else
150 static time_point from_system(_In_ const struct timespec& t) noexcept
151 {
152 return from_time_t(t.tv_sec) + t.tv_nsec / 1000;
153 }
154#endif
155 };
156 }
157}
Definition chrono.hpp:20
static time_point now() noexcept
Gets current time.
Definition chrono.hpp:42