17#ifndef TOOLBOX_SYS_TIME_HPP
18#define TOOLBOX_SYS_TIME_HPP
22#include <boost/io/ios_state.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>;
137 time_ = Time::now(wall_time);
147 static Time now() noexcept {
return {MonoClock::now(), WallClock::now()}; };
148 static Time now(WallTime wall_time)
noexcept {
return {MonoClock::now(), wall_time}; };
152 static thread_local Time time_;
155template <
typename RepT,
typename PeriodT>
156constexpr bool is_zero(std::chrono::duration<RepT, PeriodT>
d)
noexcept
158 return d ==
decltype(
d){};
161template <
typename ClockT>
162constexpr bool is_zero(std::chrono::time_point<ClockT, Duration>
t)
noexcept
164 return t ==
decltype(
t){};
167template <
typename ClockT,
typename DurationT>
175template <
typename ClockT>
176constexpr std::int64_t
ms_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
182template <
typename ClockT>
183constexpr std::int64_t
us_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
189template <
typename ClockT>
190constexpr std::int64_t
ns_since_epoch(std::chrono::time_point<ClockT, Duration>
t)
noexcept
197template <
typename ClockT,
typename RepT,
typename PeriodT>
198constexpr auto to_time(std::chrono::duration<RepT, PeriodT>
d)
noexcept
204template <
typename ClockT>
211template <
typename ClockT>
218template <
typename RepT,
typename PeriodT>
226template <
typename ClockT>
233template <
typename RepT,
typename PeriodT>
238 return {
static_cast<time_t>(
ns / 1'000'000'000L),
static_cast<long>(
ns % 1'000'000'000L)};
241template <
typename ClockT>
248template <
typename DurationT>
254template <
typename DurationT = Seconds>
260template <
typename DurationT>
267 if constexpr (std::is_same_v<DurationT, Nanos>) {
269 boost::io::ios_fill_saver
ifs{os};
270 boost::io::ios_width_saver
iws{os};
271 os <<
'.' << std::setfill(
'0') << std::setw(9) << (
ns % 1'000'000'000L);
272 }
else if constexpr (std::is_same_v<DurationT, Micros>) {
274 boost::io::ios_fill_saver
ifs{os};
275 boost::io::ios_width_saver
iws{os};
276 os <<
'.' << std::setfill(
'0') << std::setw(6) << (
us % 1'000'000L);
277 }
else if constexpr (std::is_same_v<DurationT, Millis>) {
279 boost::io::ios_fill_saver
ifs{os};
280 boost::io::ios_width_saver
iws{os};
281 os <<
'.' << std::setfill(
'0') << std::setw(3) << (
ms % 1'000L);
282 }
else if constexpr (std::is_same_v<DurationT, Seconds>) {
291 return tv.tv_sec == 0 &&
tv.tv_usec == 0;
296 tv.tv_sec =
tv.tv_usec = 0;
302 tv.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
303 tv.tv_usec =
lhs.tv_usec +
rhs.tv_usec;
304 if (
tv.tv_usec >= 1'000'000) {
306 tv.tv_usec -= 1'000'000;
314 tv.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
315 tv.tv_usec =
lhs.tv_usec -
rhs.tv_usec;
316 if (
tv.tv_usec < 0) {
318 tv.tv_usec += 1'000'000;
325 return ts.tv_sec == 0 && ts.tv_nsec == 0;
330 ts.tv_sec = ts.tv_nsec = 0;
336 ts.tv_sec =
lhs.tv_sec +
rhs.tv_sec;
337 ts.tv_nsec =
lhs.tv_nsec +
rhs.tv_nsec;
338 if (ts.tv_nsec >= 1'000'000'000) {
340 ts.tv_nsec -= 1'000'000'000;
348 ts.tv_sec =
lhs.tv_sec -
rhs.tv_sec;
349 ts.tv_nsec =
lhs.tv_nsec -
rhs.tv_nsec;
350 if (ts.tv_nsec < 0) {
352 ts.tv_nsec += 1'000'000'000;
363 constexpr int c[] = {
378 sv =
sv.substr(0, 9);
379 auto it =
sv.begin(), end =
sv.end();
417 const hours h{(
sv[0] -
'0') * 10 +
sv[1] -
'0'};
433inline namespace util {
435template <
typename RepT,
typename PeriodT>
441 using Rep =
typename Duration::rep;
ostream & operator<<(ostream &os, const pair< T, U > &p)