[time.traits] # 30 Time library [[time]](./#time) ## 30.4 Time-related traits [time.traits] ### [30.4.1](#is.fp) treat_as_floating_point [[time.traits.is.fp]](time.traits.is.fp) [🔗](#lib:treat_as_floating_point) `template struct treat_as_floating_point : is_floating_point { }; ` [1](#is.fp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1071) The duration template uses the treat_as_floating_point trait to help determine if a duration object can be converted to anotherduration with a different tick period[.](#is.fp-1.sentence-1) Iftreat_as_floating_point_v is true, then implicit conversions are allowed among durations[.](#is.fp-1.sentence-2) Otherwise, the implicit convertibility depends on the tick periods of the durations[.](#is.fp-1.sentence-3) [*Note [1](#is.fp-note-1)*: The intention of this trait is to indicate whether a given class behaves like a floating-point type, and thus allows division of one value by another with acceptable loss of precision[.](#is.fp-1.sentence-4) Iftreat_as_floating_point_v is false, Rep will be treated as if it behaved like an integral type for the purpose of these conversions[.](#is.fp-1.sentence-5) — *end note*] ### [30.4.2](#duration.values) duration_values [[time.traits.duration.values]](time.traits.duration.values) [🔗](#lib:duration_values) `template struct duration_values { public: static constexpr Rep zero() noexcept; static constexpr Rep min() noexcept; static constexpr Rep max() noexcept; }; ` [1](#duration.values-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1098) The duration template uses the duration_values trait to construct special values of the duration's representation (Rep)[.](#duration.values-1.sentence-1) This is done because the representation can be a class type with behavior that requires some other implementation to return these special values[.](#duration.values-1.sentence-2) In that case, the author of that class type should specialize duration_values to return the indicated values[.](#duration.values-1.sentence-3) [🔗](#lib:zero,duration_values) `static constexpr Rep zero() noexcept; ` [2](#duration.values-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1112) *Returns*: Rep(0)[.](#duration.values-2.sentence-1) [*Note [1](#duration.values-note-1)*: Rep(0) is specified instead ofRep() because Rep() can have some other meaning, such as an uninitialized value[.](#duration.values-2.sentence-2) — *end note*] [3](#duration.values-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1121) *Remarks*: The value returned shall be the additive identity[.](#duration.values-3.sentence-1) [🔗](#lib:min,duration_values) `static constexpr Rep min() noexcept; ` [4](#duration.values-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1132) *Returns*: numeric_limits​::​lowest()[.](#duration.values-4.sentence-1) [5](#duration.values-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1136) *Remarks*: The value returned shall compare less than or equal to zero()[.](#duration.values-5.sentence-1) [🔗](#lib:max,duration_values) `static constexpr Rep max() noexcept; ` [6](#duration.values-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1147) *Returns*: numeric_limits​::​max()[.](#duration.values-6.sentence-1) [7](#duration.values-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1151) *Remarks*: The value returned shall compare greater than zero()[.](#duration.values-7.sentence-1) ### [30.4.3](#specializations) Specializations of common_type [[time.traits.specializations]](time.traits.specializations) [🔗](#lib:common_type) `template struct common_type, chrono::duration> { using type = chrono::duration, see below>; }; ` [1](#specializations-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1166) The period of the duration indicated by this specialization ofcommon_type is the greatest common divisor of Period1 andPeriod2[.](#specializations-1.sentence-1) [*Note [1](#specializations-note-1)*: This can be computed by forming a ratio of the greatest common divisor of Period1​::​num and Period2​::​num and the least common multiple of Period1​::​den and Period2​::​den[.](#specializations-1.sentence-2) — *end note*] [2](#specializations-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1176) [*Note [2](#specializations-note-2)*: The typedef name type is a synonym for theduration with the largest tick period possible where bothduration arguments will convert to it without requiring a division operation[.](#specializations-2.sentence-1) The representation of this type is intended to be able to hold any value resulting from this conversion with no truncation error, although floating-point durations can have round-off errors[.](#specializations-2.sentence-2) — *end note*] [🔗](#lib:common_type,duration) `template struct common_type, chrono::time_point> { using type = chrono::time_point>; }; ` [3](#specializations-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1194) The common type of two time_point types is a time_point with the same clock as the two types and the common type of their two durations[.](#specializations-3.sentence-1) ### [30.4.4](#is.clock) Class template is_clock [[time.traits.is.clock]](time.traits.is.clock) [🔗](#lib:is_clock) `template struct is_clock; ` [1](#is.clock-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1205) is_clock is a [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements")) with a base characteristic of true_type if T meets the [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3 Cpp17Clock requirements [time.clock.req]") requirements ([[time.clock.req]](time.clock.req "30.3 Cpp17Clock requirements")), otherwise false_type[.](#is.clock-1.sentence-1) For the purposes of the specification of this trait, the extent to which an implementation determines that a type cannot meet the [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3 Cpp17Clock requirements [time.clock.req]") requirements is unspecified, except that as a minimum a type T shall not qualify as a [*Cpp17Clock*](time.clock.req#:Cpp17Clock "30.3 Cpp17Clock requirements [time.clock.req]") unless it meets all of the following conditions: - [(1.1)](#is.clock-1.1) the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")*s*T​::​rep,T​::​period,T​::​duration, andT​::​time_point are valid and each denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")), - [(1.2)](#is.clock-1.2) the expressionT​::​is_steady is well-formed when treated as an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]"), - [(1.3)](#is.clock-1.3) the expressionT​::​now() is well-formed when treated as an unevaluated operand[.](#is.clock-1.sentence-2) [2](#is.clock-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L1231) The behavior of a program that adds specializations for is_clock is undefined[.](#is.clock-2.sentence-1)