123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- #pragma once
- #include "systime.h"
- #include <util/str_stl.h>
- #include <util/system/platform.h>
- #include <util/system/datetime.h>
- #include <util/generic/string.h>
- #include <util/generic/strbuf.h>
- #include <util/generic/ylimits.h>
- #include <util/generic/utility.h>
- #include <util/generic/typetraits.h>
- #include <util/generic/yexception.h>
- #include <chrono>
- #if defined(__cpp_lib_three_way_comparison)
- #include <compare>
- #endif
- #include <ctime>
- #include <cstdio>
- #include <ratio>
- #include <time.h>
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4244) // conversion from 'time_t' to 'long', possible loss of data
- #endif // _MSC_VER
- // Microseconds since epoch
- class TInstant;
- // Duration is microseconds. Could be used to store timeouts, for example.
- class TDuration;
- /// Current time
- static inline TInstant Now() noexcept;
- /// Use Now() method to obtain current time instead of *Seconds() unless you understand what are you doing.
- class TDateTimeParseException: public yexception {
- };
- const int DATE_BUF_LEN = 4 + 2 + 2 + 1; // [YYYYMMDD*]
- constexpr long seconds(const struct tm& theTm) {
- return 60 * (60 * theTm.tm_hour + theTm.tm_min) + theTm.tm_sec;
- }
- void sprint_gm_date(char* buf, time_t when, long* sec = nullptr);
- bool sscan_date(const char* date, struct tm& theTm);
- const int DATE_8601_LEN = 21; // strlen("YYYY-MM-DDThh:mm:ssZ") = 20 + '\0'
- size_t FormatDate8601(char* buf, size_t len, time_t when);
- inline void sprint_date8601(char* buf, time_t when) {
- buf[FormatDate8601(buf, 64, when)] = 0;
- }
- bool ParseISO8601DateTimeDeprecated(const char* date, time_t& utcTime);
- bool ParseISO8601DateTimeDeprecated(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseRFC822DateTimeDeprecated(const char* date, time_t& utcTime);
- bool ParseRFC822DateTimeDeprecated(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseHTTPDateTimeDeprecated(const char* date, time_t& utcTime);
- bool ParseHTTPDateTimeDeprecated(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseX509ValidityDateTimeDeprecated(const char* date, time_t& utcTime);
- bool ParseX509ValidityDateTimeDeprecated(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseISO8601DateTime(const char* date, time_t& utcTime);
- bool ParseISO8601DateTime(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseRFC822DateTime(const char* date, time_t& utcTime);
- bool ParseRFC822DateTime(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseHTTPDateTime(const char* date, time_t& utcTime);
- bool ParseHTTPDateTime(const char* date, size_t dateLen, time_t& utcTime);
- bool ParseX509ValidityDateTime(const char* date, time_t& utcTime);
- bool ParseX509ValidityDateTime(const char* date, size_t dateLen, time_t& utcTime);
- constexpr long TVdiff(timeval r1, timeval r2) {
- return (1000000 * (r2.tv_sec - r1.tv_sec) + (r2.tv_usec - r1.tv_usec));
- }
- TString Strftime(const char* format, const struct tm* tm);
- // Use functions below instead of sprint_date (check IGNIETFERRO-892 for details)
- void DateToString(char* buf, const struct tm& theTm);
- void DateToString(char* buf, time_t when, long* sec = nullptr);
- TString DateToString(const struct tm& theTm);
- TString DateToString(time_t when, long* sec = nullptr);
- // Year in format "YYYY", throws an exception if year not in range [0, 9999]
- TString YearToString(const struct tm& theTm);
- TString YearToString(time_t when);
- template <class S>
- class TTimeBase {
- public:
- using TValue = ui64;
- protected:
- constexpr TTimeBase(const TValue& value) noexcept
- : Value_(value)
- {
- }
- public:
- constexpr TTimeBase() noexcept
- : Value_(0)
- {
- }
- constexpr TTimeBase(const struct timeval& tv) noexcept
- : Value_(tv.tv_sec * (ui64)1000000 + tv.tv_usec)
- {
- }
- constexpr TValue GetValue() const noexcept {
- return Value_;
- }
- constexpr double SecondsFloat() const noexcept {
- return Value_ * (1 / 1000000.0);
- }
- constexpr double MillisecondsFloat() const noexcept {
- return Value_ * (1 / 1000.0);
- }
- constexpr TValue MicroSeconds() const noexcept {
- return Value_;
- }
- constexpr TValue MilliSeconds() const noexcept {
- return MicroSeconds() / 1000;
- }
- constexpr TValue Seconds() const noexcept {
- return MilliSeconds() / 1000;
- }
- constexpr TValue Minutes() const noexcept {
- return Seconds() / 60;
- }
- constexpr TValue Hours() const noexcept {
- return Minutes() / 60;
- }
- constexpr TValue Days() const noexcept {
- return Hours() / 24;
- }
- constexpr TValue NanoSeconds() const noexcept {
- return MicroSeconds() >= (Max<TValue>() / (TValue)1000) ? Max<TValue>() : MicroSeconds() * (TValue)1000;
- }
- constexpr ui32 MicroSecondsOfSecond() const noexcept {
- return MicroSeconds() % (TValue)1000000;
- }
- constexpr ui32 MilliSecondsOfSecond() const noexcept {
- return MicroSecondsOfSecond() / (TValue)1000;
- }
- constexpr ui32 NanoSecondsOfSecond() const noexcept {
- return MicroSecondsOfSecond() * (TValue)1000;
- }
- constexpr explicit operator bool() const noexcept {
- return Value_;
- }
- protected:
- TValue Value_; // microseconds count
- };
- namespace NDateTimeHelpers {
- template <typename T>
- struct TPrecisionHelper {
- using THighPrecision = ui64;
- };
- template <>
- struct TPrecisionHelper<float> {
- using THighPrecision = double;
- };
- template <>
- struct TPrecisionHelper<double> {
- using THighPrecision = double;
- };
- } // namespace NDateTimeHelpers
- class TDuration: public TTimeBase<TDuration> {
- using TBase = TTimeBase<TDuration>;
- private:
- /**
- * private construct from microseconds
- */
- constexpr explicit TDuration(TValue value) noexcept
- : TBase(value)
- {
- }
- public:
- constexpr TDuration() noexcept {
- }
- constexpr TDuration(const struct timeval& tv) noexcept
- : TBase(tv)
- {
- }
- /**
- * TDuration is compatible with std::chrono::duration:
- * it can be constructed and compared with std::chrono::duration.
- * But there are two significant and dangerous differences between them:
- * 1) TDuration is never negative and use saturation between 0 and maximum value.
- * std::chrono::duration can be negative and can overflow.
- * 2) TDuration uses integer number of microseconds.
- * std::chrono::duration is flexible, can be integer of floating point,
- * can have different precisions.
- * So when casted from std::chrono::duration to TDuration value is clamped and rounded.
- * In arithmetic operations std::chrono::duration argument is only rounded,
- * result is TDuration and it clamped and rounded.
- * In comparisons std::chrono::duration argument is rounded.
- */
- template <typename T, typename TRatio>
- constexpr TDuration(std::chrono::duration<T, TRatio> duration) noexcept {
- static_assert(
- std::ratio_greater_equal<TRatio, std::micro>::value &&
- (!std::is_floating_point<T>::value || std::ratio_greater<TRatio, std::micro>::value),
- "Extremely likely it is loss of precision, because TDuration stores microseconds. "
- "Cast you duration explicitly to microseconds if you really need it.");
- if (duration.count() < 0) {
- *this = TDuration::Zero(); // clamp from the bottom
- } else {
- if
- #if !defined(__NVCC__)
- constexpr
- #endif
- /* if [constexpr] */ (std::ratio_greater<TRatio, std::micro>::value || std::is_floating_point<T>::value) {
- // clamp from the top
- using TCommonDuration = std::chrono::duration<typename std::common_type<T, TValue>::type, TRatio>;
- constexpr auto maxDuration = std::chrono::duration<TValue, std::micro>(::Max<TValue>());
- if (std::chrono::duration_cast<TCommonDuration>(duration) >= std::chrono::duration_cast<TCommonDuration>(maxDuration)) {
- *this = TDuration::Max();
- return;
- }
- }
- const TValue us = std::chrono::duration_cast<std::chrono::duration<TValue, std::micro>>(duration).count();
- *this = TDuration::MicroSeconds(us);
- }
- }
- static constexpr TDuration FromValue(TValue value) noexcept {
- return TDuration(value);
- }
- static constexpr TDuration MicroSeconds(ui64 us) noexcept {
- return TDuration(us);
- }
- /* noexcept(false) as conversion from T might throw, for example FromString("abc") */
- template <typename T>
- static constexpr TDuration MilliSeconds(T ms) noexcept(false) {
- return MicroSeconds((ui64)(typename NDateTimeHelpers::TPrecisionHelper<T>::THighPrecision(ms) * 1000));
- }
- using TBase::Days;
- using TBase::Hours;
- using TBase::MicroSeconds;
- using TBase::MilliSeconds;
- using TBase::Minutes;
- using TBase::Seconds;
- /// DeadLineFromTimeOut
- inline TInstant ToDeadLine() const;
- constexpr TInstant ToDeadLine(TInstant now) const;
- static constexpr TDuration Max() noexcept {
- return TDuration(::Max<TValue>());
- }
- static constexpr TDuration Zero() noexcept {
- return TDuration();
- }
- /* noexcept(false) as conversion from T might throw, for example FromString("abc") */
- template <typename T>
- static constexpr TDuration Seconds(T s) noexcept(false) {
- return MilliSeconds(typename NDateTimeHelpers::TPrecisionHelper<T>::THighPrecision(s) * 1000);
- }
- static constexpr TDuration Minutes(ui64 m) noexcept {
- return Seconds(m * 60);
- }
- static constexpr TDuration Hours(ui64 h) noexcept {
- return Minutes(h * 60);
- }
- static constexpr TDuration Days(ui64 d) noexcept {
- return Hours(d * 24);
- }
- /// parses strings like 10s, 15ms, 15.05s, 20us, or just 25 (s). See parser_ut.cpp for details
- [[nodiscard]] static TDuration Parse(const TStringBuf input);
- static bool TryParse(const TStringBuf input, TDuration& result);
- // note global Out method is defined for TDuration, so it could be written to IOutputStream as text
- template <class T>
- inline TDuration& operator+=(const T& t) noexcept {
- return (*this = (*this + t));
- }
- template <class T>
- inline TDuration& operator-=(const T& t) noexcept {
- return (*this = (*this - t));
- }
- template <class T>
- inline TDuration& operator*=(const T& t) noexcept {
- return (*this = (*this * t));
- }
- template <class T>
- inline TDuration& operator/=(const T& t) noexcept {
- return (*this = (*this / t));
- }
- TString ToString() const;
- };
- Y_DECLARE_PODTYPE(TDuration);
- template <>
- struct THash<TDuration> {
- size_t operator()(const TDuration& key) const {
- return THash<TDuration::TValue>()(key.GetValue());
- }
- };
- /// TInstant and TDuration are guaranteed to have same precision
- class TInstant: public TTimeBase<TInstant> {
- using TBase = TTimeBase<TInstant>;
- private:
- /**
- * private construct from microseconds since epoch
- */
- constexpr explicit TInstant(TValue value) noexcept
- : TBase(value)
- {
- }
- public:
- constexpr TInstant() noexcept {
- }
- constexpr TInstant(const struct timeval& tv) noexcept
- : TBase(tv)
- {
- }
- static constexpr TInstant FromValue(TValue value) noexcept {
- return TInstant(value);
- }
- static inline TInstant Now() {
- return TInstant::MicroSeconds(::MicroSeconds());
- }
- using TBase::Days;
- using TBase::Hours;
- using TBase::MicroSeconds;
- using TBase::MilliSeconds;
- using TBase::Minutes;
- using TBase::Seconds;
- static constexpr TInstant Max() noexcept {
- return TInstant(::Max<TValue>());
- }
- static constexpr TInstant Zero() noexcept {
- return TInstant();
- }
- /// us since epoch
- static constexpr TInstant MicroSeconds(ui64 us) noexcept {
- return TInstant(us);
- }
- /// ms since epoch
- static constexpr TInstant MilliSeconds(ui64 ms) noexcept {
- return MicroSeconds(ms * 1000);
- }
- /// seconds since epoch
- static constexpr TInstant Seconds(ui64 s) noexcept {
- return MilliSeconds(s * 1000);
- }
- /// minutes since epoch
- static constexpr TInstant Minutes(ui64 m) noexcept {
- return Seconds(m * 60);
- }
- /// hours since epoch
- static constexpr TInstant Hours(ui64 h) noexcept {
- return Minutes(h * 60);
- }
- /// days since epoch
- static constexpr TInstant Days(ui64 d) noexcept {
- return Hours(d * 24);
- }
- constexpr time_t TimeT() const noexcept {
- return (time_t)Seconds();
- }
- inline struct timeval TimeVal() const noexcept {
- struct timeval tv;
- ::Zero(tv);
- tv.tv_sec = TimeT();
- tv.tv_usec = MicroSecondsOfSecond();
- return tv;
- }
- inline struct tm* LocalTime(struct tm* tm) const noexcept {
- time_t clock = Seconds();
- return localtime_r(&clock, tm);
- }
- inline struct tm* GmTime(struct tm* tm) const noexcept {
- time_t clock = Seconds();
- return GmTimeR(&clock, tm);
- }
- /**
- * Formats the instant using the UTC time zone, with microsecond precision.
- *
- * @returns An ISO 8601 formatted string, e.g. '2015-11-21T23:30:27.991669Z'.
- * @note Global Out method is defined to TInstant, so it can be written as text to IOutputStream.
- */
- TString ToString() const;
- /**
- * Formats the instant using the UTC time zone.
- *
- * @returns An RFC822 formatted string, e.g. 'Sun, 06 Nov 1994 08:49:37 GMT'.
- */
- TString ToRfc822String() const;
- /**
- * Formats the instant using the UTC time zone, with second precision.
- *
- * @returns An ISO 8601 formatted string, e.g. '2015-11-21T23:30:27Z'.
- */
- TString ToStringUpToSeconds() const;
- /**
- * Formats the instant using the system time zone, with microsecond precision.
- *
- * @returns An ISO 8601 / RFC 3339 formatted string,
- * e.g. '2015-11-22T04:30:27.991669+05:00'.
- */
- TString ToIsoStringLocal() const;
- /**
- * Formats the instant using the system time zone, with microsecond precision.
- *
- * @returns A semi-ISO 8601 formatted string with timezone without colon,
- * e.g. '2015-11-22T04:30:27.991669+0500'.
- */
- TString ToStringLocal() const;
- /**
- * Formats the instant using the system time zone.
- *
- * @returns An RFC822 formatted string, e.g. 'Sun, 06 Nov 1994 08:49:37 MSK'.
- */
- TString ToRfc822StringLocal() const;
- /**
- * Formats the instant using the system time zone, with second precision.
- *
- * @returns An ISO 8601 / RFC 3339 formatted string,
- * e.g. '2015-11-22T04:30:27+05:00'.
- */
- TString ToIsoStringLocalUpToSeconds() const;
- /**
- * Formats the instant using the system time zone, with second precision.
- *
- * @returns A semi-ISO 8601 formatted string with timezone without colon,
- * e.g. '2015-11-22T04:30:27+0500'.
- */
- TString ToStringLocalUpToSeconds() const;
- TString FormatLocalTime(const char* format) const noexcept;
- TString FormatGmTime(const char* format) const noexcept;
- /// See #TryParseIso8601.
- static TInstant ParseIso8601(TStringBuf);
- /// See #TryParseRfc822.
- static TInstant ParseRfc822(TStringBuf);
- /// See #TryParseHttp.
- static TInstant ParseHttp(TStringBuf);
- /// See #TryParseX509.
- static TInstant ParseX509Validity(TStringBuf);
- /// ISO 8601 Representation of Dates and Times
- ///
- /// @link https://www.iso.org/standard/40874.html Description of format.
- static bool TryParseIso8601(TStringBuf input, TInstant& instant);
- /// RFC 822 Date and Time specification
- ///
- /// @link https://tools.ietf.org/html/rfc822#section-5 Description of format.
- static bool TryParseRfc822(TStringBuf input, TInstant& instant);
- /// RFC 2616 3.3.1 Full Date
- ///
- /// @link https://tools.ietf.org/html/rfc2616#section-3.3.1 Description of format.
- static bool TryParseHttp(TStringBuf input, TInstant& instant);
- /// X.509 certificate validity time (see rfc5280 4.1.2.5.*)
- ///
- /// @link https://tools.ietf.org/html/rfc5280#section-4.1.2.5 Description of format.
- static bool TryParseX509(TStringBuf input, TInstant& instant);
- static TInstant ParseIso8601Deprecated(TStringBuf);
- static TInstant ParseRfc822Deprecated(TStringBuf);
- static TInstant ParseHttpDeprecated(TStringBuf);
- static TInstant ParseX509ValidityDeprecated(TStringBuf);
- static bool TryParseIso8601Deprecated(TStringBuf input, TInstant& instant);
- static bool TryParseRfc822Deprecated(TStringBuf input, TInstant& instant);
- static bool TryParseHttpDeprecated(TStringBuf input, TInstant& instant);
- static bool TryParseX509Deprecated(TStringBuf input, TInstant& instant);
- template <class T>
- inline TInstant& operator+=(const T& t) noexcept {
- return (*this = (*this + t));
- }
- template <class T>
- inline TInstant& operator-=(const T& t) noexcept {
- return (*this = (*this - t));
- }
- };
- Y_DECLARE_PODTYPE(TInstant);
- template <>
- struct THash<TInstant> {
- size_t operator()(const TInstant& key) const {
- return THash<TInstant::TValue>()(key.GetValue());
- }
- };
- namespace NPrivate {
- template <bool PrintUpToSeconds, bool iso>
- struct TPrintableLocalTime {
- TInstant MomentToPrint;
- constexpr explicit TPrintableLocalTime(TInstant momentToPrint)
- : MomentToPrint(momentToPrint)
- {
- }
- };
- } // namespace NPrivate
- /** @name Helpers for printing local times to `IOutputStream`s.
- * The FormatLocal* functions create an opaque object that, when written to
- * a `IOutputStream`, outputs this instant as an ISO 8601 formatted string
- * using the system time zone.
- *
- * @note The only reason behind this set of functions is to avoid excessive
- * allocations when you directly print the local time to a stream.
- *
- * If you need something beyond just printing the value or your code
- * is not performance-critical, feel free to use the corresponding
- * TInstant::ToString*() functions.
- */
- ///@{
- /// @see TInstant::ToIsoStringLocal()
- ::NPrivate::TPrintableLocalTime<false, true> FormatIsoLocal(TInstant instant);
- /// @see TInstant::ToStringLocal()
- ::NPrivate::TPrintableLocalTime<false, false> FormatLocal(TInstant instant);
- /// @see TInstant::ToIsoStringLocalUpToSeconds()
- ::NPrivate::TPrintableLocalTime<true, true> FormatIsoLocalUpToSeconds(TInstant instant);
- /// @see TInstant::ToStringLocalUpToSeconds()
- ::NPrivate::TPrintableLocalTime<true, false> FormatLocalUpToSeconds(TInstant instant);
- ///@}
- template <class S>
- static constexpr bool operator<(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() < r.GetValue();
- }
- template <class S>
- static constexpr bool operator<=(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() <= r.GetValue();
- }
- template <class S>
- static constexpr bool operator==(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() == r.GetValue();
- }
- template <class S>
- static constexpr bool operator!=(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() != r.GetValue();
- }
- template <class S>
- static constexpr bool operator>(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() > r.GetValue();
- }
- template <class S>
- static constexpr bool operator>=(const TTimeBase<S>& l, const TTimeBase<S>& r) noexcept {
- return l.GetValue() >= r.GetValue();
- }
- namespace NDateTimeHelpers {
- template <typename T>
- static constexpr T SumWithSaturation(T a, T b) {
- static_assert(!std::numeric_limits<T>::is_signed, "expect !std::numeric_limits<T>::is_signed");
- return Max<T>() - a < b ? Max<T>() : a + b;
- }
- template <typename T>
- static constexpr T DiffWithSaturation(T a, T b) {
- static_assert(!std::numeric_limits<T>::is_signed, "expect !std::numeric_limits<T>::is_signed");
- return a < b ? 0 : a - b;
- }
- } // namespace NDateTimeHelpers
- constexpr TDuration operator-(const TInstant& l, const TInstant& r) noexcept {
- return TDuration::FromValue(::NDateTimeHelpers::DiffWithSaturation(l.GetValue(), r.GetValue()));
- }
- constexpr TInstant operator+(const TInstant& i, const TDuration& d) noexcept {
- return TInstant::FromValue(::NDateTimeHelpers::SumWithSaturation(i.GetValue(), d.GetValue()));
- }
- constexpr TInstant operator-(const TInstant& i, const TDuration& d) noexcept {
- return TInstant::FromValue(::NDateTimeHelpers::DiffWithSaturation(i.GetValue(), d.GetValue()));
- }
- constexpr TDuration operator-(const TDuration& l, const TDuration& r) noexcept {
- return TDuration::FromValue(::NDateTimeHelpers::DiffWithSaturation(l.GetValue(), r.GetValue()));
- }
- constexpr TDuration operator+(const TDuration& l, const TDuration& r) noexcept {
- return TDuration::FromValue(::NDateTimeHelpers::SumWithSaturation(l.GetValue(), r.GetValue()));
- }
- template <typename T, typename TRatio>
- constexpr bool operator==(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r.count() >= 0 && l == TDuration(r);
- }
- #if defined(__cpp_lib_three_way_comparison)
- template <typename T, typename TRatio>
- constexpr std::strong_ordering operator<=>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- if (r.count() < 0) {
- return std::strong_ordering::greater;
- }
- return l.GetValue() <=> TDuration(r).GetValue();
- }
- #else
- template <typename T, typename TRatio>
- constexpr bool operator<(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r.count() >= 0 && l < TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr bool operator<=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r.count() >= 0 && l <= TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr bool operator!=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return !(l == r);
- }
- template <typename T, typename TRatio>
- constexpr bool operator>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r.count() < 0 || l > TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr bool operator>=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r.count() < 0 || l >= TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr bool operator<(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r > l;
- }
- template <typename T, typename TRatio>
- constexpr bool operator<=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r >= l;
- }
- template <typename T, typename TRatio>
- constexpr bool operator==(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r == l;
- }
- template <typename T, typename TRatio>
- constexpr bool operator!=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r != l;
- }
- template <typename T, typename TRatio>
- constexpr bool operator>(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r < l;
- }
- template <typename T, typename TRatio>
- constexpr bool operator>=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r >= l;
- }
- #endif
- template <typename T, typename TRatio>
- constexpr TDuration operator+(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r < r.zero() ? l - TDuration(-r) : l + TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr TDuration operator+(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return r + l;
- }
- template <typename T, typename TRatio>
- constexpr TDuration operator-(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return l + (-r);
- }
- template <typename T, typename TRatio>
- constexpr TDuration operator-(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept {
- return TDuration(l) - r;
- }
- template <typename T, typename TRatio>
- constexpr TInstant operator+(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return r < r.zero() ? l - TDuration(-r) : l + TDuration(r);
- }
- template <typename T, typename TRatio>
- constexpr TInstant operator-(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept {
- return l + (-r);
- }
- template <class T>
- inline TDuration operator*(TDuration d, T t) noexcept {
- Y_ASSERT(t >= T());
- Y_ASSERT(t == T() || Max<TDuration::TValue>() / t >= d.GetValue());
- return TDuration::FromValue(d.GetValue() * t);
- }
- template <>
- inline TDuration operator*(TDuration d, double t) noexcept {
- Y_ASSERT(t >= 0 && MaxFloor<TDuration::TValue>() >= d.GetValue() * t);
- return TDuration::FromValue(d.GetValue() * t);
- }
- template <>
- inline TDuration operator*(TDuration d, float t) noexcept {
- return d * static_cast<double>(t);
- }
- template <class T>
- inline TDuration operator*(T t, TDuration d) noexcept {
- return d * t;
- }
- template <class T, std::enable_if_t<!std::is_same<TDuration, T>::value, int> = 0>
- constexpr TDuration operator/(const TDuration& d, const T& t) noexcept {
- return TDuration::FromValue(d.GetValue() / t);
- }
- constexpr double operator/(const TDuration& x, const TDuration& y) noexcept {
- return static_cast<double>(x.GetValue()) / static_cast<double>(y.GetValue());
- }
- inline TInstant TDuration::ToDeadLine() const {
- return ToDeadLine(TInstant::Now());
- }
- constexpr TInstant TDuration::ToDeadLine(TInstant now) const {
- return now + *this;
- }
- void Sleep(TDuration duration);
- void SleepUntil(TInstant instant);
- static inline TInstant Now() noexcept {
- return TInstant::Now();
- }
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif // _MSC_VER
|