17#ifndef TOOLBOX_SYS_TIME_HPP
18#define TOOLBOX_SYS_TIME_HPP
32using namespace std::literals::chrono_literals;
33using namespace std::literals::string_view_literals;
36using Decis = std::chrono::duration<int64_t, std::deci>;
37using Millis = std::chrono::milliseconds;
38using Micros = std::chrono::microseconds;
39using Nanos = std::chrono::nanoseconds;
49 using rep = Duration::rep;
50 using time_point = std::chrono::time_point<MonoClock, Duration>;
58 using FromPoint = std::chrono::time_point<MonoClock, seconds>;
59 constexpr seconds secs{std::numeric_limits<int>::max()};
74 using FromPoint = std::chrono::time_point<MonoClock, seconds>;
82 using rep = Duration::rep;
83 using time_point = std::chrono::time_point<WallClock, Duration>;
91 using FromPoint = std::chrono::time_point<WallClock, seconds>;
92 constexpr seconds secs{std::numeric_limits<int>::max()};
107 using FromPoint = std::chrono::time_point<WallClock, seconds>;
136 time_ = Time::now(wall_time);
146 static Time now() noexcept {
return {MonoClock::now(), WallClock::now()}; };
147 static Time now(WallTime wall_time)
noexcept {
return {MonoClock::now(), wall_time}; };
151 static thread_local Time time_;
154template <
typename RepT,
typename PeriodT>
155constexpr bool is_zero(std::chrono::duration<RepT, PeriodT>
d)
noexcept
157 return d ==
decltype(
d){};
160template <
typename ClockT>
161constexpr bool is_zero(std::chrono::time_point<ClockT, Duration>
t)
noexcept
163 return t ==
decltype(
t){};
166template <
typename ClockT,
typename DurationT>
174template <
typename ClockT>
175constexpr std::int64_t
ms_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
181template <
typename ClockT>
182constexpr std::int64_t
us_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
188template <
typename ClockT>
189constexpr std::int64_t
ns_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
196template <
typename ClockT,
typename RepT,
typename PeriodT>
197constexpr auto to_time(std::chrono::duration<RepT, PeriodT>
d)
noexcept
203template <
typename ClockT>
210template <
typename ClockT>
217template <
typename RepT,
typename PeriodT>
225template <
typename ClockT>
232template <
typename RepT,
typename PeriodT>
237 return {
static_cast<time_t>(
ns / 1'000'000'000L),
static_cast<long>(
ns % 1'000'000'000L)};
240template <
typename ClockT>
247template <
typename StreamT>
255template <
typename StreamT>
263template <
typename DurationT>
269template <
typename DurationT = Seconds>
275template <
typename DurationT,
typename StreamT>
283 if constexpr (std::is_same_v<DurationT, Nanos>) {
285 os <<
'.' << std::format(
"{:0>9}",
ns % 1'000'000'000L);
286 }
else if constexpr (std::is_same_v<DurationT, Micros>) {
288 os <<
'.' << std::format(
"{:0>6}",
us % 1'000'000L);
289 }
else if constexpr (std::is_same_v<DurationT, Millis>) {
291 os <<
'.' << std::format(
"{:0>3}",
ms % 1'000L);
292 }
else if constexpr (std::is_same_v<DurationT, Seconds>) {
301 return tv.tv_sec == 0 &&
tv.tv_usec == 0;
306 tv.tv_sec =
tv.tv_usec = 0;
312 tv.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
313 tv.tv_usec =
lhs.tv_usec +
rhs.tv_usec;
314 if (
tv.tv_usec >= 1'000'000) {
316 tv.tv_usec -= 1'000'000;
324 tv.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
325 tv.tv_usec =
lhs.tv_usec -
rhs.tv_usec;
326 if (
tv.tv_usec < 0) {
328 tv.tv_usec += 1'000'000;
335 return ts.tv_sec == 0 && ts.tv_nsec == 0;
340 ts.tv_sec = ts.tv_nsec = 0;
346 ts.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
347 ts.tv_nsec =
lhs.tv_nsec +
rhs.tv_nsec;
348 if (ts.tv_nsec >= 1'000'000'000) {
350 ts.tv_nsec -= 1'000'000'000;
358 ts.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
359 ts.tv_nsec =
lhs.tv_nsec -
rhs.tv_nsec;
360 if (ts.tv_nsec < 0) {
362 ts.tv_nsec += 1'000'000'000;
373 constexpr int c[] = {
388 sv =
sv.substr(0, 9);
389 auto it =
sv.begin(), end =
sv.end();
427 const hours h{(
sv[0] -
'0') * 10 +
sv[1] -
'0'};
443inline namespace util {
445template <
typename RepT,
typename PeriodT>
451 using Rep =
typename Duration::rep;
479 template <
typename Callable>
483 last_time_invoked_ = now;
489 const Seconds cooldown_interval_{};
ostream & operator<<(ostream &os, const pair< T, U > &p)