17#ifndef TOOLBOX_SYS_TIME_HPP
18#define TOOLBOX_SYS_TIME_HPP
30using namespace std::literals::chrono_literals;
31using namespace std::literals::string_view_literals;
34using Decis = std::chrono::duration<int64_t, std::deci>;
35using Millis = std::chrono::milliseconds;
36using Micros = std::chrono::microseconds;
37using Nanos = std::chrono::nanoseconds;
47 using rep = Duration::rep;
48 using time_point = std::chrono::time_point<MonoClock, Duration>;
56 using FromPoint = std::chrono::time_point<MonoClock, seconds>;
57 constexpr seconds secs{std::numeric_limits<int>::max()};
72 using FromPoint = std::chrono::time_point<MonoClock, seconds>;
80 using rep = Duration::rep;
81 using time_point = std::chrono::time_point<WallClock, Duration>;
89 using FromPoint = std::chrono::time_point<WallClock, seconds>;
90 constexpr seconds secs{std::numeric_limits<int>::max()};
105 using FromPoint = std::chrono::time_point<WallClock, seconds>;
134 time_ = Time::now(wall_time);
144 static Time now() noexcept {
return {MonoClock::now(), WallClock::now()}; };
145 static Time now(WallTime wall_time)
noexcept {
return {MonoClock::now(), wall_time}; };
149 static thread_local Time time_;
152template <
typename RepT,
typename PeriodT>
153constexpr bool is_zero(std::chrono::duration<RepT, PeriodT>
d)
noexcept
155 return d ==
decltype(
d){};
158template <
typename ClockT>
159constexpr bool is_zero(std::chrono::time_point<ClockT, Duration>
t)
noexcept
161 return t ==
decltype(
t){};
164template <
typename ClockT,
typename DurationT>
172template <
typename ClockT>
173constexpr std::int64_t
ms_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
179template <
typename ClockT>
180constexpr std::int64_t
us_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
186template <
typename ClockT>
187constexpr std::int64_t
ns_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
194template <
typename ClockT,
typename RepT,
typename PeriodT>
195constexpr auto to_time(std::chrono::duration<RepT, PeriodT>
d)
noexcept
201template <
typename ClockT>
208template <
typename ClockT>
215template <
typename RepT,
typename PeriodT>
223template <
typename ClockT>
230template <
typename RepT,
typename PeriodT>
235 return {
static_cast<time_t>(
ns / 1'000'000'000L),
static_cast<long>(
ns % 1'000'000'000L)};
238template <
typename ClockT>
245template <
typename StreamT>
253template <
typename StreamT>
261template <
typename DurationT>
267template <
typename DurationT = Seconds>
273template <
typename DurationT,
typename StreamT>
281 if constexpr (std::is_same_v<DurationT, Nanos>) {
283 os <<
'.' << std::format(
"{:0>9}",
ns % 1'000'000'000L);
284 }
else if constexpr (std::is_same_v<DurationT, Micros>) {
286 os <<
'.' << std::format(
"{:0>6}",
us % 1'000'000L);
287 }
else if constexpr (std::is_same_v<DurationT, Millis>) {
289 os <<
'.' << std::format(
"{:0>3}",
ms % 1'000L);
290 }
else if constexpr (std::is_same_v<DurationT, Seconds>) {
299 return tv.tv_sec == 0 &&
tv.tv_usec == 0;
304 tv.tv_sec =
tv.tv_usec = 0;
310 tv.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
311 tv.tv_usec =
lhs.tv_usec +
rhs.tv_usec;
312 if (
tv.tv_usec >= 1'000'000) {
314 tv.tv_usec -= 1'000'000;
322 tv.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
323 tv.tv_usec =
lhs.tv_usec -
rhs.tv_usec;
324 if (
tv.tv_usec < 0) {
326 tv.tv_usec += 1'000'000;
333 return ts.tv_sec == 0 && ts.tv_nsec == 0;
338 ts.tv_sec = ts.tv_nsec = 0;
344 ts.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
345 ts.tv_nsec =
lhs.tv_nsec +
rhs.tv_nsec;
346 if (ts.tv_nsec >= 1'000'000'000) {
348 ts.tv_nsec -= 1'000'000'000;
356 ts.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
357 ts.tv_nsec =
lhs.tv_nsec -
rhs.tv_nsec;
358 if (ts.tv_nsec < 0) {
360 ts.tv_nsec += 1'000'000'000;
371 constexpr int c[] = {
386 sv =
sv.substr(0, 9);
387 auto it =
sv.begin(), end =
sv.end();
425 const hours h{(
sv[0] -
'0') * 10 +
sv[1] -
'0'};
441inline namespace util {
443template <
typename RepT,
typename PeriodT>
449 using Rep =
typename Duration::rep;
ostream & operator<<(ostream &os, const pair< T, U > &p)