From Jason Turner

[time.clock]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpkh1arq3r/{from.md → to.md} +950 -23
tmp/tmpkh1arq3r/{from.md → to.md} RENAMED
@@ -1,39 +1,54 @@
1
- ### Clocks <a id="time.clock">[[time.clock]]</a>
2
 
3
- The types defined in this subclause shall satisfy the `TrivialClock`
4
- requirements ([[time.clock.req]]).
5
 
6
- #### Class `system_clock` <a id="time.clock.system">[[time.clock.system]]</a>
7
 
8
- Objects of class `system_clock` represent wall clock time from the
9
- system-wide realtime clock.
10
 
11
  ``` cpp
 
12
  class system_clock {
13
  public:
14
  using rep = see below;
15
  using period = ratio<unspecified, unspecified{}>;
16
  using duration = chrono::duration<rep, period>;
17
  using time_point = chrono::time_point<system_clock>;
18
  static constexpr bool is_steady = unspecified;
19
 
20
  static time_point now() noexcept;
21
 
22
- // Map to C API
23
  static time_t to_time_t (const time_point& t) noexcept;
24
  static time_point from_time_t(time_t t) noexcept;
25
  };
 
26
  ```
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  ``` cpp
29
  using system_clock::rep = unspecified;
30
  ```
31
 
32
- *Requires:*
33
- `system_clock::duration::min() < system_clock::duration::zero()` shall
34
- be `true`.
35
 
36
  [*Note 1*: This implies that `rep` is a signed type. — *end note*]
37
 
38
  ``` cpp
39
  static time_t to_time_t(const time_point& t) noexcept;
@@ -51,44 +66,956 @@ static time_point from_time_t(time_t t) noexcept;
51
  *Returns:* A `time_point` object that represents the same point in time
52
  as `t` when both values are restricted to the coarser of the precisions
53
  of `time_t` and `time_point`. It is *implementation-defined* whether
54
  values are rounded or truncated to the required precision.
55
 
56
- #### Class `steady_clock` <a id="time.clock.steady">[[time.clock.steady]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  Objects of class `steady_clock` represent clocks for which values of
59
  `time_point` never decrease as physical time advances and for which
60
  values of `time_point` advance at a steady rate relative to real time.
61
  That is, the clock may not be adjusted.
62
 
 
 
63
  ``` cpp
64
- class steady_clock {
 
65
  public:
66
  using rep = unspecified;
67
  using period = ratio<unspecified, unspecified{}>;
68
  using duration = chrono::duration<rep, period>;
69
  using time_point = chrono::time_point<unspecified, duration>;
70
- static constexpr bool is_steady = true;
71
 
72
  static time_point now() noexcept;
73
  };
 
74
  ```
75
 
76
- #### Class `high_resolution_clock` <a id="time.clock.hires">[[time.clock.hires]]</a>
77
-
78
  Objects of class `high_resolution_clock` represent clocks with the
79
  shortest tick period. `high_resolution_clock` may be a synonym for
80
  `system_clock` or `steady_clock`.
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  ``` cpp
83
- class high_resolution_clock {
84
- public:
85
- using rep = unspecified;
86
- using period = ratio<unspecified, unspecified{}>;
87
- using duration = chrono::duration<rep, period>;
88
- using time_point = chrono::time_point<unspecified, duration>;
89
- static constexpr bool is_steady = unspecified;
90
 
91
- static time_point now() noexcept;
 
 
 
 
 
 
 
92
  };
93
  ```
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Clocks <a id="time.clock">[[time.clock]]</a>
2
 
3
+ The types defined in this subclause meet the *Cpp17TrivialClock*
4
+ requirements [[time.clock.req]] unless otherwise specified.
5
 
6
+ ### Class `system_clock` <a id="time.clock.system">[[time.clock.system]]</a>
7
 
8
+ #### Overview <a id="time.clock.system.overview">[[time.clock.system.overview]]</a>
 
9
 
10
  ``` cpp
11
+ namespace std::chrono {
12
  class system_clock {
13
  public:
14
  using rep = see below;
15
  using period = ratio<unspecified, unspecified{}>;
16
  using duration = chrono::duration<rep, period>;
17
  using time_point = chrono::time_point<system_clock>;
18
  static constexpr bool is_steady = unspecified;
19
 
20
  static time_point now() noexcept;
21
 
22
+ // mapping to/from C type time_t
23
  static time_t to_time_t (const time_point& t) noexcept;
24
  static time_point from_time_t(time_t t) noexcept;
25
  };
26
+ }
27
  ```
28
 
29
+ Objects of type `system_clock` represent wall clock time from the
30
+ system-wide realtime clock. Objects of type `sys_time<Duration>` measure
31
+ time since 1970-01-01 00:00:00 UTC excluding leap seconds. This measure
32
+ is commonly referred to as *Unix time*. This measure facilitates an
33
+ efficient mapping between `sys_time` and calendar types [[time.cal]].
34
+
35
+ [*Example 1*:
36
+ `sys_seconds{sys_days{1970y/January/1}}.time_since_epoch()` is `0s`.
37
+ `sys_seconds{sys_days{2000y/January/1}}.time_since_epoch()` is
38
+ `946'684'800s`, which is `10'957 * 86'400s`.
39
+ — *end example*]
40
+
41
+ #### Members <a id="time.clock.system.members">[[time.clock.system.members]]</a>
42
+
43
  ``` cpp
44
  using system_clock::rep = unspecified;
45
  ```
46
 
47
+ *Constraints:*
48
+ `system_clock::duration::min() < system_clock::duration::zero()` is
49
+ `true`.
50
 
51
  [*Note 1*: This implies that `rep` is a signed type. — *end note*]
52
 
53
  ``` cpp
54
  static time_t to_time_t(const time_point& t) noexcept;
 
66
  *Returns:* A `time_point` object that represents the same point in time
67
  as `t` when both values are restricted to the coarser of the precisions
68
  of `time_t` and `time_point`. It is *implementation-defined* whether
69
  values are rounded or truncated to the required precision.
70
 
71
+ #### Non-member functions <a id="time.clock.system.nonmembers">[[time.clock.system.nonmembers]]</a>
72
+
73
+ ``` cpp
74
+ template<class charT, class traits, class Duration>
75
+ basic_ostream<charT, traits>&
76
+ operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);
77
+ ```
78
+
79
+ *Constraints:* `treat_as_floating_point_v<typename Duration::rep>` is
80
+ `false`, and `Duration{1} < days{1}` is `true`.
81
+
82
+ *Effects:* Equivalent to:
83
+
84
+ ``` cpp
85
+ auto const dp = floor<days>(tp);
86
+ return os << format(os.getloc(), STATICALLY-WIDEN<charT>("{} {}"),
87
+ year_month_day{dp}, hh_mm_ss{tp-dp});
88
+ ```
89
+
90
+ [*Example 1*:
91
+
92
+ ``` cpp
93
+ cout << sys_seconds{0s} << '\n'; // 1970-01-01 00:00:00
94
+ cout << sys_seconds{946'684'800s} << '\n'; // 2000-01-01 00:00:00
95
+ cout << sys_seconds{946'688'523s} << '\n'; // 2000-01-01 01:02:03
96
+ ```
97
+
98
+ — *end example*]
99
+
100
+ ``` cpp
101
+ template<class charT, class traits>
102
+ basic_ostream<charT, traits>&
103
+ operator<<(basic_ostream<charT, traits>& os, const sys_days& dp);
104
+ ```
105
+
106
+ *Effects:* `os << year_month_day{dp}`.
107
+
108
+ *Returns:* `os`.
109
+
110
+ ``` cpp
111
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
112
+ basic_istream<charT, traits>&
113
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
114
+ sys_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
115
+ minutes* offset = nullptr);
116
+ ```
117
+
118
+ *Effects:* Attempts to parse the input stream `is` into the `sys_time`
119
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
120
+ [[time.parse]]. If the parse fails to decode a valid date,
121
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
122
+ `%Z` is used and successfully parsed, that value will be assigned to
123
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
124
+ used and successfully parsed, that value will be assigned to `*offset`
125
+ if `offset` is non-null. Additionally, the parsed offset will be
126
+ subtracted from the successfully parsed timestamp prior to assigning
127
+ that difference to `tp`.
128
+
129
+ *Returns:* `is`.
130
+
131
+ ### Class `utc_clock` <a id="time.clock.utc">[[time.clock.utc]]</a>
132
+
133
+ #### Overview <a id="time.clock.utc.overview">[[time.clock.utc.overview]]</a>
134
+
135
+ ``` cpp
136
+ namespace std::chrono {
137
+ class utc_clock {
138
+ public:
139
+ using rep = a signed arithmetic type;
140
+ using period = ratio<unspecified, unspecified>;
141
+ using duration = chrono::duration<rep, period>;
142
+ using time_point = chrono::time_point<utc_clock>;
143
+ static constexpr bool is_steady = unspecified;
144
+
145
+ static time_point now();
146
+
147
+ template<class Duration>
148
+ static sys_time<common_type_t<Duration, seconds>>
149
+ to_sys(const utc_time<Duration>& t);
150
+ template<class Duration>
151
+ static utc_time<common_type_t<Duration, seconds>>
152
+ from_sys(const sys_time<Duration>& t);
153
+ };
154
+ }
155
+ ```
156
+
157
+ In contrast to `sys_time`, which does not take leap seconds into
158
+ account, `utc_clock` and its associated `time_point`, `utc_time`, count
159
+ time, including leap seconds, since 1970-01-01 00:00:00 UTC.
160
+
161
+ [*Note 1*: The UTC time standard began on 1972-01-01 00:00:10 TAI. To
162
+ measure time since this epoch instead, one can add/subtract the constant
163
+ `sys_days{1972y/1/1} - sys_days{1970y/1/1}` (`63'072'000s`) from the
164
+ `utc_time`. — *end note*]
165
+
166
+ [*Example 1*:
167
+ `clock_cast<utc_clock>(sys_seconds{sys_days{1970y/January/1}}).time_since_epoch()`
168
+ is `0s`.
169
+ `clock_cast<utc_clock>(sys_seconds{sys_days{2000y/January/1}}).time_since_epoch()`
170
+ is `946'684'822s`, which is `10'957 * 86'400s + 22s`.
171
+ — *end example*]
172
+
173
+ `utc_clock` is not a *Cpp17TrivialClock* unless the implementation can
174
+ guarantee that `utc_clock::now()` does not propagate an exception.
175
+
176
+ [*Note 2*: `noexcept(from_sys(system_clock::now()))` is
177
+ `false`. — *end note*]
178
+
179
+ #### Member functions <a id="time.clock.utc.members">[[time.clock.utc.members]]</a>
180
+
181
+ ``` cpp
182
+ static time_point now();
183
+ ```
184
+
185
+ *Returns:* `from_sys(system_clock::now())`, or a more accurate value of
186
+ `utc_time`.
187
+
188
+ ``` cpp
189
+ template<class Duration>
190
+ static sys_time<common_type_t<Duration, seconds>>
191
+ to_sys(const utc_time<Duration>& u);
192
+ ```
193
+
194
+ *Returns:* A `sys_time` `t`, such that `from_sys(t) == u` if such a
195
+ mapping exists. Otherwise `u` represents a `time_point` during a
196
+ positive leap second insertion, the conversion counts that leap second
197
+ as not inserted, and the last representable value of `sys_time` prior to
198
+ the insertion of the leap second is returned.
199
+
200
+ ``` cpp
201
+ template<class Duration>
202
+ static utc_time<common_type_t<Duration, seconds>>
203
+ from_sys(const sys_time<Duration>& t);
204
+ ```
205
+
206
+ *Returns:* A `utc_time` `u`, such that
207
+ `u.time_since_epoch() - t.time_since_epoch()` is equal to the sum of
208
+ leap seconds that were inserted between `t` and 1970-01-01. If `t` is
209
+ exactly the date of leap second insertion, then the conversion counts
210
+ that leap second as inserted.
211
+
212
+ [*Example 1*:
213
+
214
+ ``` cpp
215
+ auto t = sys_days{July/1/2015} - 2ns;
216
+ auto u = utc_clock::from_sys(t);
217
+ assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
218
+ t += 1ns;
219
+ u = utc_clock::from_sys(t);
220
+ assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
221
+ t += 1ns;
222
+ u = utc_clock::from_sys(t);
223
+ assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
224
+ t += 1ns;
225
+ u = utc_clock::from_sys(t);
226
+ assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
227
+ ```
228
+
229
+ — *end example*]
230
+
231
+ #### Non-member functions <a id="time.clock.utc.nonmembers">[[time.clock.utc.nonmembers]]</a>
232
+
233
+ ``` cpp
234
+ template<class charT, class traits, class Duration>
235
+ basic_ostream<charT, traits>&
236
+ operator<<(basic_ostream<charT, traits>& os, const utc_time<Duration>& t);
237
+ ```
238
+
239
+ *Effects:* Equivalent to:
240
+
241
+ ``` cpp
242
+ return os << format(STATICALLY-WIDEN<charT>("{:%F %T}"), t);
243
+ ```
244
+
245
+ [*Example 1*:
246
+
247
+ ``` cpp
248
+ auto t = sys_days{July/1/2015} - 500ms;
249
+ auto u = clock_cast<utc_clock>(t);
250
+ for (auto i = 0; i < 8; ++i, u += 250ms)
251
+ cout << u << " UTC\n";
252
+ ```
253
+
254
+ Produces this output:
255
+
256
+ ``` text
257
+ 2015-06-30 23:59:59.500 UTC
258
+ 2015-06-30 23:59:59.750 UTC
259
+ 2015-06-30 23:59:60.000 UTC
260
+ 2015-06-30 23:59:60.250 UTC
261
+ 2015-06-30 23:59:60.500 UTC
262
+ 2015-06-30 23:59:60.750 UTC
263
+ 2015-07-01 00:00:00.000 UTC
264
+ 2015-07-01 00:00:00.250 UTC
265
+ ```
266
+
267
+ — *end example*]
268
+
269
+ ``` cpp
270
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
271
+ basic_istream<charT, traits>&
272
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
273
+ utc_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
274
+ minutes* offset = nullptr);
275
+ ```
276
+
277
+ *Effects:* Attempts to parse the input stream `is` into the `utc_time`
278
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
279
+ [[time.parse]]. If the parse fails to decode a valid date,
280
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
281
+ `%Z` is used and successfully parsed, that value will be assigned to
282
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
283
+ used and successfully parsed, that value will be assigned to `*offset`
284
+ if `offset` is non-null. Additionally, the parsed offset will be
285
+ subtracted from the successfully parsed timestamp prior to assigning
286
+ that difference to `tp`.
287
+
288
+ *Returns:* `is`.
289
+
290
+ ``` cpp
291
+ struct leap_second_info {
292
+ bool is_leap_second;
293
+ seconds elapsed;
294
+ };
295
+ ```
296
+
297
+ The type `leap_second_info` has data members and special members
298
+ specified above. It has no base classes or members other than those
299
+ specified.
300
+
301
+ ``` cpp
302
+ template<class Duration>
303
+ leap_second_info get_leap_second_info(const utc_time<Duration>& ut);
304
+ ```
305
+
306
+ *Returns:* A `leap_second_info` `lsi`, where `lsi.is_leap_second` is
307
+ `true` if `ut` is during a positive leap second insertion, and otherwise
308
+ `false`. `lsi.elapsed` is the sum of leap seconds between 1970-01-01 and
309
+ `ut`. If `lsi.is_leap_second` is `true`, the leap second referred to by
310
+ `ut` is included in the sum.
311
+
312
+ ### Class `tai_clock` <a id="time.clock.tai">[[time.clock.tai]]</a>
313
+
314
+ #### Overview <a id="time.clock.tai.overview">[[time.clock.tai.overview]]</a>
315
+
316
+ ``` cpp
317
+ namespace std::chrono {
318
+ class tai_clock {
319
+ public:
320
+ using rep = a signed arithmetic type;
321
+ using period = ratio<unspecified, unspecified>;
322
+ using duration = chrono::duration<rep, period>;
323
+ using time_point = chrono::time_point<tai_clock>;
324
+ static constexpr bool is_steady = unspecified;
325
+
326
+ static time_point now();
327
+
328
+ template<class Duration>
329
+ static utc_time<common_type_t<Duration, seconds>>
330
+ to_utc(const tai_time<Duration>&) noexcept;
331
+ template<class Duration>
332
+ static tai_time<common_type_t<Duration, seconds>>
333
+ from_utc(const utc_time<Duration>&) noexcept;
334
+ };
335
+ }
336
+ ```
337
+
338
+ The clock `tai_clock` measures seconds since 1958-01-01 00:00:00 and is
339
+ offset 10s ahead of UTC at this date. That is, 1958-01-01 00:00:00 TAI
340
+ is equivalent to 1957-12-31 23:59:50 UTC. Leap seconds are not inserted
341
+ into TAI. Therefore every time a leap second is inserted into UTC, UTC
342
+ shifts another second with respect to TAI. For example by 2000-01-01
343
+ there had been 22 positive and 0 negative leap seconds inserted so
344
+ 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI (22s
345
+ plus the initial 10s offset).
346
+
347
+ `tai_clock` is not a *Cpp17TrivialClock* unless the implementation can
348
+ guarantee that `tai_clock::now()` does not propagate an exception.
349
+
350
+ [*Note 1*: `noexcept(from_utc(utc_clock::now()))` is
351
+ `false`. — *end note*]
352
+
353
+ #### Member functions <a id="time.clock.tai.members">[[time.clock.tai.members]]</a>
354
+
355
+ ``` cpp
356
+ static time_point now();
357
+ ```
358
+
359
+ *Returns:* `from_utc(utc_clock::now())`, or a more accurate value of
360
+ `tai_time`.
361
+
362
+ ``` cpp
363
+ template<class Duration>
364
+ static utc_time<common_type_t<Duration, seconds>>
365
+ to_utc(const tai_time<Duration>& t) noexcept;
366
+ ```
367
+
368
+ *Returns:*
369
+
370
+ ``` cpp
371
+ utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
372
+ ```
373
+
374
+ [*Note 1*:
375
+
376
+ ``` cpp
377
+ 378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s
378
+ ```
379
+
380
+ — *end note*]
381
+
382
+ ``` cpp
383
+ template<class Duration>
384
+ static tai_time<common_type_t<Duration, seconds>>
385
+ from_utc(const utc_time<Duration>& t) noexcept;
386
+ ```
387
+
388
+ *Returns:*
389
+
390
+ ``` cpp
391
+ tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
392
+ ```
393
+
394
+ [*Note 2*:
395
+
396
+ ``` cpp
397
+ 378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s
398
+ ```
399
+
400
+ — *end note*]
401
+
402
+ #### Non-member functions <a id="time.clock.tai.nonmembers">[[time.clock.tai.nonmembers]]</a>
403
+
404
+ ``` cpp
405
+ template<class charT, class traits, class Duration>
406
+ basic_ostream<charT, traits>&
407
+ operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& t);
408
+ ```
409
+
410
+ *Effects:* Equivalent to:
411
+
412
+ ``` cpp
413
+ return os << format(STATICALLY-WIDEN<charT>("{:%F %T}"), t);
414
+ ```
415
+
416
+ [*Example 1*:
417
+
418
+ ``` cpp
419
+ auto st = sys_days{2000y/January/1};
420
+ auto tt = clock_cast<tai_clock>(st);
421
+ cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, tt);
422
+ ```
423
+
424
+ Produces this output:
425
+
426
+ ``` text
427
+ 2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI
428
+ ```
429
+
430
+ — *end example*]
431
+
432
+ ``` cpp
433
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
434
+ basic_istream<charT, traits>&
435
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
436
+ tai_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
437
+ minutes* offset = nullptr);
438
+ ```
439
+
440
+ *Effects:* Attempts to parse the input stream `is` into the `tai_time`
441
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
442
+ [[time.parse]]. If the parse fails to decode a valid date,
443
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
444
+ `%Z` is used and successfully parsed, that value will be assigned to
445
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
446
+ used and successfully parsed, that value will be assigned to `*offset`
447
+ if `offset` is non-null. Additionally, the parsed offset will be
448
+ subtracted from the successfully parsed timestamp prior to assigning
449
+ that difference to `tp`.
450
+
451
+ *Returns:* `is`.
452
+
453
+ ### Class `gps_clock` <a id="time.clock.gps">[[time.clock.gps]]</a>
454
+
455
+ #### Overview <a id="time.clock.gps.overview">[[time.clock.gps.overview]]</a>
456
+
457
+ ``` cpp
458
+ namespace std::chrono {
459
+ class gps_clock {
460
+ public:
461
+ using rep = a signed arithmetic type;
462
+ using period = ratio<unspecified, unspecified>;
463
+ using duration = chrono::duration<rep, period>;
464
+ using time_point = chrono::time_point<gps_clock>;
465
+ static constexpr bool is_steady = unspecified;
466
+
467
+ static time_point now();
468
+
469
+ template<class Duration>
470
+ static utc_time<common_type_t<Duration, seconds>>
471
+ to_utc(const gps_time<Duration>&) noexcept;
472
+ template<class Duration>
473
+ static gps_time<common_type_t<Duration, seconds>>
474
+ from_utc(const utc_time<Duration>&) noexcept;
475
+ };
476
+ }
477
+ ```
478
+
479
+ The clock `gps_clock` measures seconds since the first Sunday of
480
+ January, 1980 00:00:00 UTC. Leap seconds are not inserted into GPS.
481
+ Therefore every time a leap second is inserted into UTC, UTC shifts
482
+ another second with respect to GPS. Aside from the offset from
483
+ `1958y/January/1` to `1980y/January/Sunday[1]`, GPS is behind TAI by 19s
484
+ due to the 10s offset between 1958 and 1970 and the additional 9 leap
485
+ seconds inserted between 1970 and 1980.
486
+
487
+ `gps_clock` is not a *Cpp17TrivialClock* unless the implementation can
488
+ guarantee that `gps_clock::now()` does not propagate an exception.
489
+
490
+ [*Note 1*: `noexcept(from_utc(utc_clock::now()))` is
491
+ `false`. — *end note*]
492
+
493
+ #### Member functions <a id="time.clock.gps.members">[[time.clock.gps.members]]</a>
494
+
495
+ ``` cpp
496
+ static time_point now();
497
+ ```
498
+
499
+ *Returns:* `from_utc(utc_clock::now())`, or a more accurate value of
500
+ `gps_time`.
501
+
502
+ ``` cpp
503
+ template<class Duration>
504
+ static utc_time<common_type_t<Duration, seconds>>
505
+ to_utc(const gps_time<Duration>& t) noexcept;
506
+ ```
507
+
508
+ *Returns:*
509
+
510
+ ``` cpp
511
+ gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
512
+ ```
513
+
514
+ [*Note 1*:
515
+
516
+ ``` cpp
517
+ 315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s
518
+ ```
519
+
520
+ — *end note*]
521
+
522
+ ``` cpp
523
+ template<class Duration>
524
+ static gps_time<common_type_t<Duration, seconds>>
525
+ from_utc(const utc_time<Duration>& t) noexcept;
526
+ ```
527
+
528
+ *Returns:*
529
+
530
+ ``` cpp
531
+ gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
532
+ ```
533
+
534
+ [*Note 2*:
535
+
536
+ ``` cpp
537
+ 315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s
538
+ ```
539
+
540
+ — *end note*]
541
+
542
+ #### Non-member functions <a id="time.clock.gps.nonmembers">[[time.clock.gps.nonmembers]]</a>
543
+
544
+ ``` cpp
545
+ template<class charT, class traits, class Duration>
546
+ basic_ostream<charT, traits>&
547
+ operator<<(basic_ostream<charT, traits>& os, const gps_time<Duration>& t);
548
+ ```
549
+
550
+ *Effects:* Equivalent to:
551
+
552
+ ``` cpp
553
+ return os << format(STATICALLY-WIDEN<charT>("{:%F %T}"), t);
554
+ ```
555
+
556
+ [*Example 1*:
557
+
558
+ ``` cpp
559
+ auto st = sys_days{2000y/January/1};
560
+ auto gt = clock_cast<gps_clock>(st);
561
+ cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, gt);
562
+ ```
563
+
564
+ Produces this output:
565
+
566
+ ``` text
567
+ 2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS
568
+ ```
569
+
570
+ — *end example*]
571
+
572
+ ``` cpp
573
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
574
+ basic_istream<charT, traits>&
575
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
576
+ gps_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
577
+ minutes* offset = nullptr);
578
+ ```
579
+
580
+ *Effects:* Attempts to parse the input stream `is` into the `gps_time`
581
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
582
+ [[time.parse]]. If the parse fails to decode a valid date,
583
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
584
+ `%Z` is used and successfully parsed, that value will be assigned to
585
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
586
+ used and successfully parsed, that value will be assigned to `*offset`
587
+ if `offset` is non-null. Additionally, the parsed offset will be
588
+ subtracted from the successfully parsed timestamp prior to assigning
589
+ that difference to `tp`.
590
+
591
+ *Returns:* `is`.
592
+
593
+ ### Type `file_clock` <a id="time.clock.file">[[time.clock.file]]</a>
594
+
595
+ #### Overview <a id="time.clock.file.overview">[[time.clock.file.overview]]</a>
596
+
597
+ ``` cpp
598
+ namespace std::chrono {
599
+ using file_clock = see below;
600
+ }
601
+ ```
602
+
603
+ `file_clock` is an alias for a type meeting the *Cpp17TrivialClock*
604
+ requirements [[time.clock.req]], and using a signed arithmetic type for
605
+ `file_clock::rep`. `file_clock` is used to create the `time_point`
606
+ system used for `file_time_type` [[filesystems]]. Its epoch is
607
+ unspecified, and `noexcept(file_clock::now())` is `true`.
608
+
609
+ [*Note 1*: The type that `file_clock` denotes may be in a different
610
+ namespace than `std::chrono`, such as `std::filesystem`. — *end note*]
611
+
612
+ #### Member functions <a id="time.clock.file.members">[[time.clock.file.members]]</a>
613
+
614
+ The type denoted by `file_clock` provides precisely one of the following
615
+ two sets of static member functions:
616
+
617
+ ``` cpp
618
+ template<class Duration>
619
+ static sys_time<see below>
620
+ to_sys(const file_time<Duration>&);
621
+ template<class Duration>
622
+ static file_time<see below>
623
+ from_sys(const sys_time<Duration>&);
624
+ ```
625
+
626
+ or:
627
+
628
+ ``` cpp
629
+ template<class Duration>
630
+ static utc_time<see below>
631
+ to_utc(const file_time<Duration>&);
632
+ template<class Duration>
633
+ static file_time<see below>
634
+ from_utc(const utc_time<Duration>&);
635
+ ```
636
+
637
+ These member functions shall provide `time_point` conversions consistent
638
+ with those specified by `utc_clock`, `tai_clock`, and `gps_clock`. The
639
+ `Duration` of the resultant `time_point` is computed from the `Duration`
640
+ of the input `time_point`.
641
+
642
+ #### Non-member functions <a id="time.clock.file.nonmembers">[[time.clock.file.nonmembers]]</a>
643
+
644
+ ``` cpp
645
+ template<class charT, class traits, class Duration>
646
+ basic_ostream<charT, traits>&
647
+ operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& t);
648
+ ```
649
+
650
+ *Effects:* Equivalent to:
651
+
652
+ ``` cpp
653
+ return os << format(STATICALLY-WIDEN<charT>("{:%F %T}"), t);
654
+ ```
655
+
656
+ ``` cpp
657
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
658
+ basic_istream<charT, traits>&
659
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
660
+ file_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
661
+ minutes* offset = nullptr);
662
+ ```
663
+
664
+ *Effects:* Attempts to parse the input stream `is` into the `file_time`
665
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
666
+ [[time.parse]]. If the parse fails to decode a valid date,
667
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
668
+ `%Z` is used and successfully parsed, that value will be assigned to
669
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
670
+ used and successfully parsed, that value will be assigned to `*offset`
671
+ if `offset` is non-null. Additionally, the parsed offset will be
672
+ subtracted from the successfully parsed timestamp prior to assigning
673
+ that difference to `tp`.
674
+
675
+ *Returns:* `is`.
676
+
677
+ ### Class `steady_clock` <a id="time.clock.steady">[[time.clock.steady]]</a>
678
+
679
+ ``` cpp
680
+ namespace std::chrono {
681
+ class steady_clock {
682
+ public:
683
+ using rep = unspecified;
684
+ using period = ratio<unspecified, unspecified{}>;
685
+ using duration = chrono::duration<rep, period>;
686
+ using time_point = chrono::time_point<unspecified, duration>;
687
+ static constexpr bool is_steady = true;
688
+
689
+ static time_point now() noexcept;
690
+ };
691
+ }
692
+ ```
693
 
694
  Objects of class `steady_clock` represent clocks for which values of
695
  `time_point` never decrease as physical time advances and for which
696
  values of `time_point` advance at a steady rate relative to real time.
697
  That is, the clock may not be adjusted.
698
 
699
+ ### Class `high_resolution_clock` <a id="time.clock.hires">[[time.clock.hires]]</a>
700
+
701
  ``` cpp
702
+ namespace std::chrono {
703
+ class high_resolution_clock {
704
  public:
705
  using rep = unspecified;
706
  using period = ratio<unspecified, unspecified{}>;
707
  using duration = chrono::duration<rep, period>;
708
  using time_point = chrono::time_point<unspecified, duration>;
709
+ static constexpr bool is_steady = unspecified;
710
 
711
  static time_point now() noexcept;
712
  };
713
+ }
714
  ```
715
 
 
 
716
  Objects of class `high_resolution_clock` represent clocks with the
717
  shortest tick period. `high_resolution_clock` may be a synonym for
718
  `system_clock` or `steady_clock`.
719
 
720
+ ### Local time <a id="time.clock.local">[[time.clock.local]]</a>
721
+
722
+ The family of time points denoted by `local_time<Duration>` are based on
723
+ the pseudo clock `local_t`. `local_t` has no member `now()` and thus
724
+ does not meet the clock requirements. Nevertheless
725
+ `local_time<Duration>` serves the vital role of representing local time
726
+ with respect to a not-yet-specified time zone. Aside from being able to
727
+ get the current time, the complete `time_point` algebra is available for
728
+ `local_time<Duration>` (just as for `sys_time<Duration>`).
729
+
730
+ ``` cpp
731
+ template<class charT, class traits, class Duration>
732
+ basic_ostream<charT, traits>&
733
+ operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& lt);
734
+ ```
735
+
736
+ *Effects:*
737
+
738
+ ``` cpp
739
+ os << sys_time<Duration>{lt.time_since_epoch()};
740
+ ```
741
+
742
+ *Returns:* `os`.
743
+
744
+ ``` cpp
745
+ template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
746
+ basic_istream<charT, traits>&
747
+ from_stream(basic_istream<charT, traits>& is, const charT* fmt,
748
+ local_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
749
+ minutes* offset = nullptr);
750
+ ```
751
+
752
+ *Effects:* Attempts to parse the input stream `is` into the `local_time`
753
+ `tp` using the format flags given in the NTCTS `fmt` as specified in
754
+ [[time.parse]]. If the parse fails to decode a valid date,
755
+ `is.setstate(ios_base::failbit)` is called and `tp` is not modified. If
756
+ `%Z` is used and successfully parsed, that value will be assigned to
757
+ `*abbrev` if `abbrev` is non-null. If `%z` (or a modified variant) is
758
+ used and successfully parsed, that value will be assigned to `*offset`
759
+ if `offset` is non-null.
760
+
761
+ *Returns:* `is`.
762
+
763
+ ### `time_point` conversions <a id="time.clock.cast">[[time.clock.cast]]</a>
764
+
765
+ #### Class template `clock_time_conversion` <a id="time.clock.conv">[[time.clock.conv]]</a>
766
+
767
+ ``` cpp
768
+ namespace std::chrono {
769
+ template<class DestClock, class SourceClock>
770
+ struct clock_time_conversion {};
771
+ }
772
+ ```
773
+
774
+ `clock_time_conversion` serves as a trait which can be used to specify
775
+ how to convert a source `time_point` of type
776
+ `time_point<SourceClock, Duration>` to a destination `time_point` of
777
+ type `time_point<DestClock, Duration>` via a specialization:
778
+ `clock_time_conversion<DestClock, SourceClock>`. A specialization of
779
+ `clock_time_conversion<DestClock, SourceClock>` shall provide a
780
+ const-qualified `operator()` that takes a parameter of type
781
+ `time_point<SourceClock, Duration>` and returns a
782
+ `time_point<DestClock, OtherDuration>` representing an equivalent point
783
+ in time. `OtherDuration` is a `chrono::duration` whose specialization is
784
+ computed from the input `Duration` in a manner which can vary for each
785
+ `clock_time_conversion` specialization. A program may specialize
786
+ `clock_time_conversion` if at least one of the template parameters is a
787
+ user-defined clock type.
788
+
789
+ Several specializations are provided by the implementation, as described
790
+ in [[time.clock.cast.id]], [[time.clock.cast.sys.utc]],
791
+ [[time.clock.cast.sys]], and [[time.clock.cast.utc]].
792
+
793
+ #### Identity conversions <a id="time.clock.cast.id">[[time.clock.cast.id]]</a>
794
+
795
+ ``` cpp
796
+ template<class Clock>
797
+ struct clock_time_conversion<Clock, Clock> {
798
+ template<class Duration>
799
+ time_point<Clock, Duration>
800
+ operator()(const time_point<Clock, Duration>& t) const;
801
+ };
802
+ ```
803
+
804
+ ``` cpp
805
+ template<class Duration>
806
+ time_point<Clock, Duration>
807
+ operator()(const time_point<Clock, Duration>& t) const;
808
+ ```
809
+
810
+ *Returns:* `t`.
811
+
812
+ ``` cpp
813
+ template<>
814
+ struct clock_time_conversion<system_clock, system_clock> {
815
+ template<class Duration>
816
+ sys_time<Duration>
817
+ operator()(const sys_time<Duration>& t) const;
818
+ };
819
+ ```
820
+
821
+ ``` cpp
822
+ template<class Duration>
823
+ sys_time<Duration>
824
+ operator()(const sys_time<Duration>& t) const;
825
+ ```
826
+
827
+ *Returns:* `t`.
828
+
829
+ ``` cpp
830
+ template<>
831
+ struct clock_time_conversion<utc_clock, utc_clock> {
832
+ template<class Duration>
833
+ utc_time<Duration>
834
+ operator()(const utc_time<Duration>& t) const;
835
+ };
836
+ ```
837
+
838
+ ``` cpp
839
+ template<class Duration>
840
+ utc_time<Duration>
841
+ operator()(const utc_time<Duration>& t) const;
842
+ ```
843
+
844
+ *Returns:* `t`.
845
+
846
+ #### Conversions between `system_clock` and `utc_clock` <a id="time.clock.cast.sys.utc">[[time.clock.cast.sys.utc]]</a>
847
+
848
+ ``` cpp
849
+ template<>
850
+ struct clock_time_conversion<utc_clock, system_clock> {
851
+ template<class Duration>
852
+ utc_time<common_type_t<Duration, seconds>>
853
+ operator()(const sys_time<Duration>& t) const;
854
+ };
855
+ ```
856
+
857
  ``` cpp
858
+ template<class Duration>
859
+ utc_time<common_type_t<Duration, seconds>>
860
+ operator()(const sys_time<Duration>& t) const;
861
+ ```
 
 
 
862
 
863
+ *Returns:* `utc_clock::from_sys(t)`.
864
+
865
+ ``` cpp
866
+ template<>
867
+ struct clock_time_conversion<system_clock, utc_clock> {
868
+ template<class Duration>
869
+ sys_time<common_type_t<Duration, seconds>>
870
+ operator()(const utc_time<Duration>& t) const;
871
  };
872
  ```
873
 
874
+ ``` cpp
875
+ template<class Duration>
876
+ sys_time<common_type_t<Duration, seconds>>
877
+ operator()(const utc_time<Duration>& t) const;
878
+ ```
879
+
880
+ *Returns:* `utc_clock::to_sys(t)`.
881
+
882
+ #### Conversions between `system_clock` and other clocks <a id="time.clock.cast.sys">[[time.clock.cast.sys]]</a>
883
+
884
+ ``` cpp
885
+ template<class SourceClock>
886
+ struct clock_time_conversion<system_clock, SourceClock> {
887
+ template<class Duration>
888
+ auto operator()(const time_point<SourceClock, Duration>& t) const
889
+ -> decltype(SourceClock::to_sys(t));
890
+ };
891
+ ```
892
+
893
+ ``` cpp
894
+ template<class Duration>
895
+ auto operator()(const time_point<SourceClock, Duration>& t) const
896
+ -> decltype(SourceClock::to_sys(t));
897
+ ```
898
+
899
+ *Constraints:* `SourceClock::to_sys(t)` is well-formed.
900
+
901
+ *Mandates:* `SourceClock::to_sys(t)` returns a `sys_time<Duration>`,
902
+ where `Duration` is a valid `chrono::duration` specialization.
903
+
904
+ *Returns:* `SourceClock::to_sys(t)`.
905
+
906
+ ``` cpp
907
+ template<class DestClock>
908
+ struct clock_time_conversion<DestClock, system_clock> {
909
+ template<class Duration>
910
+ auto operator()(const sys_time<Duration>& t) const
911
+ -> decltype(DestClock::from_sys(t));
912
+ };
913
+ ```
914
+
915
+ ``` cpp
916
+ template<class Duration>
917
+ auto operator()(const sys_time<Duration>& t) const
918
+ -> decltype(DestClock::from_sys(t));
919
+ ```
920
+
921
+ *Constraints:* `DestClock::from_sys(t)` is well-formed.
922
+
923
+ *Mandates:* `DestClock::from_sys(t)` returns a
924
+ `time_point<DestClock, Duration>`, where `Duration` is a valid
925
+ `chrono::duration` specialization.
926
+
927
+ *Returns:* `DestClock::from_sys(t)`.
928
+
929
+ #### Conversions between `utc_clock` and other clocks <a id="time.clock.cast.utc">[[time.clock.cast.utc]]</a>
930
+
931
+ ``` cpp
932
+ template<class SourceClock>
933
+ struct clock_time_conversion<utc_clock, SourceClock> {
934
+ template<class Duration>
935
+ auto operator()(const time_point<SourceClock, Duration>& t) const
936
+ -> decltype(SourceClock::to_utc(t));
937
+ };
938
+ ```
939
+
940
+ ``` cpp
941
+ template<class Duration>
942
+ auto operator()(const time_point<SourceClock, Duration>& t) const
943
+ -> decltype(SourceClock::to_utc(t));
944
+ ```
945
+
946
+ *Constraints:* `SourceClock::to_utc(t)` is well-formed.
947
+
948
+ *Mandates:* `SourceClock::to_utc(t)` returns a `utc_time<Duration>`,
949
+ where `Duration` is a valid `chrono::duration` specialization.
950
+
951
+ *Returns:* `SourceClock::to_utc(t)`.
952
+
953
+ ``` cpp
954
+ template<class DestClock>
955
+ struct clock_time_conversion<DestClock, utc_clock> {
956
+ template<class Duration>
957
+ auto operator()(const utc_time<Duration>& t) const
958
+ -> decltype(DestClock::from_utc(t));
959
+ };
960
+ ```
961
+
962
+ ``` cpp
963
+ template<class Duration>
964
+ auto operator()(const utc_time<Duration>& t) const
965
+ -> decltype(DestClock::from_utc(t));
966
+ ```
967
+
968
+ *Constraints:* `DestClock::from_utc(t)` is well-formed.
969
+
970
+ *Mandates:* `DestClock::from_utc(t)` returns a
971
+ `time_point<DestClock, Duration>`, where `Duration` is a valid
972
+ `chrono::duration` specialization.
973
+
974
+ *Returns:* `DestClock::from_utc(t)`.
975
+
976
+ #### Function template `clock_cast` <a id="time.clock.cast.fn">[[time.clock.cast.fn]]</a>
977
+
978
+ ``` cpp
979
+ template<class DestClock, class SourceClock, class Duration>
980
+ auto clock_cast(const time_point<SourceClock, Duration>& t);
981
+ ```
982
+
983
+ *Constraints:* At least one of the following clock time conversion
984
+ expressions is well-formed:
985
+
986
+ - ``` cpp
987
+ clock_time_conversion<DestClock, SourceClock>{}(t)
988
+ ```
989
+
990
+ - ``` cpp
991
+ clock_time_conversion<DestClock, system_clock>{}(
992
+ clock_time_conversion<system_clock, SourceClock>{}(t))
993
+ ```
994
+
995
+ - ``` cpp
996
+ clock_time_conversion<DestClock, utc_clock>{}(
997
+ clock_time_conversion<utc_clock, SourceClock>{}(t))
998
+ ```
999
+
1000
+ - ``` cpp
1001
+ clock_time_conversion<DestClock, utc_clock>{}(
1002
+ clock_time_conversion<utc_clock, system_clock>{}(
1003
+ clock_time_conversion<system_clock, SourceClock>{}(t)))
1004
+ ```
1005
+
1006
+ - ``` cpp
1007
+ clock_time_conversion<DestClock, system_clock>{}(
1008
+ clock_time_conversion<system_clock, utc_clock>{}(
1009
+ clock_time_conversion<utc_clock, SourceClock>{}(t)))
1010
+ ```
1011
+
1012
+ A clock time conversion expression is considered better than another
1013
+ clock time conversion expression if it involves fewer `operator()` calls
1014
+ on `clock_time_conversion` specializations.
1015
+
1016
+ *Mandates:* Among the well-formed clock time conversion expressions from
1017
+ the above list, there is a unique best expression.
1018
+
1019
+ *Returns:* The best well-formed clock time conversion expression in the
1020
+ above list.
1021
+