From 16c5f5885f8d6b70d3a7df057e9eed30babeafc9 Mon Sep 17 00:00:00 2001
From: Howard Hinnant
Howard E. Hinnant
-2017-11-03
+Tomasz Kamiński
+2017-11-26
Extending
@@ -59,6 +60,9 @@ Document number: D0355R5<chrono>
to Calendars and Time Zones
Changes since R4
+
to_sys_time
,
+to_utc_time
, to_tai_time
, to_gps_time
,
+to_file_time
, with clock_cast
.zoned_time
conversion among different TimeZonePtr
types.nonexistent_local_time
and
@@ -74,7 +78,7 @@ but can be updated at run time. Removed remote_download
and
to_stream
sets failbit
if it is required to create a name
for an invalid month or weekday.fmt
(P0645)format
throw an exception if anything happens so that it
+format
throw an exception if anything happens so that it
could not return an accurate string.zoned_time
on TimeZonePtr
.weekday_indexed
a defaulted default constructor.tzdb
.
parse
in terms of to_stream
and
from_stream
.
-to_stream
and from_stream
for year
,
+to_stream
and from_stream
for year
,
month
, day
, weekday
, year_month
, and
month_day
.<chrono>
library (specifically a
-system_clock::time_point
with a precision of days).
+system_clock::time_point
with a precision of days).
@@ -301,7 +305,7 @@ can never mean "3 seconds", unless it is explicitly typed to do so:
-And just like seconds
, there is a year literal suffix which can help make
+And just like seconds
, there is a year literal suffix which can help make
your code more readable:
year_month_day
are time points with a precision of a day, but
they are also field types. They are composed of 3 fields under the hood:
year
, month
and day
. Thus when you
construct a year_month_day
from a year
,
-month
and day
, absolutely no computation takes place.
+month
and day
, absolutely no computation takes place.
The only thing that happens is a year
, month
and
day
are stored inside the year_month_day
.
@@ -435,11 +439,11 @@ static_assert(ymd == sun[5]/may/2016);
-The literal sun[5]/may/2016
means "the 5th Sunday of May in 2016."
+The literal sun[5]/may/2016
means "the 5th Sunday of May in 2016."
The conventional syntax is remarkably readable. Constructor syntax is
also available to do the same thing. The type constructed is
year_month_weekday
which does nothing but store a
-year
, month
, weekday
, and the number 5.
+year
, month
, weekday
, and the number 5.
This "auxiliary calendar" converts to and from sys_days
just like
year_month_day
as demonstrated above. As such,
year_month_weekday
will interoperate with year_month_day
@@ -534,7 +538,7 @@ local time specified by the local_time
.
To interoperate with time zones, calendrical types must convert to and from
local_days
as well as sys_days
. The math is identical
-for both conversions, so it is very easy for the calendar author to provide.
+for both conversions, so it is very easy for the calendar author to provide.
But as seen in this example, the meaning can be quite different.
--template <class Duration> -sys_time<common_type_t<Duration, seconds>> -to_sys_time(const utc_time<Duration>& u); ---- --Returns: A
-sys_time t
, such thatto_utc_time(t) == u
-if such a mapping exists. Otherwiseu
represents a -time_point during a leap second insertion and the last representable value of -sys_time prior
to the insertion of the leap second is returned. --[Example: -
---auto t = sys_days{jul/1/2015} - 500ms; -auto u = to_utc_time(t); -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25s); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25s); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25001ms); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25251ms); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25501ms); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 25751ms); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 26s); -cout << t << " SYS == " << u << " UTC\n"; -u += 250ms; -t = to_sys_time(u); -assert(u.time_since_epoch() - t.time_since_epoch() == 26s); -cout << t << " SYS == " << u << " UTC\n"; --Output: -
---2015-06-30 23:59:59.500 SYS == 2015-06-30 23:59:59.500 UTC -2015-06-30 23:59:59.750 SYS == 2015-06-30 23:59:59.750 UTC -2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.000 UTC -2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.250 UTC -2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.500 UTC -2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.750 UTC -2015-07-01 00:00:00.000 SYS == 2015-07-01 00:00:00.000 UTC -2015-07-01 00:00:00.250 SYS == 2015-07-01 00:00:00.250 UTC --— end example] -
--template <class Duration> -sys_time<common_type_t<Duration, seconds>> -to_sys_time(const tai_time<Duration>& u); ---- --Effects: Equivalent to:
-return to_sys_time(to_utc_time(u));
--template <class Duration> -sys_time<common_type_t<Duration, seconds>> -to_sys_time(const gps_time<Duration>& u); ---- --Effects: Equivalent to:
-return to_sys_time(to_utc_time(u));
--template <class Duration> -sys_time<Duration> -to_sys_time(const file_time<Duration>& u); -----Returns: A
-sys_time t
, such thatto_file_time(t) == u
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. -template <class charT, class traits, class Duration> basic_ostream<charT, traits>& @@ -2080,7 +1924,7 @@ If@@ -2128,8 +1982,8 @@ account,%Z
is used and successfully parsed, that value will be assignedIf
@@ -2106,13 +1950,23 @@ Add new section [time.clock.utc] after 23.17.7.1 Class system_clock [time.clock. class utc_clock { public: - using duration = system_clock::duration; - using rep = duration::rep; - using period = duration::period; + 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); };%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null. Additionally, the parsed offset will be subtracted from the successfully parsed time stamp prior to assigning that difference totp
.utc_clock
and its associatedtime_point
,-to_utc_time(sys_seconds{sys_days{1970y/jan/1}}).time_since_epoch() is 0s -to_utc_time(sys_seconds{sys_days{2000y/jan/1}}).time_since_epoch() is 946'684'822s which is 10'957 * 86'400s + 22s +clock_cast<utc_clock>(sys_seconds{sys_days{1970y/jan/1}}).time_since_epoch() is 0s +clock_cast<utc_clock>(sys_seconds{sys_days{2000y/jan/1}}).time_since_epoch() is 946'684'822s which is 10'957 * 86'400s + 22s@@ -2139,7 +1993,7 @@ to_utc_time(sys_seconds{sys_days{2000y/jan/1}}).time_since_epoch() is 946'684'82
@@ -2148,15 +2002,32 @@ static utc_clock::time_point utc_clock::now();
utc_clock
is not aTrivialClock
unless the implementation can guarantee thatutc_clock::now()
does not propagate an exception. -[Note:noexcept(to_utc_time(system_clock::now()))
is +[Note:noexcept(from_sys(system_clock::now()))
isfalse
. — end note]-Returns: The implementations should supply the best measure available. -This may be approximated with
to_utc_time(system_clock::now())
. +Returns:from_sys(system_clock::now())
, or a more accurate +value ofutc_time
.-template <class Duration> +template <typename Duration> +static +sys_time<common_type_t<Duration, seconds>> +utc_clock::to_sys(const utc_time<Duration>& u); ++++ ++Returns: A
+sys_time
t
, such that +from_sys(t) == u
if such a mapping exists. Otherwiseu
+represents atime_point
during a leap second insertion and the last +representable value ofsys_time
prior to the insertion of the leap +second is returned. ++template <typename Duration> +static utc_time<common_type_t<Duration, seconds>> -to_utc_time(const sys_time<Duration>& t); +utc_clock::from_sys(const sys_time<Duration>& t);-@@ -2171,16 +2042,16 @@ counts that leap second as inserted.
auto t = sys_days{jul/1/2015} - 2ns; -auto u = to_utc_time(t); +auto u = utc_clock::from_sys(t); assert(u.time_since_epoch() - t.time_since_epoch() == 25s); t += 1ns; -u = to_utc_time(t); +u = utc_clock::from_sys(t); assert(u.time_since_epoch() - t.time_since_epoch() == 25s); t += 1ns; -u = to_utc_time(t); +u = utc_clock::from_sys(t); assert(u.time_since_epoch() - t.time_since_epoch() == 26s); t += 1ns; -u = to_utc_time(t); +u = utc_clock::from_sys(t); assert(u.time_since_epoch() - t.time_since_epoch() == 26s);@@ -2188,47 +2059,6 @@ assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
-template <class Duration> -utc_time<common_type_t<Duration, seconds>> -to_utc_time(const tai_time<Duration>& t); ---- --Returns:
-utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
--Note:
-378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
--template <class Duration> -utc_time<common_type_t<Duration, seconds>> -to_utc_time(const gps_time<Duration>& t); ---- --Returns:
-utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
--Note:
-315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
--template <class Duration> -utc_time<common_type_t<Duration, seconds>> -to_utc_time(const file_time<Duration>& t); -----Returns: A
-utc_time t
, such thatto_file_time(t) == u
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. -template <class charT, class traits, class Duration> basic_ostream<charT, traits>& @@ -2269,7 +2099,7 @@ of that format shall be@@ -2361,7 +2201,7 @@ is equivalent to 2000-01-01 00:00:32 TAI (22s plus the initial 10s offset)."60"
.@@ -2313,7 +2143,7 @@ Ifauto t = sys_days{jul/1/2015} - 500ms; -auto u = to_utc_time(t); +auto u = clock_cast<utc_clock>(t); for (auto i = 0; i < 8; ++i, u += 250ms) cout << u << " UTC\n";%Z
is used and successfully parsed, that value will be assignedIf
@@ -2339,13 +2169,23 @@ Add new section [time.clock.tai] after 23.17.7.2 Class utc_clock [time.clock.utc class tai_clock { public: - using duration = system_clock::duration; - using rep = duration::rep; - using period = duration::period; + 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; };%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null. Additionally, the parsed offset will be subtracted from the successfully parsed time stamp prior to assigning that difference totp
.@@ -2370,30 +2210,20 @@ static tai_clock::time_point tai_clock::now();
tai_clock
is not aTrivialClock
unless the implementation can guarantee thattai_clock::now()
does not propagate an exception. -[Note:noexcept(to_tai_time(system_clock::now()))
is +[Note:noexcept(from_utc(utc_clock::now()))
isfalse
. — end note]-Returns: The implementations should supply the best measure available. This may -be approximated with
to_tai_time(system_clock::now())
. +Returns:from_utc(utc_clock::now())
, or a more accurate +value oftai_time
.template <class Duration> -tai_time<common_type_t<Duration, seconds>> -to_tai_time(const sys_time<Duration>& t); +static +utc_time<common_type_t<Duration, seconds>> +to_utc(const tai_time<Duration>& t) noexcept;- --Effects: Equivalent to:
-return to_tai_time(to_utc_time(t));
. --template <class Duration> -tai_time<common_type_t<Duration, seconds>> -to_tai_time(const utc_time<Duration>& t); ----Returns:
tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
+Returns:utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
Note:
378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
@@ -2402,28 +2232,16 @@ to_tai_time(const utc_time<Duration>& t);template <class Duration> +static tai_time<common_type_t<Duration, seconds>> -to_tai_time(const gps_time<Duration>& t); +tai_clock::from_utc(const utc_time<Duration>& t) noexcept;- --Returns:
tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 694656019s
+Returns:tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
-Note:
-694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s
--template <class Duration> -tai_time<common_type_t<Duration, seconds>> -to_tai_time(const file_time<Duration>& t); ---@@ -2469,7 +2287,7 @@ sys_time<Duration>{tp.time_since_epoch()} - (sys_days{1970y/jan/1} - sys_d-Returns: A
tai_time t
, such thatto_file_time(t) == u
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. +Note:378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
auto st = sys_days{2000_y/jan/1}; -auto tt = to_tai_time(st); +auto tt = clock_cast<tai_clock>(st); cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", tt);@@ -2505,7 +2323,7 @@ If
%Z
is used and successfully parsed, that value will be assignedIf
@@ -2532,13 +2350,23 @@ Add new section [time.clock.gps] after 23.17.7.3 Class tai_clock [time.clock.tai class gps_clock { public: - using duration = system_clock::duration; - using rep = duration::rep; - using period = duration::period; + 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; }; @@ -2554,7 +2382,7 @@ the 10s offset between 1958 and 1970 and the additional 9 leap seconds inserted%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null. Additionally, the parsed offset will be subtracted from the successfully parsed time stamp prior to assigning that difference totp
.@@ -2563,30 +2391,20 @@ static gps_clock::time_point gps_clock::now();
gps_clock
is not aTrivialClock
unless the implementation can guarantee thatgps_clock::now()
does not propagate an exception. -[Note:noexcept(to_gps_time(system_clock::now()))
is +[Note:noexcept(from_utc(utc_clock::now()))
isfalse
. — end note]-Returns: The implementations should supply the best measure available. This may -be approximated with
to_gps_time(system_clock::now())
. +Returns:from_utc(utc_clock::now())
, or a more accurate +value ofgps_time
.template <class Duration> -gps_time<common_type_t<Duration, seconds>> -to_gps_time(const sys_time<Duration>& t); +static +utc_time<common_type_t<Duration, seconds>> +gps_clock::to_utc(const gps_time<Duration>& t) noexcept;- --Effects: Equivalent to:
-return to_gps_time(to_utc_time(t));
. --template <class Duration> -gps_time<common_type_t<Duration, seconds>> -to_gps_time(const utc_time<Duration>& t); ----Returns:
gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
+Returns:gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
Note:
315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
@@ -2595,28 +2413,16 @@ to_gps_time(const utc_time<Duration>& t);template <class Duration> +static gps_time<common_type_t<Duration, seconds>> -to_gps_time(const tai_time<Duration>& t); +gps_clock::from_utc(const utc_time<Duration>& t) noexcept;- --Returns:
gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 694656019s
+Returns:gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
-Note:
-694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s
--template <class Duration> -gps_time<common_type_t<Duration, seconds>> -to_gps_time(const file_time<Duration>& t); ---@@ -2662,7 +2468,7 @@ sys_time<Duration>{tp.time_since_epoch()} + (sys_days{1980y/jan/sun[1]} --Returns: A
gps_time t
, such thatto_file_time(t) == u
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. +Note:315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
auto st = sys_days{2000_y/jan/1}; -auto gt = to_gps_time(st); +auto gt = clock_cast<gps_clock>(st); cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", gt);@@ -2698,7 +2504,7 @@ If
%Z
is used and successfully parsed, that value will be assignedIf
@@ -2724,13 +2530,15 @@ Add new section [time.clock.file] after 23.17.7.4 Class gps_clock [time.clock.gp class file_clock { public: - using rep = unspecified; + using rep = a signed arithmetic type; using period = ratio<unspecified, unspecified>; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<file_clock>; static constexpr bool is_steady = unspecified; static time_point now() noexcept; + + // Conversion functions, see below }; @@ -2740,54 +2548,52 @@ used for%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null. Additionally, the parsed offset will be subtracted from the successfully parsed time stamp prior to assigning that difference totp
.file_time_type
([filesystems]). It's epoch is unspecified-template <class Duration> -file_time<Duration> -to_file_time(const sys_time<Duration>& t); +static file_clock::time_point file_clock::now();+-Returns: A
file_time u
, such thatto_sys_time(u) == t
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. +Returns: Afile_clock::time_point
indicating the current time.+The class
+ +file_clock
shall provide precisely one of the +following two sets of static member functions: ++template <class Duration> -file_time<common_type_t<Duration, seconds>> -to_file_time(const utc_time<Duration>& t); +static +sys_time<some duration> +to_sys(const file_time<Duration>&); + +template <class Duration> +static +file_time<some duration> +from_sys(const sys_time<Duration>&);-+-Returns: A
-file_time u
, such thatto_utc_time(u) == t
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. +or:template <class Duration> -file_time<common_type_t<Duration, seconds>> -to_file_time(const tai_time<Duration>& t); ---+static +utc_time<some duration> +to_utc(const file_time<Duration>&); --Returns: A
-file_time u
, such thatto_tai_time(u) == t
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. -template <class Duration> -file_time<common_type_t<Duration, seconds>> -to_file_time(const gps_time<Duration>& t); +static +file_time<some duration> +from_utc(const utc_time<Duration>&);-+@@ -2820,7 +2626,8 @@ the null-terminated array-Returns: A
file_time t
, such thatto_gps_time(t) == u
if -such a mapping exists.t
andu
should represent the same point -in time, even though they may have different epochs. +These member functions shall providetime_point
+conversions consistent with those specified byutc_clock
, +tai_clock
, andgps_clock
.fmt
.fmt
encoding follows t specified by [time.format]. If%Z
is used, it will be replaced with"UTC"
. If%z
is used (or a modified form of%z
), an offset of0min
will be formatted. The date and time formatted shall be -equivalent to that formatted by asys_time
initialized withto_sys_time(tp)
. +equivalent to that formatted by asys_time
initialized withclock_cast<system_clock>(tp)
, +or by autc_time
initialized withclock_cast<utc_clock>(tp)
.Returns:
os
. @@ -2849,7 +2656,7 @@ If%Z
is used and successfully parsed, that value will be assignedIf
@@ -2874,7 +2681,7 @@ Add new section [time.clock.local_time] after 23.17.7.3 Class high_resolution_cl%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null. Additionally, the parsed offset will be subtracted from the successfully parsed time stamp prior to assigning that difference totp
.The family of time points denoted by
local_time<Duration>
are based on the pseudo clocklocal_t
.local_t
has -no membernow()
and thus does not meet the clock requirements. +no membernow()
and thus does not meet the clock requirements. Neverthelesslocal_time<Duration>
serves the vital role of representing local time with respect to a not-yet-specified time zone. Aside from being able to get the current time, the completetime_point
@@ -2948,7 +2755,7 @@ If%Z
is used and successfully parsed, that value will be assignedIf
%z
(or a modified variant) is used and successfully parsed, that value -will be assigned to*offset
ifoffset
is non-null. +will be assigned to*offset
ifoffset
is non-null.Returns:
is
. @@ -2960,6 +2767,311 @@ will be assigned to*offset
ifoffset
is non-null.+Add new section [time.clock.clock_cast] after 23.17.7.9 local_time [time.clock.local_time]: +
+ ++ ++23.17.7.9 clock_cast [time.clock.clock_cast]
+ ++template <class DestClock, class SourceClock> +struct clock_time_conversion +{}; +++
+ +clock_time_conversion
serves as trait which can be used to specify how to +converttime_point<SourceClock, Duration>
to +time_point<DestClock, Duration>
via a specialization: +clock_time_conversion<DestClock, SourceClock>
. A specialization of +clock_time_conversion<DestClock, SourceClock>
shall provide a +const
-qualifiedoperator()
that takes a parameter of type +time_point<SourceClock, Duration>
and returns a +time_point<DestClock, some duration>
representing an equivalent +point in time. A program may specializeclock_time_conversion
if at least +one of the template parameters is user-defined clock type. ++Several specializations are provided by the implementation: +
++// Identity + +template <typename Clock> +struct clock_time_conversion<Clock, Clock> +{ + template <class Duration> + time_point<Clock, Duration> + operator()(const time_point<Clock, Duration>& t) const; +}; + +template <class Duration> +time_point<Clock, Duration> +operator()(const time_point<Clock, Duration>& t) const; ++ +++ ++Returns:
+t
. ++template <> +struct clock_time_conversion<system_clock, system_clock> +{ + template <class Duration> + sys_time<Duration> + operator()(const sys_time<Duration>& t) const; +}; + +template <class Duration> +sys_time<Duration> +operator()(const sys_time<Duration>& t) const; ++ +++ ++Returns:
+t
. ++template <> +struct clock_time_conversion<utc_clock, utc_clock> +{ + template <class Duration> + utc_time<Duration> + operator()(const utc_time<Duration>& t) const; +}; + +template <class Duration> +utc_time<Duration> +operator()(const utc_time<Duration>& t) const; ++ +++ ++Returns:
+t
. ++// system_clock <-> utc_clock ++ ++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; +}; + +template <class Duration> +utc_time<common_type_t<Duration, seconds>> +operator()(const sys_time<Duration>& t) const; ++ +++ ++Returns:
+utc_clock::from_sys(t)
. ++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; +}; + +template <class Duration> +sys_time<common_type_t<Duration, seconds>> +operator()(const utc_time<Duration>& t) const; ++ +++ ++Returns:
+utc_clock::to_sys(t)
. ++// Clock <-> system_clock ++ ++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)); +}; + +template <class Duration> +auto +operator()(const time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_sys(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+SourceClock::to_sys(t)
is well formed. If +SourceClock::to_sys(t)
does not return +sys_time<some duration>
the program is ill-formed. ++Returns:
+SourceClock::to_sys(t)
. ++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)); +}; + +template <class Duration> +auto +operator()(const sys_time<Duration>& t) const + -> decltype(DestClock::from_sys(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+DestClock::from_sys(t)
is well formed. If +DestClock::from_sys(t)
does not return +time_point<DestClock, some duration>
the program is ill-formed. ++Returns:
+DestClock::from_sys(t)
. ++// Clock <-> utc_clock ++ ++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)); +}; + +template <class Duration> +auto +operator()(const time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_utc(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+SourceClock::to_utc(t)
is well formed. If +SourceClock::to_utc(t)
does not return +utc_time<some duration>
the program is ill-formed. ++Returns:
+SourceClock::to_utc(t)
. ++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)); +}; + +template <class Duration> +auto +operator()(const utc_time<Duration>& t) const + -> decltype(DestClock::from_utc(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+DestClock::from_utc(t)
is well formed. If +DestClock::from_utc(t)
does not return +time_point<DestClock, some duration>
the program is ill-formed. +. +
+Returns:
+DestClock::from_utc(t)
. ++// clock_cast ++ ++template <class DestClock, class SourceClock, class Duration> +time_point<DestClock, some duration> +clock_cast(const time_point<SourceClock, Duration>& t); ++ +++ ++Remarks: This function does not participate in overload resolution unless +at least one of the following expressions are well formed: +
++
+- +
clock_time_conversion<DestClock, SourceClock>{}(t)
- Exactly one of: +
++
- +
clock_time_conversion<DestClock, system_clock>{}( + clock_time_conversion<system_clock, SourceClock>{}(t))
+- +
clock_time_conversion<DestClock, utc_clock>{}( + clock_time_conversion<utc_clock, SourceClock>{}(t))
- Exactly one of: +
++
- +
clock_time_conversion<DestClock, utc_clock>{}( + clock_time_conversion<utc_clock, system_clock>{}( + clock_time_conversion<system_clock, SourceClock>{}(t)))
- +
clock_time_conversion<DestClock, system_clock>{}( + clock_time_conversion<system_clock, utc_clock>{}( + clock_time_conversion<utc_clock, SourceClock>{}(t)))
+Returns: The first expression in the above list that is well-formed. If item 1 is +not well-formed and both expressions in item 2 are well-formed, the +
+clock_cast
is ambiguous (ill-formed). If items 1 and 2 are not well-formed +and both expressions in item 3 are well-formed, theclock_cast
is ambiguous +(ill-formed). ++Back to TOC +
+Add a new section 23.17.8 Formatting [time.format]:
@@ -3773,8 +3885,8 @@ tosys_days
andlocal_days
.23.17.10.1 Class
last_spec
[time.calendar.last]-The struct
@@ -4143,7 +4255,7 @@ constexpr day operator "" d(unsigned long long d) noexcept;last_spec
is used in conjunction with other calendar types to -specify the last in a sequence. For example, depending on context, it can represent +The structlast_spec
is used in conjunction with other calendar types to +specify the last in a sequence. For example, depending on context, it can represent the last day of a month, or the last day of the week of a month.
month
represents a month of a year. It normally holds values in -the range 1 to 12. However it may hold non-negative values outside this range. +the range 1 to 12. However it may hold non-negative values outside this range. It can be constructed with anyunsigned
value, which will be subsequently truncated to fit intomonth
's unspecified internal storage.month
is equality and less-than comparable, and @@ -4921,13 +5033,13 @@ constexpr year operator "" y(unsigned long long y) noexcept; normally holds values in the range 0 to 6, corresponding to Sunday through Saturday. However it may hold non-negative values outside this range. It can be constructed with anyunsigned
value, which will be subsequently -truncated to fit intoweekday
's unspecified internal storage. +truncated to fit intoweekday
's unspecified internal storage.weekday
is equality comparable.weekday
is not less-than comparable because there is no universal consensus on which day is the first day of the week. This design chooses the encoding of 0 to 6 to represent Sunday through Saturday only because this is consistent with existing C and C++ practice. Howeverweekday
's comparison and arithmetic operations -treat the days of the week as a circular range, with no beginning and no end. +treat the days of the week as a circular range, with no beginning and no end. One can stream out aweekday
.weekday
has explicit conversions to and fromunsigned
. There are 7weekday
constants, one for each day of the week in thechrono_literals
@@ -5441,7 +5553,7 @@ return os << wdi.weekday() << '[' << wdi.index() << ']';23.17.10.7 Class
weekday_last
[time.calendar.weekday_last]-
@@ -6511,7 +6623,7 @@ andweekday_last
represents the lastweekday
of a month. +weekday_last
represents the lastweekday
of a month. It is most easily constructed by indexing aweekday
withlast
.day
.year_month_day
is a field-based time point w resolution ofdays
. One can observe each field.year_month_day
supportsyears
andmonths
oriented arithmetic, but notdays
oriented arithmetic. For the latter, there is a conversion to -sys_days
which efficiently supportsdays
oriented arithmetic. +sys_days
which efficiently supportsdays
oriented arithmetic. There is also a conversion fromsys_days
.year_month_day
is equality and less-than comparable. @@ -7317,12 +7429,12 @@ return os << ymdl.year() << '/' << ymdl.month_day_last();@@ -9026,7 +9138,7 @@ struct tzdb class tzdb_list { - std::atomic<tzdb*> head_{nullptr}; // exposition only + atomic<tzdb*> head_{nullptr}; // exposition only public: class const_iterator; @@ -9053,7 +9165,7 @@ implicitly access the
year_month_weekday
represents a specificyear
, -month
, and nthweekday
of themonth
. +month
, and nthweekday
of themonth
.year_month_weekday
is a field-based time point with a resolution ofdays
. One can observe each field.year_month_weekday
supportsyears
andmonths
oriented arithmetic, but notdays
oriented arithmetic. For the latter, there is a conversion tosys_days
which -efficiently supportsdays
oriented arithmetic. +efficiently supportsdays
oriented arithmetic.year_month_weekday
is equality comparable.front()
of this list via the read-only namespace scope functionsget_tzdb()
,locate_zone()
andcurrent_zone()
. Eachvector
intzdb
is sorted to enable fast -lookup. One can iterate over and inspect this database. And +lookup. One can iterate over and inspect this database. And multiple versions of the database can be used at once, via thetzdb_list
. @@ -9097,7 +9209,7 @@ list<tzdb>& get_tzdb_list(); Effects: If this is the first access to the database, will initialize the database. If this call initializes the database, the resulting database will be atzdb_list
which holds a -single initializedtzdb
. +single initializedtzdb
.Returns: A reference to the database. @@ -9301,7 +9413,7 @@ the base class with a sequence of
char
equivalent to that produced byos.str()
initialized as shown below:-std::ostringstream os; +ostringstream os; os << tp << " is in a gap between\n" << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' ' << i.first.abbrev << " and\n" @@ -9317,7 +9429,7 @@ os << tp << " is in a gap between\n"-#include "tz.h" +#include <chrono> #include <iostream> int @@ -9378,7 +9490,7 @@ the base class with a sequence ofchar
equivalent to that produced byos.str()
initialized as shown below:-std::ostringstream os; +ostringstream os; os << tp << " is ambiguous. It could be\n" << tp << ' ' << i.first.abbrev << " == " << tp - i.first.offset << " UTC or\n" @@ -9392,7 +9504,7 @@ os << tp << " is ambiguous. It could be\n"-#include "tz.h" +#include <chrono> #include <iostream> int @@ -9949,7 +10061,7 @@ template <class Duration2, TimeZonePtr>Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -10058,7 +10170,7 @@ template <class Duration2, TimeZonePtr>
Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -10078,7 +10190,7 @@ template <class Duration2, TimeZonePtr>
Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -10286,7 +10398,7 @@ class leap public: leap(const leap&) = default; leap& operator=(const leap&) = default; - + // Undocumented constructors sys_seconds date() const; @@ -10557,8 +10669,8 @@ Add a new section 23.17.12.8 link [time.timezone.link]: class link { private: - std::string name_; // exposition only - std::string target_; // exposition only + string name_; // exposition only + string target_; // exposition only public: link(const link&) = default; diff --git a/tz.html b/tz.html index d2e2c35..69ff297 100644 --- a/tz.html +++ b/tz.html @@ -1058,7 +1058,7 @@ implicitly access the
@@ -2215,7 +2215,7 @@ template <class Duration2, TimeZonePtr>front()
of this list via the read-only namespace scope functionsget_tzdb()
,locate_zone()
andcurrent_zone()
. Eachvector
intzdb
is sorted to enable fast -lookup. One can iterate over and inspect this database. And +lookup. One can iterate over and inspect this database. And multiple versions of the database can be used at once, via thetzdb_list
.Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -2324,7 +2324,7 @@ template <class Duration2, TimeZonePtr>
Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -2344,7 +2344,7 @@ template <class Duration2, TimeZonePtr>
Remarks: Does not participate in overload resolution unless -
sys_time<Duration2>
is implicitly convertible to +sys_time<Duration2>
is implicitly convertible tosys_time<Duration>
.@@ -2679,10 +2679,10 @@ public: using time_point = std::chrono::time_point<utc_clock>; static constexpr bool is_steady = unspecified; - static time_point now() noexcept; + static time_point now(); template <class Duration> - static + static sys_time<std::common_type_t<Duration, std::chrono::seconds>> to_sys(const utc_time<Duration>&); @@ -2715,7 +2715,7 @@ second information. When this is the case,
utc_clock
will not exis-static utc_clock::time_point utc_clock::now() noexcept; +static utc_clock::time_point utc_clock::now();@@ -2726,7 +2726,7 @@ value of
utc_time
.template <typename Duration> -static +static sys_time<std::common_type_t<Duration, std::chrono::seconds>> utc_clock::to_sys(const utc_time<Duration>& u);@@ -2830,16 +2830,16 @@ public: using time_point = std::chrono::time_point<tai_clock>; static constexpr bool is_steady = unspecified; - static time_point now() noexcept; - - template <class Duration> - static - utc_time<std::common_type_t<Duration, std::chrono::seconds>> - to_utc(const std::chrono::time_point<tai_clock, Duration>&) noexcept; + static time_point now(); template <class Duration> static - tai_time<std::common_type<Duration, std::chrono::seconds>> + utc_time<std::common_type_t<Duration, std::chrono::seconds>> + to_utc(const tai_time<Duration>&) noexcept; + + template <class Duration> + static + tai_time<std::common_type_t<Duration, std::chrono::seconds>> from_utc(const utc_time<Duration>&) noexcept; }; @@ -2864,7 +2864,7 @@ second information. When this is the case,tai_clock
will not exis-static tai_clock::time_point tai_clock::now() noexcept; +static tai_clock::time_point tai_clock::now();@@ -2875,7 +2875,7 @@ value of
tai_time
.template <class Duration> -static +static utc_time<std::common_type_t<Duration, std::chrono::seconds>> to_utc(const std::chrono::time_point<tai_clock, Duration>& t) noexcept;@@ -2891,7 +2891,7 @@ to_utc(const std::chrono::time_point<tai_clock, Duration>& t) noexcepttemplate <class Duration> static -tai_time<std::common_type<Duration, std::chrono::seconds>> +tai_time<std::common_type_t<Duration, std::chrono::seconds>> tai_clock::from_utc(const utc_time<Duration>& t) noexcept;@@ -2975,10 +2975,10 @@ public: using time_point = std::chrono::time_point<gps_clock>; static constexpr bool is_steady = unspecified; - static time_point now() noexcept; + static time_point now(); template <class Duration> - static + static utc_time<std::common_type_t<Duration, std::chrono::seconds>> to_utc(const gps_time<Duration>&) noexcept; @@ -3019,7 +3019,7 @@ value ofgps_time
.template <class Duration> -static +static utc_time<std::common_type_t<Duration, std::chrono::seconds>> gps_clock::to_utc(const gps_time<Duration>& t) noexcept;@@ -3189,7 +3189,7 @@ converttime_point<SourceClock, Duration>
totime_point<SourceClock, Duration>
and returns atime_point<DestClock, some duration>
representing an equivalent point in time. A program may specializeclock_time_conversion
if at least -one of the template parameters is user-defined clock type. +one of the template parameters is user-defined clock type.