27 Time library [time]

27.5 Class template duration [time.duration]

A duration type measures time between two points in time (time_­points).
A duration has a representation which holds a count of ticks and a tick period.
The tick period is the amount of time which occurs from one tick to the next, in units of seconds.
It is expressed as a rational constant using the template ratio.
namespace std::chrono {
  template<class Rep, class Period = ratio<1>>
  class duration {
  public:
    using rep    = Rep;
    using period = typename Period::type;

  private:
    rep rep_;       // exposition only

  public:
    // [time.duration.cons], construct/copy/destroy
    constexpr duration() = default;
    template<class Rep2>
      constexpr explicit duration(const Rep2& r);
    template<class Rep2, class Period2>
      constexpr duration(const duration<Rep2, Period2>& d);
    ~duration() = default;
    duration(const duration&) = default;
    duration& operator=(const duration&) = default;

    // [time.duration.observer], observer
    constexpr rep count() const;

    // [time.duration.arithmetic], arithmetic
    constexpr common_type_t<duration> operator+() const;
    constexpr common_type_t<duration> operator-() const;
    constexpr duration& operator++();
    constexpr duration  operator++(int);
    constexpr duration& operator--();
    constexpr duration  operator--(int);

    constexpr duration& operator+=(const duration& d);
    constexpr duration& operator-=(const duration& d);

    constexpr duration& operator*=(const rep& rhs);
    constexpr duration& operator/=(const rep& rhs);
    constexpr duration& operator%=(const rep& rhs);
    constexpr duration& operator%=(const duration& rhs);

    // [time.duration.special], special values
    static constexpr duration zero() noexcept;
    static constexpr duration min() noexcept;
    static constexpr duration max() noexcept;
  };
}
Rep shall be an arithmetic type or a class emulating an arithmetic type.
If duration is instantiated with a duration type as the argument for the template parameter Rep, the program is ill-formed.
If Period is not a specialization of ratio, the program is ill-formed.
If Period​::​num is not positive, the program is ill-formed.
Members of duration do not throw exceptions other than those thrown by the indicated operations on their representations.
The defaulted copy constructor of duration shall be a constexpr function if and only if the required initialization of the member rep_­ for copy and move, respectively, would satisfy the requirements for a constexpr function.
[Example
:
duration<long, ratio<60>> d0;       // holds a count of minutes using a long
duration<long long, milli> d1;      // holds a count of milliseconds using a long long
duration<double, ratio<1, 30>>  d2; // holds a count with a tick period of  of a second
                                    // (30 Hz) using a double
— end example
]

27.5.1 Constructors [time.duration.cons]

template<class Rep2> constexpr explicit duration(const Rep2& r);
Constraints: is_­convertible_­v<const Rep2&, rep> is true and
  • treat_­as_­floating_­point_­v<rep> is true or
  • treat_­as_­floating_­point_­v<Rep2> is false.
[Example
:
duration<int, milli> d(3);          // OK
duration<int, milli> d(3.5);        // error
— end example
]
Postconditions: count() == static_­cast<rep>(r).
template<class Rep2, class Period2> constexpr duration(const duration<Rep2, Period2>& d);
Constraints: No overflow is induced in the conversion and treat_­as_­floating_­point_­v<rep> is true or both ratio_­divide<Period2, period>​::​den is 1 and treat_­as_­floating_­point_­v<Rep2> is false.
[Note
:
This requirement prevents implicit truncation error when converting between integral-based duration types.
Such a construction could easily lead to confusion about the value of the duration.
— end note
]
[Example
:
duration<int, milli> ms(3);
duration<int, micro> us = ms;       // OK
duration<int, milli> ms2 = us;      // error
— end example
]
Effects: Initializes rep_­ with duration_­cast<duration>(d).count().

27.5.2 Observer [time.duration.observer]

constexpr rep count() const;
Returns: rep_­.

27.5.3 Arithmetic [time.duration.arithmetic]

constexpr common_type_t<duration> operator+() const;
Returns: common_­type_­t<duration>(*this).
constexpr common_type_t<duration> operator-() const;
Returns: common_­type_­t<duration>(-rep_­).
constexpr duration& operator++();
Effects: Equivalent to: ++rep_­.
Returns: *this.
constexpr duration operator++(int);
Effects: Equivalent to: return duration(rep_­++);
constexpr duration& operator--();
Effects: Equivalent to: --rep_­.
Returns: *this.
constexpr duration operator--(int);
Effects: Equivalent to: return duration(rep_­--);
constexpr duration& operator+=(const duration& d);
Effects: Equivalent to: rep_­ += d.count().
Returns: *this.
constexpr duration& operator-=(const duration& d);
Effects: Equivalent to: rep_­ -= d.count().
Returns: *this.
constexpr duration& operator*=(const rep& rhs);
Effects: Equivalent to: rep_­ *= rhs.
Returns: *this.
constexpr duration& operator/=(const rep& rhs);
Effects: Equivalent to: rep_­ /= rhs.
Returns: *this.
constexpr duration& operator%=(const rep& rhs);
Effects: Equivalent to: rep_­ %= rhs.
Returns: *this.
constexpr duration& operator%=(const duration& rhs);
Effects: Equivalent to: rep_­ %= rhs.count().
Returns: *this.

27.5.4 Special values [time.duration.special]

static constexpr duration zero() noexcept;
Returns: duration(duration_­values<rep>​::​zero()).
static constexpr duration min() noexcept;
Returns: duration(duration_­values<rep>​::​min()).
static constexpr duration max() noexcept;
Returns: duration(duration_­values<rep>​::​max()).

27.5.5 Non-member arithmetic [time.duration.nonmember]

In the function descriptions that follow, unless stated otherwise, let CD represent the return type of the function.
template<class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() + CD(rhs).count()).
template<class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() - CD(rhs).count()).
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);
Constraints: is_­convertible_­v<const Rep2&, common_­type_­t<Rep1, Rep2>> is true.
Returns: CD(CD(d).count() * s).
template<class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);
Constraints: is_­convertible_­v<const Rep1&, common_­type_­t<Rep1, Rep2>> is true.
Returns: d * s.
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);
Constraints: is_­convertible_­v<const Rep2&, common_­type_­t<Rep1, Rep2>> is true and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() / s).
template<class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<Rep1, Rep2> operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Let CD be common_­type_­t<duration<Rep1, Period1>, duration<Rep2, Period2>>.
Returns: CD(lhs).count() / CD(rhs).count().
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);
Constraints: is_­convertible_­v<const Rep2&, common_­type_­t<Rep1, Rep2>> is true and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() % s).
template<class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() % CD(rhs).count()).

27.5.6 Comparisons [time.duration.comparisons]

In the function descriptions that follow, CT represents common_­type_­t<A, B>, where A and B are the types of the two arguments to the function.
template<class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() == CT(rhs).count().
template<class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() < CT(rhs).count().
template<class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: rhs < lhs.
template<class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(rhs < lhs).
template<class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(lhs < rhs).
template<class Rep1, class Period1, class Rep2, class Period2> requires three_­way_­comparable<typename CT::rep> constexpr auto operator<=>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() <=> CT(rhs).count().

27.5.7 Conversions [time.duration.cast]

template<class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
Constraints: ToDuration is a specialization of duration.
Returns: Let CF be ratio_­divide<Period, typename ToDuration​::​period>, and CR be common_­type<typename ToDuration​::​rep, Rep, intmax_­t>​::​type.
  • If CF​::​num == 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(d.count()))
    
  • otherwise, if CF​::​num != 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
    
  • otherwise, if CF​::​num == 1 and CF​::​den != 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
    
  • otherwise, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
    
[Note
:
This function does not use any implicit conversions; all conversions are done with static_­cast.
It avoids multiplications and divisions when it is known at compile time that one or more arguments is 1.
Intermediate computations are carried out in the widest representation and only converted to the destination representation at the final step.
— end note
]
template<class ToDuration, class Rep, class Period> constexpr ToDuration floor(const duration<Rep, Period>& d);
Constraints: ToDuration is a specialization of duration.
Returns: The greatest result t representable in ToDuration for which t <= d.
template<class ToDuration, class Rep, class Period> constexpr ToDuration ceil(const duration<Rep, Period>& d);
Constraints: ToDuration is a specialization of duration.
Returns: The least result t representable in ToDuration for which t >= d.
template<class ToDuration, class Rep, class Period> constexpr ToDuration round(const duration<Rep, Period>& d);
Constraints: ToDuration is a specialization of duration and treat_­as_­floating_­point_­v<typename ToDuration​::​rep> is false.
Returns: The value of ToDuration that is closest to d.
If there are two closest values, then return the value t for which t % 2 == 0.

27.5.8 Suffixes for duration literals [time.duration.literals]

This subclause describes literal suffixes for constructing duration literals.
The suffixes h, min, s, ms, us, ns denote duration values of the corresponding types hours, minutes, seconds, milliseconds, microseconds, and nanoseconds respectively if they are applied to integer-literals.
If any of these suffixes are applied to a floating-point-literal the result is a chrono​::​duration literal with an unspecified floating-point representation.
If any of these suffixes are applied to an integer-literal and the resulting chrono​::​duration value cannot be represented in the result type because of overflow, the program is ill-formed.
[Example
:
The following code shows some duration literals.
using namespace std::chrono_literals;
auto constexpr aday=24h;
auto constexpr lesson=45min;
auto constexpr halfanhour=0.5h;
— end example
]
constexpr chrono::hours operator""h(unsigned long long hours); constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);
Returns: A duration literal representing hours hours.
constexpr chrono::minutes operator""min(unsigned long long minutes); constexpr chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);
Returns: A duration literal representing minutes minutes.
constexpr chrono::seconds operator""s(unsigned long long sec); constexpr chrono::duration<unspecified> operator""s(long double sec);
Returns: A duration literal representing sec seconds.
[Note
:
The same suffix s is used for basic_­string but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals.
— end note
]
constexpr chrono::milliseconds operator""ms(unsigned long long msec); constexpr chrono::duration<unspecified, milli> operator""ms(long double msec);
Returns: A duration literal representing msec milliseconds.
constexpr chrono::microseconds operator""us(unsigned long long usec); constexpr chrono::duration<unspecified, micro> operator""us(long double usec);
Returns: A duration literal representing usec microseconds.
constexpr chrono::nanoseconds operator""ns(unsigned long long nsec); constexpr chrono::duration<unspecified, nano> operator""ns(long double nsec);
Returns: A duration literal representing nsec nanoseconds.

27.5.9 Algorithms [time.duration.alg]

template<class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
Constraints: numeric_­limits<Rep>​::​is_­signed is true.
Returns: If d >= d.zero(), return d, otherwise return -d.

27.5.10 I/O [time.duration.io]

template<class charT, class traits, class Rep, class Period> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const duration<Rep, Period>& d);
Effects: Inserts the duration d onto the stream os as if it were implemented as follows:
basic_ostringstream<charT, traits> s;
s.flags(os.flags());
s.imbue(os.getloc());
s.precision(os.precision());
s << d.count() << units-suffix;
return os << s.str();
where units-suffix depends on the type Period​::​type as follows:
  • If Period​::​type is atto, units-suffix is "as".
  • Otherwise, if Period​::​type is femto, units-suffix is "fs".
  • Otherwise, if Period​::​type is pico, units-suffix is "ps".
  • Otherwise, if Period​::​type is nano, units-suffix is "ns".
  • Otherwise, if Period​::​type is micro, it is implementation-defined whether units-suffix is "Ξs" ("\u00b5\u0073") or "us".
  • Otherwise, if Period​::​type is milli, units-suffix is "ms".
  • Otherwise, if Period​::​type is centi, units-suffix is "cs".
  • Otherwise, if Period​::​type is deci, units-suffix is "ds".
  • Otherwise, if Period​::​type is ratio<1>, units-suffix is "s".
  • Otherwise, if Period​::​type is deca, units-suffix is "das".
  • Otherwise, if Period​::​type is hecto, units-suffix is "hs".
  • Otherwise, if Period​::​type is kilo, units-suffix is "ks".
  • Otherwise, if Period​::​type is mega, units-suffix is "Ms".
  • Otherwise, if Period​::​type is giga, units-suffix is "Gs".
  • Otherwise, if Period​::​type is tera, units-suffix is "Ts".
  • Otherwise, if Period​::​type is peta, units-suffix is "Ps".
  • Otherwise, if Period​::​type is exa, units-suffix is "Es".
  • Otherwise, if Period​::​type is ratio<60>, units-suffix is "min".
  • Otherwise, if Period​::​type is ratio<3600>, units-suffix is "h".
  • Otherwise, if Period​::​type is ratio<86400>, units-suffix is "d".
  • Otherwise, if Period​::​type​::​den == 1, units-suffix is "[num]s".
  • Otherwise, units-suffix is "[num/den]s".
In the list above, the use of num and den refer to the static data members of Period​::​type, which are converted to arrays of charT using a decimal conversion with no leading zeroes.
Returns: os.
template<class charT, class traits, class Rep, class Period, class Alloc = allocator<charT>> basic_istream<charT, traits>& from_stream(basic_istream<charT, traits>& is, const charT* fmt, duration<Rep, Period>& d, basic_string<charT, traits, Alloc>* abbrev = nullptr, minutes* offset = nullptr);
Effects: Attempts to parse the input stream is into the duration d using the format flags given in the NTCTS fmt as specified in [time.parse].
If the parse parses everything specified by the parsing format flags without error, and yet none of the flags impacts a duration, d will be assigned a zero value.
If %Z is used and successfully parsed, that value will be assigned to *abbrev if abbrev is non-null.
If %z (or a modified variant) is used and successfully parsed, that value will be assigned to *offset if offset is non-null.
Returns: is.