Files
2025-10-25 03:02:53 +03:00

1127 lines
46 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[time.clock]
# 30 Time library [[time]](./#time)
## 30.7 Clocks [time.clock]
### [30.7.1](#general) General [[time.clock.general]](time.clock.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2633)
The types defined in [time.clock] meet the[*Cpp17TrivialClock*](time.clock.req#:Cpp17TrivialClock "30.3Cpp17Clock requirements[time.clock.req]") requirements ([[time.clock.req]](time.clock.req "30.3Cpp17Clock requirements"))
unless otherwise specified[.](#general-1.sentence-1)
### [30.7.2](#system) Class system_clock [[time.clock.system]](time.clock.system)
#### [30.7.2.1](#system.overview) Overview [[time.clock.system.overview]](time.clock.system.overview)
namespace std::chrono {class system_clock {public:using rep = *see below*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<system_clock>; static constexpr bool is_steady = *unspecified*; static time_point now() noexcept; // mapping to/from C type time_tstatic time_t to_time_t (const time_point& t) noexcept; static time_point from_time_t(time_t t) noexcept; };}
[1](#system.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2663)
Objects of type system_clock represent wall clock time from the system-wide
realtime clock[.](#system.overview-1.sentence-1)
Objects of type sys_time<Duration> measure time since
1970-01-01 00:00:00 UTC excluding leap seconds[.](#system.overview-1.sentence-2)
This measure is commonly referred to as [*Unix time*](#def:Unix_time "30.7.2.1Overview[time.clock.system.overview]")[.](#system.overview-1.sentence-3)
This measure facilitates an efficient mapping betweensys_time and calendar types ([[time.cal]](time.cal "30.8The civil calendar"))[.](#system.overview-1.sentence-4)
[*Example [1](#system.overview-example-1)*:
sys_seconds{sys_days{1970y/January/1}}.time_since_epoch() is 0s[.](#system.overview-1.sentence-5)
sys_seconds{sys_days{2000y/January/1}}.time_since_epoch() is 946'684'800s,
which is 10'957 * 86'400s[.](#system.overview-1.sentence-6)
— *end example*]
#### [30.7.2.2](#system.members) Members [[time.clock.system.members]](time.clock.system.members)
[🔗](#lib:rep,system_clock)
`using system_clock::rep = unspecified;
`
[1](#system.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2686)
*Constraints*: system_clock::duration::min() < system_clock::duration::zero() is true[.](#system.members-1.sentence-1)
[*Note [1](#system.members-note-1)*:
This implies that rep is a signed type[.](#system.members-1.sentence-2)
— *end note*]
[🔗](#lib:to_time_t,system_clock)
`static time_t to_time_t(const time_point& t) noexcept;
`
[2](#system.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2700)
*Returns*: A time_t object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_t andtime_point[.](#system.members-2.sentence-1)
It is implementation-defined
whether values are rounded or truncated to the required precision[.](#system.members-2.sentence-2)
[🔗](#lib:from_time_t,system_clock)
`static time_point from_time_t(time_t t) noexcept;
`
[3](#system.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2716)
*Returns*: A time_point object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_t andtime_point[.](#system.members-3.sentence-1)
It is implementation-defined
whether values are rounded or truncated to the required precision[.](#system.members-3.sentence-2)
#### [30.7.2.3](#system.nonmembers) Non-member functions [[time.clock.system.nonmembers]](time.clock.system.nonmembers)
[🔗](#lib:operator%3c%3c,sys_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);
`
[1](#system.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2736)
*Constraints*: treat_as_floating_point_v<typename Duration::rep> is false, andDuration{1} < days{1} is true[.](#system.nonmembers-1.sentence-1)
[2](#system.nonmembers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2741)
*Effects*: Equivalent to:return os << format(os.getloc(), *STATICALLY-WIDEN*<charT>("{:L%F %T}"), tp);
[3](#system.nonmembers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2748)
[*Example [1](#system.nonmembers-example-1)*: cout << sys_seconds{0s} << '\n'; // 1970-01-01 00:00:00 cout << sys_seconds{946'684'800s} << '\n'; // 2000-01-01 00:00:00 cout << sys_seconds{946'688'523s} << '\n'; // 2000-01-01 01:02:03 — *end example*]
[🔗](#lib:operator%3c%3c,sys_days)
`template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const sys_days& dp);
`
[4](#system.nonmembers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2766)
*Effects*: os << year_month_day{dp}[.](#system.nonmembers-4.sentence-1)
[5](#system.nonmembers-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2770)
*Returns*: os[.](#system.nonmembers-5.sentence-1)
[🔗](#lib:from_stream,sys_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
sys_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[6](#system.nonmembers-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2785)
*Effects*: Attempts to parse the input stream is into the sys_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#system.nonmembers-6.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#system.nonmembers-6.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#system.nonmembers-6.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#system.nonmembers-6.sentence-4)
Additionally, the parsed offset will be subtracted
from the successfully parsed timestamp
prior to assigning that difference to tp[.](#system.nonmembers-6.sentence-5)
[7](#system.nonmembers-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2802)
*Returns*: is[.](#system.nonmembers-7.sentence-1)
### [30.7.3](#utc) Class utc_clock [[time.clock.utc]](time.clock.utc)
#### [30.7.3.1](#utc.overview) Overview [[time.clock.utc.overview]](time.clock.utc.overview)
namespace std::chrono {class utc_clock {public:using rep = *a signed arithmetic type*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<utc_clock>; static constexpr bool is_steady = *unspecified*; static time_point now(); template<class Duration>static sys_time<common_type_t<Duration, seconds>> to_sys(const utc_time<Duration>& t); template<class Duration>static utc_time<common_type_t<Duration, seconds>> from_sys(const sys_time<Duration>& t); };}
[1](#utc.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2834)
In contrast to sys_time,
which does not take leap seconds into account,utc_clock and its associated time_point, utc_time,
count time, including leap seconds, since 1970-01-01 00:00:00 UTC.
[*Note [1](#utc.overview-note-1)*:
The UTC time standard began on 1972-01-01 00:00:10 TAI.
To measure time since this epoch instead, one can add/subtract the constantsys_days{1972y/1/1} - sys_days{1970y/1/1} (63'072'000s)
from the utc_time[.](#utc.overview-1.sentence-1)
— *end note*]
[*Example [1](#utc.overview-example-1)*:
clock_cast<utc_clock>(sys_seconds{sys_days{1970y/January/1}}).time_since_epoch() is 0s[.](#utc.overview-1.sentence-2)
clock_cast<utc_clock>(sys_seconds{sys_days{2000y/January/1}}).time_since_epoch() is 946'684'822s,
which is 10'957 * 86'400s + 22s[.](#utc.overview-1.sentence-4)
— *end example*]
[2](#utc.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2852)
utc_clock is not a [*Cpp17TrivialClock*](time.clock.req#:Cpp17TrivialClock "30.3Cpp17Clock requirements[time.clock.req]") unless the implementation can guarantee that utc_clock::now() does not propagate an exception[.](#utc.overview-2.sentence-1)
[*Note [2](#utc.overview-note-2)*:
noexcept(from_sys(system_clock::now())) is false[.](#utc.overview-2.sentence-2)
— *end note*]
#### [30.7.3.2](#utc.members) Member functions [[time.clock.utc.members]](time.clock.utc.members)
[🔗](#lib:now,utc_clock)
`static time_point now();
`
[1](#utc.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2868)
*Returns*: from_sys(system_clock::now()), or a more accurate value of utc_time[.](#utc.members-1.sentence-1)
[🔗](#lib:to_sys,utc_clock)
`template<class Duration>
static sys_time<common_type_t<Duration, seconds>>
to_sys(const utc_time<Duration>& u);
`
[2](#utc.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2881)
*Returns*: A sys_time t,
such that from_sys(t) == u if such a mapping exists[.](#utc.members-2.sentence-1)
Otherwise u represents a time_point during a positive leap second insertion,
the conversion counts that leap second as not inserted,
and the last representable value of sys_time prior to the insertion of the leap second is returned[.](#utc.members-2.sentence-2)
[🔗](#lib:from_sys,utc_clock)
`template<class Duration>
static utc_time<common_type_t<Duration, seconds>>
from_sys(const sys_time<Duration>& t);
`
[3](#utc.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2900)
*Returns*: A utc_time u, such thatu.time_since_epoch() - t.time_since_epoch() is equal to the sum of leap seconds that were inserted
between t and 1970-01-01[.](#utc.members-3.sentence-1)
If t is exactly the date of leap second insertion,
then the conversion counts that leap second as inserted[.](#utc.members-3.sentence-2)
[*Example [1](#utc.members-example-1)*: auto t = sys_days{July/1/2015} - 2ns;auto u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s); — *end example*]
#### [30.7.3.3](#utc.nonmembers) Non-member functions [[time.clock.utc.nonmembers]](time.clock.utc.nonmembers)
[🔗](#lib:operator%3c%3c,utc_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const utc_time<Duration>& t);
`
[1](#utc.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2937)
*Effects*: Equivalent to:return os << format(os.getloc(), *STATICALLY-WIDEN*<charT>("{:L%F %T}"), t);
[2](#utc.nonmembers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2944)
[*Example [1](#utc.nonmembers-example-1)*: auto t = sys_days{July/1/2015} - 500ms;auto u = clock_cast<utc_clock>(t);for (auto i = 0; i < 8; ++i, u += 250ms) cout << u << " UTC\n";
Produces this output:
```
2015-06-30 23:59:59.500 UTC
2015-06-30 23:59:59.750 UTC
2015-06-30 23:59:60.000 UTC
2015-06-30 23:59:60.250 UTC
2015-06-30 23:59:60.500 UTC
2015-06-30 23:59:60.750 UTC
2015-07-01 00:00:00.000 UTC
2015-07-01 00:00:00.250 UTC
```
— *end example*]
[🔗](#lib:from_stream,utc_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
utc_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[3](#utc.nonmembers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2977)
*Effects*: Attempts to parse the input stream is into the utc_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#utc.nonmembers-3.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#utc.nonmembers-3.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#utc.nonmembers-3.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#utc.nonmembers-3.sentence-4)
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp
prior to assigning that difference to tp[.](#utc.nonmembers-3.sentence-5)
[4](#utc.nonmembers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L2994)
*Returns*: is[.](#utc.nonmembers-4.sentence-1)
[🔗](#lib:leap_second_info)
`struct leap_second_info {
bool is_leap_second;
seconds elapsed;
};
`
[5](#utc.nonmembers-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3008)
The type leap_second_info has data members and special members specified above[.](#utc.nonmembers-5.sentence-1)
It has no base classes or members other than those specified[.](#utc.nonmembers-5.sentence-2)
[🔗](#lib:get_leap_second_info)
`template<class Duration>
leap_second_info get_leap_second_info(const utc_time<Duration>& ut);
`
[6](#utc.nonmembers-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3021)
*Returns*: A leap_second_info lsi,
where lsi.is_leap_second is true if ut is during a positive leap second insertion, and
otherwise false[.](#utc.nonmembers-6.sentence-1)
lsi.elapsed is the sum of leap seconds between 1970-01-01 and ut[.](#utc.nonmembers-6.sentence-2)
If lsi.is_leap_second is true,
the leap second referred to by ut is included in the sum[.](#utc.nonmembers-6.sentence-3)
### [30.7.4](#tai) Class tai_clock [[time.clock.tai]](time.clock.tai)
#### [30.7.4.1](#tai.overview) Overview [[time.clock.tai.overview]](time.clock.tai.overview)
namespace std::chrono {class tai_clock {public:using rep = *a signed arithmetic type*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<tai_clock>; static constexpr bool is_steady = *unspecified*; static time_point now(); template<class Duration>static utc_time<common_type_t<Duration, seconds>> to_utc(const tai_time<Duration>&) noexcept; template<class Duration>static tai_time<common_type_t<Duration, seconds>> from_utc(const utc_time<Duration>&) noexcept; };}
[1](#tai.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3059)
The clock tai_clock measures seconds since 1958-01-01 00:00:00
and is offset 10s ahead of UTC at this date[.](#tai.overview-1.sentence-1)
That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC[.](#tai.overview-1.sentence-2)
Leap seconds are not inserted into TAI[.](#tai.overview-1.sentence-3)
Therefore every time a leap second is inserted into UTC,
UTC shifts another second with respect to TAI[.](#tai.overview-1.sentence-4)
For example by 2000-01-01 there had been
22 positive and 0 negative leap seconds inserted
so 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI
(22s plus the initial 10s offset)[.](#tai.overview-1.sentence-5)
[2](#tai.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3071)
tai_clock is not a [*Cpp17TrivialClock*](time.clock.req#:Cpp17TrivialClock "30.3Cpp17Clock requirements[time.clock.req]") unless the implementation can guarantee that tai_clock::now() does not propagate an exception[.](#tai.overview-2.sentence-1)
[*Note [1](#tai.overview-note-1)*:
noexcept(from_utc(utc_clock::now())) is false[.](#tai.overview-2.sentence-2)
— *end note*]
#### [30.7.4.2](#tai.members) Member functions [[time.clock.tai.members]](time.clock.tai.members)
[🔗](#lib:now,tai_clock)
`static time_point now();
`
[1](#tai.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3087)
*Returns*: from_utc(utc_clock::now()), or a more accurate value of tai_time[.](#tai.members-1.sentence-1)
[🔗](#lib:to_utc,tai_clock)
`template<class Duration>
static utc_time<common_type_t<Duration, seconds>>
to_utc(const tai_time<Duration>& t) noexcept;
`
[2](#tai.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3100)
*Returns*: utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
[*Note [1](#tai.members-note-1)*: 378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s — *end note*]
[🔗](#lib:from_utc,tai_clock)
`template<class Duration>
static tai_time<common_type_t<Duration, seconds>>
from_utc(const utc_time<Duration>& t) noexcept;
`
[3](#tai.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3120)
*Returns*: tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
[*Note [2](#tai.members-note-2)*: 378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s — *end note*]
#### [30.7.4.3](#tai.nonmembers) Non-member functions [[time.clock.tai.nonmembers]](time.clock.tai.nonmembers)
[🔗](#lib:operator%3c%3c,tai_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& t);
`
[1](#tai.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3142)
*Effects*: Equivalent to:return os << format(os.getloc(), *STATICALLY-WIDEN*<charT>("{:L%F %T}"), t);
[2](#tai.nonmembers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3149)
[*Example [1](#tai.nonmembers-example-1)*: auto st = sys_days{2000y/January/1};auto tt = clock_cast<tai_clock>(st);
cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, tt);
Produces this output:
```
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI
```
— *end example*]
[🔗](#lib:from_stream,tai_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
tai_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[3](#tai.nonmembers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3175)
*Effects*: Attempts to parse the input stream is into the tai_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#tai.nonmembers-3.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#tai.nonmembers-3.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#tai.nonmembers-3.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#tai.nonmembers-3.sentence-4)
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to tp[.](#tai.nonmembers-3.sentence-5)
[4](#tai.nonmembers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3191)
*Returns*: is[.](#tai.nonmembers-4.sentence-1)
### [30.7.5](#gps) Class gps_clock [[time.clock.gps]](time.clock.gps)
#### [30.7.5.1](#gps.overview) Overview [[time.clock.gps.overview]](time.clock.gps.overview)
namespace std::chrono {class gps_clock {public:using rep = *a signed arithmetic type*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<gps_clock>; static constexpr bool is_steady = *unspecified*; static time_point now(); template<class Duration>static utc_time<common_type_t<Duration, seconds>> to_utc(const gps_time<Duration>&) noexcept; template<class Duration>static gps_time<common_type_t<Duration, seconds>> from_utc(const utc_time<Duration>&) noexcept; };}
[1](#gps.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3223)
The clock gps_clock measures
seconds since the first Sunday of January, 1980 00:00:00 UTC[.](#gps.overview-1.sentence-1)
Leap seconds are not inserted into GPS[.](#gps.overview-1.sentence-2)
Therefore every time a leap second is inserted into UTC,
UTC shifts another second with respect to GPS[.](#gps.overview-1.sentence-3)
Aside from the offset from 1958y/January/1 to 1980y/January/Sunday[1],
GPS is behind TAI by 19s due to the 10s offset between 1958 and 1970
and the additional 9 leap seconds inserted between 1970 and 1980[.](#gps.overview-1.sentence-4)
[2](#gps.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3233)
gps_clock is not a [*Cpp17TrivialClock*](time.clock.req#:Cpp17TrivialClock "30.3Cpp17Clock requirements[time.clock.req]") unless the implementation can guarantee thatgps_clock::now() does not propagate an exception[.](#gps.overview-2.sentence-1)
[*Note [1](#gps.overview-note-1)*:
noexcept(from_utc(utc_clock::now())) is false[.](#gps.overview-2.sentence-2)
— *end note*]
#### [30.7.5.2](#gps.members) Member functions [[time.clock.gps.members]](time.clock.gps.members)
[🔗](#lib:now,gps_clock)
`static time_point now();
`
[1](#gps.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3249)
*Returns*: from_utc(utc_clock::now()), or a more accurate value of gps_time[.](#gps.members-1.sentence-1)
[🔗](#lib:to_utc,gps_clock)
`template<class Duration>
static utc_time<common_type_t<Duration, seconds>>
to_utc(const gps_time<Duration>& t) noexcept;
`
[2](#gps.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3262)
*Returns*: utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
[*Note [1](#gps.members-note-1)*: 315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s — *end note*]
[🔗](#lib:from_utc,gps_clock)
`template<class Duration>
static gps_time<common_type_t<Duration, seconds>>
from_utc(const utc_time<Duration>& t) noexcept;
`
[3](#gps.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3282)
*Returns*: gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
[*Note [2](#gps.members-note-2)*: 315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s — *end note*]
#### [30.7.5.3](#gps.nonmembers) Non-member functions [[time.clock.gps.nonmembers]](time.clock.gps.nonmembers)
[🔗](#lib:operator%3c%3c,gps_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const gps_time<Duration>& t);
`
[1](#gps.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3304)
*Effects*: Equivalent to:return os << format(os.getloc(), *STATICALLY-WIDEN*<charT>("{:L%F %T}"), t);
[2](#gps.nonmembers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3311)
[*Example [1](#gps.nonmembers-example-1)*: auto st = sys_days{2000y/January/1};auto gt = clock_cast<gps_clock>(st);
cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, gt);
Produces this output:
```
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS
```
— *end example*]
[🔗](#lib:from_stream,gps_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
gps_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[3](#gps.nonmembers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3337)
*Effects*: Attempts to parse the input stream is into the gps_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#gps.nonmembers-3.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#gps.nonmembers-3.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#gps.nonmembers-3.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#gps.nonmembers-3.sentence-4)
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to tp[.](#gps.nonmembers-3.sentence-5)
[4](#gps.nonmembers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3353)
*Returns*: is[.](#gps.nonmembers-4.sentence-1)
### [30.7.6](#file) Type file_clock [[time.clock.file]](time.clock.file)
#### [30.7.6.1](#file.overview) Overview [[time.clock.file.overview]](time.clock.file.overview)
namespace std::chrono {using file_clock = *see below*;}
[1](#file.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3369)
file_clock is an alias for a type
meeting the [*Cpp17TrivialClock*](time.clock.req#:Cpp17TrivialClock "30.3Cpp17Clock requirements[time.clock.req]") requirements ([[time.clock.req]](time.clock.req "30.3Cpp17Clock requirements")), and
using a signed arithmetic type for file_clock::rep[.](#file.overview-1.sentence-1)
file_clock is used to create the time_point system
used for file_time_type ([[filesystems]](filesystems "31.12File systems"))[.](#file.overview-1.sentence-2)
Its epoch is unspecified, andnoexcept(file_clock::now()) is true[.](#file.overview-1.sentence-3)
[*Note [1](#file.overview-note-1)*:
The type that file_clock denotes can be
in a different namespace than std::chrono,
such as std::filesystem[.](#file.overview-1.sentence-4)
— *end note*]
#### [30.7.6.2](#file.members) Member functions [[time.clock.file.members]](time.clock.file.members)
[1](#file.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3386)
The type denoted by file_clock provides
precisely one of the following two sets of static member functions:template<class Duration>static sys_time<*see below*> to_sys(const file_time<Duration>&);template<class Duration>static file_time<*see below*> from_sys(const sys_time<Duration>&); or:template<class Duration>static utc_time<*see below*> to_utc(const file_time<Duration>&);template<class Duration>static file_time<*see below*> from_utc(const utc_time<Duration>&);
These member functions shall provide time_point conversions
consistent with those specified byutc_clock, tai_clock, and gps_clock[.](#file.members-1.sentence-2)
The Duration of the resultant time_point is computed from the Duration of the input time_point[.](#file.members-1.sentence-3)
#### [30.7.6.3](#file.nonmembers) Non-member functions [[time.clock.file.nonmembers]](time.clock.file.nonmembers)
[🔗](#lib:operator%3c%3c,file_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& t);
`
[1](#file.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3423)
*Effects*: Equivalent to:return os << format(os.getloc(), *STATICALLY-WIDEN*<charT>("{:L%F %T}"), t);
[🔗](#lib:from_stream,file_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
file_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[2](#file.nonmembers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3441)
*Effects*: Attempts to parse the input stream is into the file_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#file.nonmembers-2.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#file.nonmembers-2.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#file.nonmembers-2.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#file.nonmembers-2.sentence-4)
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to tp[.](#file.nonmembers-2.sentence-5)
[3](#file.nonmembers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3457)
*Returns*: is[.](#file.nonmembers-3.sentence-1)
### [30.7.7](#steady) Class steady_clock [[time.clock.steady]](time.clock.steady)
namespace std::chrono {class steady_clock {public:using rep = *unspecified*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<*unspecified*, duration>; static constexpr bool is_steady = true; static time_point now() noexcept; };}
[1](#steady-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3480)
Objects of class steady_clock represent clocks for which values of time_point never decrease as physical time advances and for which values of time_point advance at
a steady rate relative to real time[.](#steady-1.sentence-1)
That is, the clock may not be adjusted[.](#steady-1.sentence-2)
### [30.7.8](#hires) Class high_resolution_clock [[time.clock.hires]](time.clock.hires)
namespace std::chrono {class high_resolution_clock {public:using rep = *unspecified*; using period = ratio<*unspecified*, *unspecified*>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<*unspecified*, duration>; static constexpr bool is_steady = *unspecified*; static time_point now() noexcept; };}
[1](#hires-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3503)
Objects of class high_resolution_clock represent clocks with the
shortest tick period[.](#hires-1.sentence-1)
high_resolution_clock may be a synonym forsystem_clock or steady_clock[.](#hires-1.sentence-2)
### [30.7.9](#local) Local time [[time.clock.local]](time.clock.local)
[1](#local-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3511)
The family of time points
denoted by local_time<Duration> are based on the pseudo clock local_t[.](#local-1.sentence-1)
local_t has no member now() and thus does not meet the clock requirements[.](#local-1.sentence-2)
Nevertheless local_time<Duration> serves the vital role of
representing local time with respect to a not-yet-specified time zone[.](#local-1.sentence-3)
Aside from being able to get the current time,
the complete time_point algebra is available
for local_time<Duration> (just as for sys_time<Duration>)[.](#local-1.sentence-4)
[🔗](#lib:operator%3c%3c,local_time)
`template<class charT, class traits, class Duration>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& lt);
`
[2](#local-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3531)
*Effects*: os << sys_time<Duration>{lt.time_since_epoch()};
[3](#local-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3537)
*Returns*: os[.](#local-3.sentence-1)
[🔗](#lib:from_stream,local_time)
`template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
basic_istream<charT, traits>&
from_stream(basic_istream<charT, traits>& is, const charT* fmt,
local_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
minutes* offset = nullptr);
`
[4](#local-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3552)
*Effects*: Attempts to parse the input stream is into the local_time tp using
the format flags given in the NTCTS fmt as specified in [[time.parse]](time.parse "30.13Parsing")[.](#local-4.sentence-1)
If the parse fails to decode a valid date,is.setstate(ios_base::failbit) is called andtp is not modified[.](#local-4.sentence-2)
If %Z is used and successfully parsed,
that value will be assigned to *abbrev if abbrev is non-null[.](#local-4.sentence-3)
If %z (or a modified variant) is used and successfully parsed,
that value will be assigned to *offset if offset is non-null[.](#local-4.sentence-4)
[5](#local-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3566)
*Returns*: is[.](#local-5.sentence-1)
### [30.7.10](#cast) time_point conversions [[time.clock.cast]](time.clock.cast)
#### [30.7.10.1](#conv) Class template clock_time_conversion [[time.clock.conv]](time.clock.conv)
namespace std::chrono {template<class DestClock, class SourceClock>struct clock_time_conversion {};}
[1](#conv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3583)
clock_time_conversion serves as a trait
which can be used to specify how to convert
a source time_point of typetime_point<SourceClock, Duration> to a destination time_point of typetime_point<DestClock, Duration> via a specialization:clock_time_conversion<DestClock, SourceClock>[.](#conv-1.sentence-1)
A specialization of clock_time_conversion<DestClock, SourceClock> shall provide a const-qualified operator() that takes a parameter of type time_point<SourceClock, Duration> and returns a time_point<DestClock, OtherDuration> representing an equivalent point in time[.](#conv-1.sentence-2)
OtherDuration is a chrono::duration whose specialization is computed from the input Duration in a manner which can vary for each clock_time_conversion specialization[.](#conv-1.sentence-3)
A program may specialize clock_time_conversion if at least one of the template parameters is a user-defined clock type[.](#conv-1.sentence-4)
[2](#conv-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3603)
Several specializations are provided by the implementation,
as described in[[time.clock.cast.id]](#cast.id "30.7.10.2Identity conversions"),[[time.clock.cast.sys.utc]](#cast.sys.utc "30.7.10.3Conversions between system_­clock and utc_­clock"),[[time.clock.cast.sys]](#cast.sys "30.7.10.4Conversions between system_­clock and other clocks"), and[[time.clock.cast.utc]](#cast.utc "30.7.10.5Conversions between utc_­clock and other clocks")[.](#conv-2.sentence-1)
#### [30.7.10.2](#cast.id) Identity conversions [[time.clock.cast.id]](time.clock.cast.id)
template<class Clock>struct clock_time_conversion<Clock, Clock> {template<class Duration> time_point<Clock, Duration>operator()(const time_point<Clock, Duration>& t) const;};
[🔗](#lib:operator(),clock_time_conversion)
`template<class Duration>
time_point<Clock, Duration>
operator()(const time_point<Clock, Duration>& t) const;
`
[1](#cast.id-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3630)
*Returns*: t[.](#cast.id-1.sentence-1)
template<>struct clock_time_conversion<system_clock, system_clock> {template<class Duration> sys_time<Duration>operator()(const sys_time<Duration>& t) const;};
[🔗](#lib:operator(),clock_time_conversion_)
`template<class Duration>
sys_time<Duration>
operator()(const sys_time<Duration>& t) const;
`
[2](#cast.id-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3652)
*Returns*: t[.](#cast.id-2.sentence-1)
template<>struct clock_time_conversion<utc_clock, utc_clock> {template<class Duration> utc_time<Duration>operator()(const utc_time<Duration>& t) const;};
[🔗](#lib:operator(),clock_time_conversion__)
`template<class Duration>
utc_time<Duration>
operator()(const utc_time<Duration>& t) const;
`
[3](#cast.id-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3674)
*Returns*: t[.](#cast.id-3.sentence-1)
#### [30.7.10.3](#cast.sys.utc) Conversions between system_clock and utc_clock [[time.clock.cast.sys.utc]](time.clock.cast.sys.utc)
template<>struct clock_time_conversion<utc_clock, system_clock> {template<class Duration> utc_time<common_type_t<Duration, seconds>>operator()(const sys_time<Duration>& t) const;};
[🔗](#lib:operator(),clock_time_conversion___)
`template<class Duration>
utc_time<common_type_t<Duration, seconds>>
operator()(const sys_time<Duration>& t) const;
`
[1](#cast.sys.utc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3698)
*Returns*: utc_clock::from_sys(t)[.](#cast.sys.utc-1.sentence-1)
template<>struct clock_time_conversion<system_clock, utc_clock> {template<class Duration> sys_time<common_type_t<Duration, seconds>>operator()(const utc_time<Duration>& t) const;};
[🔗](#lib:operator(),clock_time_conversion____)
`template<class Duration>
sys_time<common_type_t<Duration, seconds>>
operator()(const utc_time<Duration>& t) const;
`
[2](#cast.sys.utc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3720)
*Returns*: utc_clock::to_sys(t)[.](#cast.sys.utc-2.sentence-1)
#### [30.7.10.4](#cast.sys) Conversions between system_clock and other clocks [[time.clock.cast.sys]](time.clock.cast.sys)
template<class SourceClock>struct clock_time_conversion<system_clock, SourceClock> {template<class Duration>auto operator()(const time_point<SourceClock, Duration>& t) const-> decltype(SourceClock::to_sys(t));};
[🔗](#lib:operator(),clock_time_conversion_____)
`template<class Duration>
auto operator()(const time_point<SourceClock, Duration>& t) const
-> decltype(SourceClock::to_sys(t));
`
[1](#cast.sys-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3744)
*Constraints*: SourceClock::to_sys(t) is well-formed[.](#cast.sys-1.sentence-1)
[2](#cast.sys-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3748)
*Mandates*: SourceClock::to_sys(t) returns a sys_time<Duration2> for some type Duration2 ([[time.point.general]](time.point.general "30.6.1General"))[.](#cast.sys-2.sentence-1)
[3](#cast.sys-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3753)
*Returns*: SourceClock::to_sys(t)[.](#cast.sys-3.sentence-1)
template<class DestClock>struct clock_time_conversion<DestClock, system_clock> {template<class Duration>auto operator()(const sys_time<Duration>& t) const-> decltype(DestClock::from_sys(t));};
[🔗](#lib:operator(),clock_time_conversion______)
`template<class Duration>
auto operator()(const sys_time<Duration>& t) const
-> decltype(DestClock::from_sys(t));
`
[4](#cast.sys-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3775)
*Constraints*: DestClock::from_sys(t) is well-formed[.](#cast.sys-4.sentence-1)
[5](#cast.sys-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3779)
*Mandates*: DestClock::from_sys(t) returns a time_point<DestClock, Duration2> for some type Duration2 ([[time.point.general]](time.point.general "30.6.1General"))[.](#cast.sys-5.sentence-1)
[6](#cast.sys-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3784)
*Returns*: DestClock::from_sys(t)[.](#cast.sys-6.sentence-1)
#### [30.7.10.5](#cast.utc) Conversions between utc_clock and other clocks [[time.clock.cast.utc]](time.clock.cast.utc)
template<class SourceClock>struct clock_time_conversion<utc_clock, SourceClock> {template<class Duration>auto operator()(const time_point<SourceClock, Duration>& t) const-> decltype(SourceClock::to_utc(t));};
[🔗](#lib:operator(),clock_time_conversion_______)
`template<class Duration>
auto operator()(const time_point<SourceClock, Duration>& t) const
-> decltype(SourceClock::to_utc(t));
`
[1](#cast.utc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3808)
*Constraints*: SourceClock::to_utc(t) is well-formed[.](#cast.utc-1.sentence-1)
[2](#cast.utc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3812)
*Mandates*: SourceClock::to_utc(t) returns a utc_time<Duration2> for some type Duration2 ([[time.point.general]](time.point.general "30.6.1General"))[.](#cast.utc-2.sentence-1)
[3](#cast.utc-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3817)
*Returns*: SourceClock::to_utc(t)[.](#cast.utc-3.sentence-1)
template<class DestClock>struct clock_time_conversion<DestClock, utc_clock> {template<class Duration>auto operator()(const utc_time<Duration>& t) const-> decltype(DestClock::from_utc(t));};
[🔗](#lib:operator(),clock_time_conversion________)
`template<class Duration>
auto operator()(const utc_time<Duration>& t) const
-> decltype(DestClock::from_utc(t));
`
[4](#cast.utc-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3839)
*Constraints*: DestClock::from_utc(t) is well-formed[.](#cast.utc-4.sentence-1)
[5](#cast.utc-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3843)
*Mandates*: DestClock::from_utc(t) returns a time_point<DestClock, Duration2> for some type Duration2 ([[time.point.general]](time.point.general "30.6.1General"))[.](#cast.utc-5.sentence-1)
[6](#cast.utc-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3848)
*Returns*: DestClock::from_utc(t)[.](#cast.utc-6.sentence-1)
#### [30.7.10.6](#cast.fn) Function template clock_cast [[time.clock.cast.fn]](time.clock.cast.fn)
[🔗](#lib:clock_cast)
`template<class DestClock, class SourceClock, class Duration>
auto clock_cast(const time_point<SourceClock, Duration>& t);
`
[1](#cast.fn-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3862)
*Constraints*: At least one of the following clock time conversion expressions
is well-formed:
- [(1.1)](#cast.fn-1.1)
clock_time_conversion<DestClock, SourceClock>{}(t)
- [(1.2)](#cast.fn-1.2)
clock_time_conversion<DestClock, system_clock>{}( clock_time_conversion<system_clock, SourceClock>{}(t))
- [(1.3)](#cast.fn-1.3)
clock_time_conversion<DestClock, utc_clock>{}( clock_time_conversion<utc_clock, SourceClock>{}(t))
- [(1.4)](#cast.fn-1.4)
clock_time_conversion<DestClock, utc_clock>{}( clock_time_conversion<utc_clock, system_clock>{}( clock_time_conversion<system_clock, SourceClock>{}(t)))
- [(1.5)](#cast.fn-1.5)
clock_time_conversion<DestClock, system_clock>{}( clock_time_conversion<system_clock, utc_clock>{}( clock_time_conversion<utc_clock, SourceClock>{}(t)))
A clock time conversion expression is considered better than
another clock time conversion expression if it involves feweroperator() calls on clock_time_conversion specializations[.](#cast.fn-1.sentence-2)
[2](#cast.fn-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3904)
*Mandates*: Among the well-formed clock time conversion expressions
from the above list, there is a unique best expression[.](#cast.fn-2.sentence-1)
[3](#cast.fn-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L3909)
*Returns*: The best well-formed clock time conversion expression in the above list[.](#cast.fn-3.sentence-1)