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