diff --git a/d0355r0.html b/d0355r0.html new file mode 100644 index 0000000..29319a2 --- /dev/null +++ b/d0355r0.html @@ -0,0 +1,7880 @@ + + + +
+ +<chrono>
to Calendars and Time Zones
+The purpose of a calendar is to give a name to each day.1 There are many
+different ways this can be accomplished. This paper proposes only the Gregorian
+calendar. However the design of this proposal is such that clients can
+code other calendars and have them interoperate with <chrono>
,
+the civil calendar, and with time zones, all with a minimal
+coupling. For example:
+
+ ++#include "coptic.h" // not proposed, just an example +#include <chrono> +#include <iostream> + +int +main() +{ + using namespace std::chrono_literals; + auto date = 2016y/may/29; + cout << date << " is " << coptic::year_month_day{date} << " in the Coptic calendar\n"; + // 2016-05-29 is 1732-09-21 in the Coptic calendar +} +
+The above example creates a date in the Gregorian calendar (proposed) with the
+literal 2016y/may/29
. The meaning of this literal is without
+question. It is clearly readable. This proposal has no knowledge whatsoever of
+the Coptic calendar. However it is relatively easy to create a Coptic calendar
+(which knows nothing about the Gregorian calendar), which will convert to and
+from the Gregorian calendar. This is done by establishing a clear and simple
+communication channel between calendar systems and the
+<chrono>
library (specifically a
+system_clock::time_point
with a a precision of days).
+
+The paper proposes: +
+ +<chrono>
to support calendar and
+time zone libraries.strftime
-like formatting and parsing facilities with fully operational
+support for fractional seconds, time zone abbreviations, and UTC offsets.<chrono>
clock for computing with leap seconds which is
+also supported by the IANA Time Zone
+Database.+Everything proposed herein has been fully implemented here: +
+ ++https://github.com/HowardHinnant/date ++ +
+The implementation includes full documentation, and an active community of users +with positive field experience. The implementation has been ported to Windows, +Linux, and OS X. +
+ ++The API stresses: +
+ +<chrono>
library.+Listing "Performance" in the API design deserves a little explanation as one +usually thinks of that as an implementation issue. Think of it this way: +
+ +vector<T>::push_front(const T&)
existed, that would
+encourage inefficient code, even though it would be trivial to implement.
+list<T>::operator[](size_type index)
existed, that would
+encourage inefficient code, even though it would be trivial to implement (by
+incrementing from begin()
or decrementing from end()
).
+
+This API makes it convenient to write efficient code, and inconvenient to write
+inefficient code. It turns out that conversion between a field type such as
+{year, month, day}
and a serial type such as
+{count-of-days}
is one of the more expensive operations when
+dealing with calendrical computations. Both data structures are very useful
+(just as both vector
and list
are very useful). So
+this library puts you in control of when and how often that conversion
+takes place, and makes it easy to avoid such conversions when not necessary.
+
+One can create a year
like this:
+
+ ++auto y = year{2016}; +
+Just like <chrono>
, type safety is taken very seriously. The
+type year
is distinct from type int
, just as 3
+can never mean "3 seconds", unless it is explicitly typed to do so:
+seconds{3}
.
+
+And just like seconds
, there is a year literal suffix which can help make
+your code more readable:
+
+ ++auto y = 2016y; +
+year
is a partial-calendar-type. It can be combined with
+other partial-calendar-types to create a full-calendar-type such as
+year_month_day
. Full-calendar-types can be converted to and from
+the family of system_clock::time_point
s. Full-calendar-types such
+as 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.
+The only thing that happens is a year
, month
and
+day
are stored inside the year_month_day
.
+
+ ++year_month_day ymd1{2016y, month{5}, day{29}}; +
+This is a very simple operation and can even be made
+constexpr
when all of the inputs are compile-time constants. And
+conventional syntax is available which means the exact same thing, with
+the same run-time or compile-time performance. It can make date literals much
+more readable without sacrificing type safety:
+
+ ++constexpr year_month_day ymd1{2016y, month{5}, day{29}}; +constexpr auto ymd2 = 2016y/may/29d; +static_assert(ymd1 == ymd2); +static_assert(ymd1.year() == 2016y); +static_assert(ymd1.month() == may); +static_assert(ymd1.day() == 29d); +
+year_month_day
is a very simple, very understandable
+calendrical data structure:
+
+ ++class year_month_day +{ + chrono::year y_; // exposition only + chrono::month m_; // exposition only + chrono::day d_; // exposition only + +public: + constexpr year_month_day(const chrono::year& y, const chrono::month& m, const chrono::day& d) noexcept; + // ... +
+By now you should be yawning and muttering "so what?" +
+ +
+Now we introduce a little <chrono>
infrastructure that serves
+as the communication channel with simplistic calendrical data structures such as
+year_month_day
.
+
+ ++using days = duration<int32_t, ratio_multiply<ratio<24>, hours::period>>; +template <class Duration> using sys_time = time_point<system_clock, Duration>; +using sys_days = sys_time<days>; +
+sys_days
is a std::chrono::time_point
. This
+time_point
is based on system_clock
and has a very coarse
+precision: 24 hours. Just as system_clock::time_point
is nothing more
+than a count of microseconds (or nanoseconds, or whatever), sys_days
is
+simply a count of days since the system_clock
epoch. And
+sys_days
is fully interoperable with
+system_clock::time_point
in all of the ways normal to the
+<chrono>
library:
+
sys_days
implicitly converts to system_clock::time_point
+with no truncation error.system_clock::time_point
does not implicitly convert to
+sys_days
because it would involve truncation error.system_clock::time_point
by
+using the existing <chrono>
facilities time_point_cast
+or floor
.+ ++constexpr system_clock::time_point tp = sys_days{2016y/may/29d}; // Convert date to time_point +static_assert(tp.time_since_epoch() == 1'464'480'000'000'000us); +constexpr auto ymd = year_month_day{floor<days>(tp)}; // Convert time_point to date +static_assert(ymd == 2016y/may/29d); +
+The calendrical type year_month_day
provides conversions to and
+from sys_days
. This conversion is easy to do for std::lib
+implementors using algorithms
+such as these.
+If the committee standardizes existing practice and specifies that
+system_clock
measures
+Unix Time,
+then it will be equally easy for
+anyone to write their own calendar system which converts to and from
+sys_days
(e.g. the coptic example in the introduction).
+
+This proposal actually contains a second calendar. It is so closely related to the
+civil calendar that we normally don't think of it as another calendar. We often
+refer to dates like "the 5th Sunday of May in 2016" as opposed to "the 29th of May
+in 2016." This proposal makes it so easy to build fully functional calendars that
+interoperate with system_clock::time_point
, that it is nearly trivial
+to include such functionality:
+
+ ++constexpr system_clock::time_point tp = sys_days{sun[5]/may/2016}; // Convert date to time_point +static_assert(tp.time_since_epoch() == 1'464'480'000'000'000us); +constexpr auto ymd = year_month_weekday{floor<days>(tp)}; // Convert time_point to date +static_assert(ymd == sun[5]/may/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.
+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
+(by bouncing off of sys_days
) just as it will with any other calendar
+that interoperates with sys_days
:
+
+ ++static_assert(2016y/may/29d == year_month_day{sun[5]/may/2016}); +
+Since year_month_day
is so easy to convert to (or from) a
+time_point
it makes sense to convert to a time_point
when
+you need to talk about a date and time-of-day:
+
+ ++constexpr auto tp = sys_days{2016y/may/29d} + 7h + 30min; // 2016-05-29 07:30 UTC +
+The time zone is implicitly UTC because system_clock
tracks Unix Time which is (a very
+close approximation to) UTC. If you need another time zone, no worries, we'll
+get there. And remember, tp
above is a
+system_clock::time_point
, except with minutes precision. You can
+compare it with system_clock::now()
to find out if the date is in
+the past or the future. Also note that the syntax above (like
+<chrono>
) is precision neutral. That's because the
+syntax above is <chrono>
, except for the part
+converting a calendar type into the <chrono>
system. If you
+suddenly need to convert your minutes-precision time point into seconds or
+milliseconds (or whatever) precision, the change is seamlessly handled by the
+existing <chrono>
system:
+
+ ++constexpr auto tp = sys_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 UTC +
+Simple streaming is provided: +
+ ++ ++cout << tp << '\n'; // 2016-05-29 07:30:06.153 +
+But I need the time in Tokyo! +
+ ++ ++auto tp = sys_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 UTC +auto zt = make_zoned("Asia/Tokyo", tp); +cout << zt << '\n'; // 2016-05-29 16:30:06.153 JST +
+The helper function make_zoned
creates a type zoned_time
which
+is templated on the duration type of tp
. The use of make_zoned
+deduces that you desire milliseconds precision in this example. This effectively
+pairs a time zone with a time point. In this example we pair the time zone
+"Asia/Tokyo" with a sys_time
(which is implicitly UTC). When printed
+out, you see the local time, and by default the current time zone abbreviation. Also
+by default, you see the full precision of the zoned_time
.
+
+Sometimes, instead of specifying the time in UTC as above, it is convenient to specify +the time in terms of the local time of the time zone. It is very easy to change the +above example to mean 7:30 JST instead of 16:30 JST: +
+ ++ ++auto tp = local_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 +auto zt = make_zoned("Asia/Tokyo", tp); +cout << zt << '\n'; // 2016-05-29 07:30:06.153 JST +
+The only change to the code is the use of local_days
in
+place of sys_days
. local_days
is also a
+std::chrono::time_point
but it has no clock::now()
+functionality. This time_point
is called local_time
.
+A local_time
can refer to any time zone. In the above
+example when we pair "Asia/Tokyo" with the local_time
, the
+result becomes a zoned_time
with the 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.
+But as seen in this example, the meaning can be quite different.
+
+The client of the calendar library can easily use the calendar types with the
+time zone library, specifying times either in the local time, or in UTC, simply
+by switching between local_days
and sys_days
. Here
+is an example that sets up a meeting at 9am on the third Tuesday of June, 2016
+in New York:
+
+ ++auto zt = make_zoned("America/New_York", local_days{tue[3]/jun/2016} + 9h); +cout << zt << '\n'; // 2016-06-21 09:00:00 EDT +
+Need to set up a video conference with your partners in Helsinki? +
+ ++ ++cout << make_zoned("Europe/Helsinki", zt) << '\n'; +
+This converts one zoned_time
into another zoned_time
where
+the only difference is changing from "America/New_York" to "Europe/Helsinki". The
+conversion preserves the UTC equivalent in both zoned_time
s, and
+therefore outputs:
+
+ ++2016-06-21 16:00:00 EEST +
+And if this is not the formatting you prefer, that is easily fixed too: +
+ ++ ++cout << format("%F %H:%M %z", make_zoned("Europe/Helsinki", zt)) << '\n'; +// 2016-06-21 16:00 +0300 +
+Or perhaps properly localized: +
+ ++ ++cout << format(locale{"fi_FI"}, "%c", make_zoned("Europe/Helsinki", zt)) << '\n'; +// Ti 21 Kes 16:00:00 2016 +
+ ++Text in grey boxes is not proposed wording. +
+ ++Append to synopsis in 20.15.2 Header
<chrono>
synopsis [time.syn]: +
+ ++namespace std { +namespace chrono { +// ... +using days = duration<signed integer type of at least 25 bits, ratio_multiply<ratio<24>, hours::period>>; +using weeks = duration<signed integer type of at least 22 bits, ratio_multiply<ratio<7>, days::period>>; +using years = duration<signed integer type of at least 17 bits, ratio_multiply<ratio<146097, 400>, days::period>>; +using months = duration<signed integer type of at least 20 bits, ratio_divide<years::period, ratio<12>>>; + +template <class Duration> using sys_time = time_point<system_clock, Duration>; +using sys_days = sys_time<days>; +using sys_seconds = sys_time<seconds>; + +template <class CharT, class Traits, class Duration> +basic_ostream<CharT, Traits>& +operator<<(basic_ostream<CharT, Traits>& os, const sys_time<Duration>& tp); + +template <class CharT, class Traits> +basic_ostream<CharT, Traits>& +operator<<(basic_ostream<CharT, Traits>& os, const sys_days& dp); + +struct local_t {}; +template <class Duration> using local_time = time_point<local_t, Duration>; +using local_days = local_time<days>; +using local_seconds = local_time<seconds>; + +template <class CharT, class Traits, class Duration> +basic_ostream<CharT, Traits>& +operator<<(basic_ostream<CharT, Traits>& os, const local_time<Duration>& tp); + +// civil calendar + +struct last_spec; + +class day; + +constexpr bool operator==(const day& x, const day& y) noexcept; +constexpr bool operator!=(const day& x, const day& y) noexcept; +constexpr bool operator< (const day& x, const day& y) noexcept; +constexpr bool operator> (const day& x, const day& y) noexcept; +constexpr bool operator<=(const day& x, const day& y) noexcept; +constexpr bool operator>=(const day& x, const day& y) noexcept; + +constexpr day operator+(const day& x, const days& y) noexcept; +constexpr day operator+(const days& x, const day& y) noexcept; +constexpr day operator-(const day& x, const days& y) noexcept; +constexpr days operator-(const day& x, const day& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const day& d); + +class month; + +constexpr bool operator==(const month& x, const month& y) noexcept; +constexpr bool operator!=(const month& x, const month& y) noexcept; +constexpr bool operator< (const month& x, const month& y) noexcept; +constexpr bool operator> (const month& x, const month& y) noexcept; +constexpr bool operator<=(const month& x, const month& y) noexcept; +constexpr bool operator>=(const month& x, const month& y) noexcept; + +constexpr month operator+(const month& x, const months& y) noexcept; +constexpr month operator+(const months& x, const month& y) noexcept; +constexpr month operator-(const month& x, const months& y) noexcept; +constexpr months operator-(const month& x, const month& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const month& m); + +class year; + +constexpr bool operator==(const year& x, const year& y) noexcept; +constexpr bool operator!=(const year& x, const year& y) noexcept; +constexpr bool operator< (const year& x, const year& y) noexcept; +constexpr bool operator> (const year& x, const year& y) noexcept; +constexpr bool operator<=(const year& x, const year& y) noexcept; +constexpr bool operator>=(const year& x, const year& y) noexcept; + +constexpr year operator+(const year& x, const years& y) noexcept; +constexpr year operator+(const years& x, const year& y) noexcept; +constexpr year operator-(const year& x, const years& y) noexcept; +constexpr years operator-(const year& x, const year& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year& y); + +class weekday; + +constexpr bool operator==(const weekday& x, const weekday& y) noexcept; +constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; + +constexpr weekday operator+(const weekday& x, const days& y) noexcept; +constexpr weekday operator+(const days& x, const weekday& y) noexcept; +constexpr weekday operator-(const weekday& x, const days& y) noexcept; +constexpr days operator-(const weekday& x, const weekday& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const weekday& wd); + +class weekday_indexed; + +constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; +constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const weekday_indexed& wdi); + +class weekday_last; + +constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; +constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const weekday_last& wdl); + +class month_day; + +constexpr bool operator==(const month_day& x, const month_day& y) noexcept; +constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator< (const month_day& x, const month_day& y) noexcept; +constexpr bool operator> (const month_day& x, const month_day& y) noexcept; +constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const month_day& md); + +class month_day_last; + +constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const month_day_last& mdl); + +class month_weekday; + +constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; +constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const month_weekday& mwd); + +class month_weekday_last; + +constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; +constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const month_weekday_last& mwdl); + +class year_month; + +constexpr bool operator==(const year_month& x, const year_month& y) noexcept; +constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator< (const year_month& x, const year_month& y) noexcept; +constexpr bool operator> (const year_month& x, const year_month& y) noexcept; +constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; + +constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; +constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; +constexpr months operator-(const year_month& x, const year_month& y) noexcept; +constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; +constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year_month& ym); + +class year_month_day; + +constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; + +constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; +constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; +constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year_month_day& ymd); + +class year_month_day_last; + +constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept; + +constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) noexcept; +constexpr year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year_month_day_last& ymdl); + +class year_month_weekday; + +constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; +constexpr bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept; + +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept; +constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year_month_weekday& ymwdi); + +class year_month_weekday_last; + +constexpr bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; +constexpr bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; + +constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +constexpr year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; +constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; +constexpr year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; +constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const year_month_weekday_last& ymwdl); + +// civil calendar conventional syntax operators +constexpr year_month operator/(const year& y, const month& m) noexcept; +constexpr year_month operator/(const year& y, int m) noexcept; +constexpr month_day operator/(const month& m, const day& d) noexcept; +constexpr month_day operator/(const month& m, int d) noexcept; +constexpr month_day operator/(int m, const day& d) noexcept; +constexpr month_day operator/(const day& d, const month& m) noexcept; +constexpr month_day operator/(const day& d, int m) noexcept; +constexpr month_day_last operator/(const month& m, last_spec) noexcept; +constexpr month_day_last operator/(int m, last_spec) noexcept; +constexpr month_day_last operator/(last_spec, const month& m) noexcept; +constexpr month_day_last operator/(last_spec, int m) noexcept; +constexpr month_weekday operator/(const month& m, const weekday_indexed& wdi) noexcept; +constexpr month_weekday operator/(int m, const weekday_indexed& wdi) noexcept; +constexpr month_weekday operator/(const weekday_indexed& wdi, const month& m) noexcept; +constexpr month_weekday operator/(const weekday_indexed& wdi, int m) noexcept; +constexpr month_weekday_last operator/(const month& m, const weekday_last& wdl) noexcept; +constexpr month_weekday_last operator/(int m, const weekday_last& wdl) noexcept; +constexpr month_weekday_last operator/(const weekday_last& wdl, const month& m) noexcept; +constexpr month_weekday_last operator/(const weekday_last& wdl, int m) noexcept; +constexpr year_month_day operator/(const year_month& ym, const day& d) noexcept; +constexpr year_month_day operator/(const year_month& ym, int d) noexcept; +constexpr year_month_day operator/(const year& y, const month_day& md) noexcept; +constexpr year_month_day operator/(int y, const month_day& md) noexcept; +constexpr year_month_day operator/(const month_day& md, const year& y) noexcept; +constexpr year_month_day operator/(const month_day& md, int y) noexcept; +constexpr year_month_day_last operator/(const year_month& ym, last_spec) noexcept; +constexpr year_month_day_last operator/(const year& y, const month_day_last& mdl) noexcept; +constexpr year_month_day_last operator/(int y, const month_day_last& mdl) noexcept; +constexpr year_month_day_last operator/(const month_day_last& mdl, const year& y) noexcept; +constexpr year_month_day_last operator/(const month_day_last& mdl, int y) noexcept; +constexpr year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; +constexpr year_month_weekday operator/(const year& y, const month_weekday& mwd) noexcept; +constexpr year_month_weekday operator/(int y, const month_weekday& mwd) noexcept; +constexpr year_month_weekday operator/(const month_weekday& mwd, const year& y) noexcept; +constexpr year_month_weekday operator/(const month_weekday& mwd, int y) noexcept; +constexpr year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) noexcept; +constexpr year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) noexcept; +constexpr year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) noexcept; +constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept; +constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept; + +// time_of_day +enum {am = 1, pm}; +template <class Duration> class time_of_day; +time_of_day<hours> +time_of_day<minutes> +time_of_day<seconds> +time_of_day<duration<Rep, Period>> + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const time_of_day<hours>& t); + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const time_of_day<minutes>& t); + +template<class CharT, class Traits> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const time_of_day<seconds>& t); + +template<class CharT, class Traits, class Rep, class Period> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const time_of_day<duration<Rep, Period>>& t); + +template <class Rep, class Period> +constexpr time_of_day<duration<Rep, Period>> make_time(duration<Rep, Period> d) noexcept; + +constexpr time_of_day<hours> make_time(hours h, unsigned md) noexcept; +constexpr time_of_day<minutes> make_time(hours h, minutes m, unsigned md) noexcept; +constexpr time_of_day<seconds> make_time(hours h, minutes m, seconds s, unsigned md) noexcept; + +template <class Rep, class Period> +constexpr time_of_day<duration<Rep, Period>> +make_time(hours h, minutes m, seconds s, duration<Rep, Period> sub_s, unsigned md) noexcept; + +// time zone database + +struct TZ_DB; +const TZ_DB& get_tzdb(); +const time_zone* locate_zone(const string& tz_name); +const time_zone* current_zone(); + +// Remote time zone database -- Needs discussion + +const TZ_DB& reload_tzdb(); +string remote_version(); +bool remote_download(const string& version); +bool remote_install(const string& version); + +// exception classes +class nonexistent_local_time; +class ambiguous_local_time; + +struct sys_info; +ostream& operator<<(ostream& os, const sys_info& si); + +struct local_info; +ostream& operator<<(ostream& os, const local_info& li); + +enum class choose {earliest, latest}; +class time_zone; + +bool operator==(const time_zone& x, const time_zone& y); +bool operator!=(const time_zone& x, const time_zone& y); + +bool operator<(const time_zone& x, const time_zone& y); +bool operator>(const time_zone& x, const time_zone& y); +bool operator<=(const time_zone& x, const time_zone& y); +bool operator>=(const time_zone& x, const time_zone& y); + +ostream& operator<<(ostream& os, const time_zone& z); + +template <class Duration> class zoned_time; + +using zoned_seconds = zoned_time<seconds>; + +template <class Duration1, class Duration2> +bool +operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); + +template <class Duration1, class Duration2> +bool +operator!=(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); + +template <class Duration> +basic_ostream<class CharT, class Traits>& +operator<<(basic_ostream<class CharT, class Traits>& os, const zoned_time<Duration>& t); + +// make_zoned + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(sys_time<Duration> tp); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, local_time<Duration> tp); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, local_time<Duration> tp); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, local_time<Duration> tp, choose c); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, local_time<Duration> tp, choose c); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const zoned_time<Duration>& zt); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt, choose c); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const zoned_time<Duration>& zt, choose c); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const sys_time<Duration>& st); + +template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const sys_time<Duration>& st); + +// format + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + local_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, local_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + const zoned_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, const zoned_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + sys_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, sys_time<Duration> tp); + +// const CharT* formats + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, local_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, local_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, const zoned_time<Duration>& tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, const zoned_time<Duration>& tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, sys_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, sys_time<Duration> tp); + +// parse + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +// const CharT* formats + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, basic_string<CharT, Traits>& abbrev, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, minutes& offset, + basic_string<CharT, Traits>& abbrev); + +// leap second support + +class utc_clock; + +template <class Duration> + using utc_time = time_point<utc_clock, Duration>; + +using utc_seconds = utc_time<seconds>; + +template <class Duration> + utc_time<common_type_t<Duration, seconds>> to_utc_time(sys_time<Duration> t); + +template <class Duration> + sys_time<common_type_t<Duration, seconds>> to_sys_time(utc_time<Duration> u) + +class leap; + +bool operator==(const leap& x, const leap& y); +bool operator!=(const leap& x, const leap& y); +bool operator< (const leap& x, const leap& y); +bool operator> (const leap& x, const leap& y); +bool operator<=(const leap& x, const leap& y); +bool operator>=(const leap& x, const leap& y); + +template <class Duration> bool operator==(const const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator==(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator!=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator!=(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator< (const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator< (const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator> (const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator> (const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator<=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator<=(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator>=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator>=(const sys_time<Duration>& x, const leap& y); + +class link; + +bool operator==(const link& x, const link& y); +bool operator!=(const link& x, const link& y); +bool operator< (const link& x, const link& y); +bool operator> (const link& x, const link& y); +bool operator<=(const link& x, const link& y); +bool operator>=(const link& x, const link& y); + +} // namespace chrono + +inline namespace literals { +inline namespace chrono_literals { +// ... +constexpr chrono::last_spec last{}; + +constexpr chrono::weekday sun{0}; +constexpr chrono::weekday mon{1}; +constexpr chrono::weekday tue{2}; +constexpr chrono::weekday wed{3}; +constexpr chrono::weekday thu{4}; +constexpr chrono::weekday fri{5}; +constexpr chrono::weekday sat{6}; + +constexpr chrono::month jan{1}; +constexpr chrono::month feb{2}; +constexpr chrono::month mar{3}; +constexpr chrono::month apr{4}; +constexpr chrono::month may{5}; +constexpr chrono::month jun{6}; +constexpr chrono::month jul{7}; +constexpr chrono::month aug{8}; +constexpr chrono::month sep{9}; +constexpr chrono::month oct{10}; +constexpr chrono::month nov{11}; +constexpr chrono::month dec{12}; + +constexpr chrono::day operator "" d(unsigned long long d) noexcept; +constexpr chrono::year operator "" y(unsigned long long y) noexcept; +} +} +
+ ++Add new section [time.point.io] after 20.15.6.7 time_point_cast [time.point.cast]:: +
+template <class Duration> +ostream& +operator<<(ostream& os, const time_point<system_clock, Duration>& tp); ++ +
++ ++Remarks: This operator shall not participate in overload resolution if +
+treat_as_floating_point<typename Duration::rep>::value
is +true, or ifDuration{1} >= days{1}
. ++Effects: +
+++auto const dp = floor<days>(tp); +os << year_month_day{dp} << ' ' << make_time(tp-dp); ++Returns:
+os
. +
+ostream& operator<<(ostream& os, const sys_days& dp); ++ +
++ ++Effects: +
++ ++os << year_month_day{dp}; ++Returns:
+os
. +
+template <class Duration> ostream& operator<<(ostream& os, const local_time<Duration>& lt); ++ +
++ ++Effects: +
++ ++os << sys_time<Duration>{lt.time_since_epoch()}; ++Returns:
+os
. +
+ ++Add new section [time.calendar] after 20.15.7 Clocks [time.clocks]: +
+The types in this subclause describe the civil (Gregorian) calendar and its relationship
+to sys_days
and local_days
.
+
last_spec
[time.calendar.last]
+The struct last_spec
is used in conjunction with other calendar types to
+indicate 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.
+
+There is an constexpr
object of this type named last
in the
+chrono_literals
namespace.
+
+struct last_spec +{ + explicit last_spec() = default; +}; ++ +
day
[time.calendar.day]
+day
represents a day of a month. It normally holds values in
+the range 1 to 31. However it may hold non-negative values outside this range. It can be constructed
+with any unsigned
value, which will be subsequently truncated to fit into
+day
's unspecified internal storage. day
is equality and less-than
+comparable, and participates in basic arithmetic with days
representing the
+quantity between any two day
's. One can form a day
literal with
+d
. And one can stream out a day
.
+day
has explicit conversions to and from unsigned
.
+
+class day +{ + unsigned char d_; // exposition only +public: + explicit constexpr day(unsigned d) noexcept; + + constexpr day& operator++() noexcept; + constexpr day operator++(int) noexcept; + constexpr day& operator--() noexcept; + constexpr day operator--(int) noexcept; + + constexpr day& operator+=(const days& d) noexcept; + constexpr day& operator-=(const days& d) noexcept; + + constexpr explicit operator unsigned() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const day& x, const day& y) noexcept; +constexpr bool operator!=(const day& x, const day& y) noexcept; +constexpr bool operator< (const day& x, const day& y) noexcept; +constexpr bool operator> (const day& x, const day& y) noexcept; +constexpr bool operator<=(const day& x, const day& y) noexcept; +constexpr bool operator>=(const day& x, const day& y) noexcept; + +constexpr day operator+(const day& x, const days& y) noexcept; +constexpr day operator+(const days& x, const day& y) noexcept; +constexpr day operator-(const day& x, const days& y) noexcept; +constexpr days operator-(const day& x, const day& y) noexcept; + +ostream& operator<<(ostream& os, const day& d); ++ +
+day
is a trivially copyable class type.
+day
is a standard-layout class type.
+day
is a literal class type.
+
+explicit constexpr day::day(unsigned d) noexcept; ++ +
++ ++Effects: Constructs an object of type
+day
by constructing +d_
withd
. +
+constexpr day& day::operator++() noexcept; ++ +
++ ++Effects:
+++d_
. ++Returns:
+*this
. +
+constexpr day day::operator++(int) noexcept; ++ +
++ ++Effects:
+++(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr day& day::operator--() noexcept; ++ +
++ ++Effects:
+--d_
. ++Returns:
+*this
. +
+constexpr day day::operator--(int) noexcept; ++ +
++ ++Effects:
+--(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr day& day::operator+=(const days& d) noexcept; ++ +
++ ++Effects:
+*this = *this + d
. ++Returns:
+*this
. +
+constexpr day& day::operator-=(const days& d) noexcept; ++ +
++ ++Effects:
+*this = *this - d
. ++Returns:
+*this
. +
+constexpr explicit day::operator unsigned() const noexcept; ++ +
++ ++Returns:
+d_
. +
+constexpr bool day::ok() const noexcept; ++ +
++ ++Returns:
+1 <= d_ && d_ <= 31
. +
+constexpr bool operator==(const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+unsigned{x} == unsigned{y}
. +
+constexpr bool operator!=(const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr bool operator< (const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+unsigned{x} < unsigned{y}
. +
+constexpr bool operator> (const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr day operator+(const day& x, const days& y) noexcept; ++ +
++ ++Returns:
+day{unsigned{x} + y.count()}
. +
+constexpr day operator+(const days& x, const day& y) noexcept; ++ +
++ ++Returns:
+y + x
. +
+constexpr day operator-(const day& x, const days& y) noexcept; ++ +
++ ++Returns:
+x + -y
. +
+constexpr days operator-(const day& x, const day& y) noexcept; ++ +
++ ++Returns:
+days{static_cast<days::rep>(unsigned{x} - unsigned{y})}
. +
+ostream& operator<<(ostream& os, const day& d); ++ +
++ ++Effects: Inserts a decimal integral text representation of
+d
into +os
. Single digit values are prefixed with'0'
. ++Returns:
+os
. +
+constexpr day operator "" d(unsigned long long d) noexcept; ++ +
++ ++Returns:
+day{static_cast<unsigned>(d)}
. +
month
[time.calendar.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.
+It can be constructed with any unsigned
value, which will be
+subsequently truncated to fit into month
's unspecified internal
+storage. month
is equality and less-than comparable, and
+participates in basic arithmetic with months
representing the
+quantity between any two month
's. One can stream out a
+month
. month
has explicit conversions to and from
+unsigned
. There are 12 month
constants, one for each
+month of the year in the chrono_literals
namespace.
+
+class month +{ + unsigned char m_; // exposition only +public: + explicit constexpr month(unsigned m) noexcept; + + constexpr month& operator++() noexcept; + constexpr month operator++(int) noexcept; + constexpr month& operator--() noexcept; + constexpr month operator--(int) noexcept; + + constexpr month& operator+=(const months& m) noexcept; + constexpr month& operator-=(const months& m) noexcept; + + constexpr explicit operator unsigned() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const month& x, const month& y) noexcept; +constexpr bool operator!=(const month& x, const month& y) noexcept; +constexpr bool operator< (const month& x, const month& y) noexcept; +constexpr bool operator> (const month& x, const month& y) noexcept; +constexpr bool operator<=(const month& x, const month& y) noexcept; +constexpr bool operator>=(const month& x, const month& y) noexcept; + +constexpr month operator+(const month& x, const months& y) noexcept; +constexpr month operator+(const months& x, const month& y) noexcept; +constexpr month operator-(const month& x, const months& y) noexcept; +constexpr months operator-(const month& x, const month& y) noexcept; + +ostream& operator<<(ostream& os, const month& m); ++ +
+month
is a trivially copyable class type.
+month
is a standard-layout class type.
+month
is a literal class type.
+
+explicit constexpr month::month(unsigned m) noexcept; ++ +
++ ++Effects: Constructs an object of type
+month
by constructing +m_
withm
. +
+constexpr month& month::operator++() noexcept; ++ +
++ ++Effects: If
+m_ != 12
,++m_
. Otherwise sets +m_
to 1. ++Returns:
+*this
. +
+constexpr month month::operator++(int) noexcept; ++ +
++ ++Effects:
+++(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr month& month::operator--() noexcept; ++ +
++ ++Effects: If
+m_ != 1
,--m_
. Otherwise sets +m_
to 12. ++Returns:
+*this
. +
+constexpr month month::operator--(int) noexcept; ++ +
++ ++Effects:
+--(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr month& month::operator+=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this + m
. ++Returns:
+*this
. +
+constexpr month& month::operator-=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this - m
. ++Returns:
+*this
. +
+constexpr explicit month::operator unsigned() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr bool month::ok() const noexcept; ++ +
++ ++Returns:
+1 <= m_ && m_ <= 12
. +
+constexpr bool operator==(const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+unsigned{x} == unsigned{y}
. +
+constexpr bool operator!=(const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr bool operator< (const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+unsigned{x} < unsigned{y}
. +
+constexpr bool operator> (const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const month& x, const month& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr month operator+(const month& x, const months& y) noexcept; ++ +
++ ++Returns: A
+month
for whichok() == true
and is found as +if by incrementing (or decrementing ify < months{0}
)x
, +y
times. Ifmonth.ok() == false
prior to this operation, +behaves as if*this
is first brought into the range [1, 12] by modular +arithmetic. [Note: For examplemonth{0}
becomesmonth{12}
, +andmonth{13}
becomesmonth{1}
. — end note] ++Complexity: O(1) with respect to the value of
+y
. That is, repeated +increments or decrements is not a valid implementation. ++Example:
+feb + months{11} == jan
. +
+constexpr month operator+(const months& x, const month& y) noexcept; ++ +
++ ++Returns:
+y + x
. +
+constexpr month operator-(const month& x, const months& y) noexcept; ++ +
++ ++Returns:
+x + -y
. +
+constexpr months operator-(const month& x, const month& y) noexcept; ++ +
++ ++Requires:
+x.ok() == true
andy.ok() == true
. ++Returns: A value of
+months
in the range ofmonths{0}
to +months{11}
inclusive. ++Remarks: The returned value
+m
shall satisfy the equality: +y + m == x
. ++Example:
+jan - feb == months{11}
. +
+ostream& operator<<(ostream& os, const month& m); ++ +
++ ++Effects: If
+ok() == true
outputs the same string that would be +output for the month field byasctime
. Otherwise outputs +unsigned{m} << " is not a valid month"
. ++Returns:
+os
. +
year
[time.calendar.year]
+year
represents a year in the civil calendar. It shall represent values
+in the range [min(), max()]
. It can be constructed with any
+int
value, which will be subsequently truncated to fit into
+year
's internal unspecified storage. year
is equality and less-than
+comparable, and participates in basic arithmetic with years
representing the
+quantity between any two year
's. One can form a year
literal
+with y
. And one can stream out a year
.
+year
has explicit conversions to and from int
.
+
+class year +{ + short y_; // exposition only +public: + explicit constexpr year(int y) noexcept; + + constexpr year& operator++() noexcept; + constexpr year operator++(int) noexcept; + constexpr year& operator--() noexcept; + constexpr year operator--(int) noexcept; + + constexpr year& operator+=(const years& y) noexcept; + constexpr year& operator-=(const years& y) noexcept; + + constexpr bool is_leap() const noexcept; + + constexpr explicit operator int() const noexcept; + constexpr bool ok() const noexcept; + + static constexpr year min() noexcept; + static constexpr year max() noexcept; +}; + +constexpr bool operator==(const year& x, const year& y) noexcept; +constexpr bool operator!=(const year& x, const year& y) noexcept; +constexpr bool operator< (const year& x, const year& y) noexcept; +constexpr bool operator> (const year& x, const year& y) noexcept; +constexpr bool operator<=(const year& x, const year& y) noexcept; +constexpr bool operator>=(const year& x, const year& y) noexcept; + +constexpr year operator+(const year& x, const years& y) noexcept; +constexpr year operator+(const years& x, const year& y) noexcept; +constexpr year operator-(const year& x, const years& y) noexcept; +constexpr years operator-(const year& x, const year& y) noexcept; + +ostream& operator<<(ostream& os, const year& y); ++ +
+year
is a trivially copyable class type.
+year
is a standard-layout class type.
+year
is a literal class type.
+
+explicit constexpr year::year(int y) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year
by constructing +y_
withy
. +
+constexpr year& year::operator++() noexcept; ++ +
++ ++Effects:
+++y_
. ++Returns:
+*this
. +
+constexpr year year::operator++(int) noexcept; ++ +
++ ++Effects:
+++(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr year& year::operator--() noexcept; ++ +
++ ++Effects:
+--y_
. ++Returns:
+*this
. +
+constexpr year year::operator--(int) noexcept; ++ +
++ ++Effects:
+--(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr year& year::operator+=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this + y
. ++Returns:
+*this
. +
+constexpr year& year::operator-=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this - y
. ++Returns:
+*this
. +
+constexpr bool year::is_leap() const noexcept; ++ +
++ ++Returns:
+true
if*this
represents a leap year, else +returnsfalse
. +
+constexpr explicit year::operator int() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr bool year::ok() const noexcept; ++ +
++ ++Returns:
+true
. +
+static constexpr year year::min() noexcept; ++ +
++ ++Returns:
+year{numeric_limits<decltype(y_)>::min()}
. +
+static constexpr year year::max() noexcept; ++ +
++ ++Returns:
+year{numeric_limits<decltype(y_)>::max()}
. +
+constexpr bool operator==(const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+int{x} == int{y}
. +
+constexpr bool operator!=(const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr bool operator< (const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+int{x} < int{y}
. +
+constexpr bool operator> (const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr year operator+(const year& x, const years& y) noexcept; ++ +
++ ++Returns:
+year{int{x} + y.count()}
. +
+constexpr year operator+(const years& x, const year& y) noexcept; ++ +
++ ++Returns:
+y + x
. +
+constexpr year operator-(const year& x, const years& y) noexcept; ++ +
++ ++Returns:
+x + -y
. +
+constexpr years operator-(const year& x, const year& y) noexcept; ++ +
++ ++Returns:
+years{int{x} - int{y}}
. +
+ostream& operator<<(ostream& os, const year& y); ++ +
++ ++Effects: Inserts a signed decimal integral text representation of
+y
+intoos
. If the year is less than four decimal digits, pads the year with +'0'
to four digits. If the year is negative, prefixes with'-'
. ++Returns:
+os
. +
+constexpr year operator "" y(unsigned long long y) noexcept; ++ +
++ ++Returns:
+year{static_cast<int>(y)}
. +
weekday
[time.calendar.weekday]
+weekday
represents a day of the week in the civil calendar. It
+normally holds values in the range 0 to 6, corresponding to Sunday thru
+Saturday. However it may hold non-negative values outside this range. It can be
+constructed with any unsigned
value, which will be subsequently
+truncated to fit into weekday
'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 thru Saturday only because this is consistent with existing C and C++
+practice. However weekday
's comparison and arithmetic operations
+treat the days of the week as a circular range, with no beginning and no end.
+One can stream out a weekday
. weekday
has explicit
+conversions to and from unsigned
. There are 7 weekday
+constants, one for each day of the week in the chrono_literals
+namespace.
+
+A weekday
can be implicitly constructed from a sys_days
. This
+is the computation that discovers the day of the week of an arbitrary date.
+
+A weekday
can be indexed with either unsigned
or
+last
. This produces new types which represent the first, second, third,
+fourth, fifth or last weekdays of a month.
+
+class weekday +{ + unsigned char wd_; // exposition only +public: + explicit constexpr weekday(unsigned wd) noexcept; + constexpr weekday(const sys_days& dp) noexcept; + constexpr explicit weekday(const local_days& dp) noexcept; + + constexpr weekday& operator++() noexcept; + constexpr weekday operator++(int) noexcept; + constexpr weekday& operator--() noexcept; + constexpr weekday operator--(int) noexcept; + + constexpr weekday& operator+=(const days& d) noexcept; + constexpr weekday& operator-=(const days& d) noexcept; + + constexpr explicit operator unsigned() const noexcept; + constexpr bool ok() const noexcept; + + constexpr weekday_indexed operator[](unsigned index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; +}; + +constexpr bool operator==(const weekday& x, const weekday& y) noexcept; +constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; + +constexpr weekday operator+(const weekday& x, const days& y) noexcept; +constexpr weekday operator+(const days& x, const weekday& y) noexcept; +constexpr weekday operator-(const weekday& x, const days& y) noexcept; +constexpr days operator-(const weekday& x, const weekday& y) noexcept; + +ostream& operator<<(ostream& os, const weekday& wd); ++ +
+weekday
is a trivially copyable class type.
+weekday
is a standard-layout class type.
+weekday
is a literal class type.
+
+explicit constexpr weekday::weekday(unsigned wd) noexcept; ++ +
++ ++Effects: Constructs an object of type
+weekday
by constructing +wd_
withwd
. +
+constexpr weekday(const sys_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+weekday
by computing what day +of the week corresponds to thesys_days dp
, and representing that day of +the week inwd_
. ++Example: If
+dp
represents 1970-01-01, the constructed +weekday
shall represent Thursday by storing 4 inwd_
. +
+constexpr explicit weekday(const local_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+weekday
by computing what day +of the week corresponds to thelocal_days dp
, and representing that day of +the week inwd_
. ++The value after construction shall be identical to that constructed from +
+sys_days{dp.time_since_epoch()}
. +
+constexpr weekday& weekday::operator++() noexcept; ++ +
++ ++Effects: If
+wd_ != 6
,++wd_
. Otherwise sets +wd_
to 0. ++Returns:
+*this
. +
+constexpr weekday weekday::operator++(int) noexcept; ++ +
++ ++Effects:
+++(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr weekday& weekday::operator--() noexcept; ++ +
++ ++Effects: If
+wd_ != 0
,--wd_
. Otherwise sets +wd_
to 6. ++Returns:
+*this
. +
+constexpr weekday weekday::operator--(int) noexcept; ++ +
++ ++Effects:
+--(*this)
. ++Returns: A copy of
+*this
as it existed on entry to this member +function. +
+constexpr weekday& weekday::operator+=(const days& d) noexcept; ++ +
++ ++Effects:
+*this = *this + d
. ++Returns:
+*this
. +
+constexpr weekday& weekday::operator-=(const days& d) noexcept; ++ +
++ ++Effects:
+*this = *this - d
. ++Returns:
+*this
. +
+constexpr explicit weekday::operator unsigned() const noexcept; ++ +
++ ++Returns:
+wd_
. +
+constexpr bool weekday::ok() const noexcept; ++ +
++ ++Returns:
+wd_ <= 6
. +
+constexpr weekday_indexed weekday::operator[](unsigned index) const noexcept; ++ +
++ ++Returns:
+{*this, index}
. +
+constexpr weekday_last weekday::operator[](last_spec) const noexcept; ++ +
++ ++Returns:
+weekday_last{*this}
. +
+constexpr bool operator==(const weekday& x, const weekday& y) noexcept; ++ +
++ ++Returns:
+unsigned{x} == unsigned{y}
. +
+constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr weekday operator+(const weekday& x, const days& y) noexcept; ++ +
++ ++Returns: A
+weekday
for whichok() == true
and is found as +if by incrementing (or decrementing ify < days{0}
)x
, +y
times. Ifweekday.ok() == false
prior to this operation, +behaves as if*this
is first brought into the range [0, 6] by modular +arithmetic. [Note: For exampleweekday{7}
becomes +weekday{0}
. — end note] ++Complexity: O(1) with respect to the value of
+y
. That is, repeated +increments or decrements is not a valid implementation. ++Example:
+mon + days{6} == sun
. +
+constexpr weekday operator+(const days& x, const weekday& y) noexcept; ++ +
++ ++Returns:
+y + x
. +
+constexpr weekday operator-(const weekday& x, const days& y) noexcept; ++ +
++ ++Returns:
+x + -y
. +
+constexpr days operator-(const weekday& x, const weekday& y) noexcept; ++ +
++ ++Requires:
+x.ok() == true
andy.ok() == true
. ++Returns: A value of
+days
in the range ofdays{0}
to +days{6}
inclusive. ++Remarks: The returned value
+d
shall satisfy the equality: +y + d == x
. ++Example:
+sun - mon == days{6}
. +
+ostream& operator<<(ostream& os, const weekday& wd); ++ +
++ ++Effects: If
+ok() == true
outputs the same string that would be +output for the weekday field byasctime
. Otherwise outputs +unsigned{wd} << " is not a valid weekday"
. ++Returns:
+os
. +
weekday_indexed
[time.calendar.weekday_indexed]
+weekday_indexed
represents a weekday
and a small index in the
+range 1 to 5. This class is used to represent the first, second, third, fourth or fifth
+weekday of a month. It is most easily constructed by indexing a weekday
.
+
+[Example: +
+ ++ ++constexpr auto wdi = sun[2]; // wdi is the second Sunday of an as yet unspecified month +static_assert(wdi.weekday() == sun); +static_assert(wdi.index() == 2); +
+— end example:] +
+ ++class weekday_indexed +{ + chrono::weekday wd_; // exposition only + unsigned char index_; // exposition only + +public: + constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; + + constexpr chrono::weekday weekday() const noexcept; + constexpr unsigned index() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; +constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; + +ostream& operator<<(ostream& os, const weekday_indexed& wdi); ++ +
+weekday_indexed
is a trivially copyable class type.
+weekday_indexed
is a standard-layout class type.
+weekday_indexed
is a literal class type.
+
+constexpr weekday_indexed::weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; ++ +
++ ++Effects: Constructs an object of type
+weekday_indexed
by constructing +wd_
withwd
andindex_
withindex
. +
+constexpr weekday weekday_indexed::weekday() const noexcept; ++ +
++ ++Returns:
+wd_
. +
+constexpr unsigned weekday_indexed::index() const noexcept; ++ +
++ ++Returns:
+index_
. +
+constexpr bool weekday_indexed::ok() const noexcept; ++ +
++ ++Returns:
+wd_.ok() && 1 <= index_ && index_ <= 5
. +
+constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; ++ +
++ ++Returns:
+x.weekday() == y.weekday() && x.index() == y.index()
. +
+constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+ostream& operator<<(ostream& os, const weekday_indexed& wdi); ++ +
++ ++Effects: Inserts +
+os << wdi.weekday() << '[' << wdi.index() << ']'
. ++Returns:
+os
. +
weekday_last
[time.calendar.weekday_last]
+weekday_last
represents the last weekday
of a month.
+It is most easily constructed by indexing a weekday
with last
.
+
+[Example: +
+ ++ ++constexpr auto wdl = sun[last]; // wdl is the last Sunday of an as yet unspecified month +static_assert(wdl.weekday() == sun); +
+— end example:] +
+ ++class weekday_last +{ + chrono::weekday wd_; // exposition only + +public: + explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; + + constexpr chrono::weekday weekday() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; +constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; + +ostream& operator<<(ostream& os, const weekday_last& wdl); ++ +
+weekday_last
is a trivially copyable class type.
+weekday_last
is a standard-layout class type.
+weekday_last
is a literal class type.
+
+explicit constexpr weekday_last::weekday_last(const chrono::weekday& wd) noexcept; ++ +
++ ++Effects: Constructs an object of type
+weekday_last
by constructing +wd_
withwd
. +
+constexpr weekday weekday_last::weekday() const noexcept; ++ +
++ ++Returns:
+wd_
. +
+constexpr bool weekday_last::ok() const noexcept; ++ +
++ ++Returns:
+wd_.ok()
. +
+constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; ++ +
++ ++Returns:
+x.weekday() == y.weekday()
. +
+constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+ostream& operator<<(ostream& os, const weekday_last& wdl); ++ +
++ ++Effects: Inserts +
+os << wdi.weekday() << "[last]"
. ++Returns:
+os
. +
month_day
[time.calendar.month_day]
+month_day
represents a specific day
of a specific
+month
, but with an unspecified year
. One can observe the
+different components. One can assign a new value. month_day
is equality
+comparable and less-than comparable. One can stream out a month_day
.
+
+class month_day +{ + chrono::month m_; // exposition only + chrono::day d_; // exposition only + +public: + constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::day day() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const month_day& x, const month_day& y) noexcept; +constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator< (const month_day& x, const month_day& y) noexcept; +constexpr bool operator> (const month_day& x, const month_day& y) noexcept; +constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; + +ostream& operator<<(ostream& os, const month_day& md); ++ +
+month_day
is a trivially copyable class type.
+month_day
is a standard-layout class type.
+month_day
is a literal class type.
+
+constexpr month_day::month_day(const chrono::month& m, const chrono::day& d) noexcept; ++ +
++ ++Effects: Constructs an object of type
+month_day
by constructing +m_
withm
, andd_
withd
. +
+constexpr month month_day::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr day month_day::day() const noexcept; ++ +
++ ++Returns:
+d_
. +
+constexpr bool month_day::ok() const noexcept; ++ +
++ ++Returns:
+true
ifm_.ok()
is true, and if +1d <= d_
, and ifd_ <=
the number of days in month +m_
. Form_ == feb
the number of days is considered to be 29. +Otherwise returnsfalse
. +
+constexpr bool operator==(const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns:
+x.month() == y.month() && x.day() == y.day()
+
+constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
+
+constexpr bool operator< (const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns: If
+x.month() < y.month()
returnstrue
. Else +ifx.month() > y.month()
returnsfalse
. Else returns +x.day() < y.day()
. +
+constexpr bool operator> (const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+ostream& operator<<(ostream& os, const month_day& md); ++ +
++ ++Effects: Inserts +
+os << md.month() << '/' << md.day()
. ++Returns:
+os
. +
month_day_last
[time.calendar.month_day_last]
+month_day_last
represents the last day
of a month
.
+It is most easily constructed using the expression m/last
or
+last/m
, where m
is an expression with type month
.
+
+[Example: +
+ ++ ++constexpr auto mdl = feb/last; // mdl is the last day of February of an as yet unspecified year +static_assert(mdl.month() == feb); +
+— end example:] +
+ ++class month_day_last +{ + chrono::month m_; // exposition only + +public: + constexpr explicit month_day_last(const chrono::month& m) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; + +ostream& operator<<(ostream& os, const month_day_last& mdl); ++ +
+month_day_last
is a trivially copyable class type.
+month_day_last
is a standard-layout class type.
+month_day_last
is a literal class type.
+
+constexpr explicit month_day_last::month_day_last(const chrono::month& m) noexcept; ++ +
++ ++Effects: Constructs an object of type
+month_day_last
by constructing +m_
withm
. +
+constexpr month month_day_last::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr bool month_day_last::ok() const noexcept; ++ +
++ ++Returns:
+m_.ok()
. +
+constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+x.month() == y.month()
. +
+constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
+
+constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+x.month() < y.month()
. +
+constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+ostream& operator<<(ostream& os, const month_day_last& mdl); ++ +
++ ++Effects: Inserts +
+os << mdl.month() << "/last"
. ++Returns:
+os
. +
month_weekday
[time.calendar.month_weekday]
+month_weekday
represents the nth weekday
of a
+month
, of an as yet unspecified year
. To do this the
+month_weekday
stores a month
and a weekday_indexed
.
+
+class month_weekday +{ + chrono::month m_; // exposition only + chrono::weekday_indexed wdi_; // exposition only +public: + constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday_indexed weekday_indexed() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; +constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; + +ostream& operator<<(ostream& os, const month_weekday& mwd); ++ +
+month_weekday
is a trivially copyable class type.
+month_weekday
is a standard-layout class type.
+month_weekday
is a literal class type.
+
+constexpr month_weekday::month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; ++ +
++ ++Effects: Constructs an object of type
+month_weekday
by constructing +m_
withm
, andwdi_
withwdi
. +
+constexpr month month_weekday::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr weekday_indexed month_weekday::weekday_indexed() const noexcept; ++ +
++ ++Returns:
+wdi_
. +
+constexpr bool month_weekday::ok() const noexcept; ++ +
++ ++Returns:
+m_.ok() && wdi_.ok()
. +
+constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; ++ +
++ ++Returns:
+x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()
. +
+constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+ostream& operator<<(ostream& os, const month_weekday& mwd); ++ +
++ ++Effects: Inserts +
+os << mwd.month() << '/' << mwd.weekday_indexed()
. ++Returns:
+os
. +
month_weekday_last
[time.calendar.month_weekday_last]
+month_weekday_last
represents the last weekday
of a
+month
, of an as yet unspecified year
. To do this the
+month_weekday_last
stores a month
and a
+weekday_last
.
+
+class month_weekday_last +{ + chrono::month m_; // exposition only + chrono::weekday_last wdl_; // exposition only +public: + constexpr month_weekday_last(const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday_last weekday_last() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; +constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; + +ostream& operator<<(ostream& os, const month_weekday_last& mwdl); ++ +
+month_weekday_last
is a trivially copyable class type.
+month_weekday_last
is a standard-layout class type.
+month_weekday_last
is a literal class type.
+
+constexpr month_weekday_last::month_weekday_last(const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; ++ +
++ ++Effects: Constructs an object of type
+month_weekday_last
by constructing +m_
withm
, andwdl_
withwdl
. +
+constexpr month month_weekday_last::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr weekday_last month_weekday_last::weekday_last() const noexcept; ++ +
++ ++Returns:
+wdl_
. +
+constexpr bool month_weekday_last::ok() const noexcept; ++ +
++ ++Returns:
+m_.ok() && wdl_.ok()
. +
+constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; ++ +
++ ++Returns:
+x.month() == y.month() && x.weekday_last() == y.weekday_last()
. +
+constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+ostream& operator<<(ostream& os, const month_weekday_last& mwdl); ++ +
++ ++Effects: Inserts +
+os << mwdl.month() << '/' << mwdl.weekday_last()
. ++Returns:
+os
. +
year_month
[time.calendar.year_month]
+year_month
represents a specific month
of a specific
+year
, but with an unspecified day
. year_month
is a
+field-based time point with a resolution of months
. One can observe the
+different components. One can assign a new value. year_month
is equality
+comparable and less-than comparable. One can stream out a year_month
.
+
+class year_month +{ + chrono::year y_; // exposition only + chrono::month m_; // exposition only + +public: + constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + + constexpr year_month& operator+=(const months& dm) noexcept; + constexpr year_month& operator-=(const months& dm) noexcept; + constexpr year_month& operator+=(const years& dy) noexcept; + constexpr year_month& operator-=(const years& dy) noexcept; + + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const year_month& x, const year_month& y) noexcept; +constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator< (const year_month& x, const year_month& y) noexcept; +constexpr bool operator> (const year_month& x, const year_month& y) noexcept; +constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; + +constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; +constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; +constexpr months operator-(const year_month& x, const year_month& y) noexcept; +constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; +constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; + +ostream& operator<<(ostream& os, const year_month& ym); ++ +
+year_month
is a trivially copyable class type.
+year_month
is a standard-layout class type.
+year_month
is a literal class type.
+
+constexpr year_month::year_month(const chrono::year& y, const chrono::month& m) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month
by constructing +y_
withy
, andm_
withm
. +
+constexpr year year_month::year() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr month year_month::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr year_month& operator+=(const months& dm) noexcept; ++ +
++ ++Effects:
+*this = *this + dm
. ++Returns:
+*this
. +
+constexpr year_month& operator-=(const months& dm) noexcept; ++ +
++ ++Effects:
+*this = *this - dm
. ++Returns:
+*this
. +
+constexpr year_month& operator+=(const years& dy) noexcept; ++ +
++ ++Effects:
+*this = *this + dy
. ++Returns:
+*this
. +
+constexpr year_month& operator-=(const years& dy) noexcept; ++ +
++ ++Effects:
+*this = *this - dy
. ++Returns:
+*this
. +
+constexpr bool year_month::ok() const noexcept; ++ +
++ ++Returns:
+y_.ok() && m_.ok()
. +
+constexpr bool operator==(const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns:
+x.year() == y.year() && x.month() == y.month()
+
+constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
+
+constexpr bool operator< (const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns: If
+x.year() < y.year()
returnstrue
. Else +ifx.year() > y.year()
returnsfalse
. Else returns +x.month() < y.month()
. +
+constexpr bool operator> (const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; ++ +
++ ++Returns: A
+year_month
valuez
such that +z - ym == dm
. ++Complexity: O(1) with respect to the value of
+dm
. +
+constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; ++ +
++ ++Returns:
+ym + dm
. +
+constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; ++ +
++ ++Returns:
+ym + -dm
. +
+constexpr months operator-(const year_month& x, const year_month& y) noexcept; ++ +
++ ++Returns: The number of
+months
one must add toy
to get +x
. +
+constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; ++ +
++ ++Returns:
+(ym.year() + dy) / ym.month()
. +
+constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; ++ +
++ ++Returns:
+ym + dy
. +
+constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; ++ +
++ ++Returns:
+ym + -dy
. +
+ostream& operator<<(ostream& os, const year_month& ym); ++ +
++ ++Effects: Inserts +
+os << ym.year() << '/' << ym.month()
. ++Returns:
+os
. +
year_month_day
[time.calendar.year_month_day]
+year_month_day
represents a specific year
, month
,
+and day
. year_month_day
is a field-based time point with a
+resolution of days
. One can observe each field. year_month_day
+supports years
and months
oriented arithmetic, but not
+days
oriented arithmetic. For the latter, there is a conversion to
+sys_days
which efficiently supports days
oriented arithmetic.
+There is also a conversion from sys_days
.
+year_month_day
is equality and less-than comparable.
+
+class year_month_day +{ + chrono::year y_; // exposition only + chrono::month m_; // exposition only + chrono::day d_; // exposition only + +public: + constexpr year_month_day(const chrono::year& y, const chrono::month& m, const chrono::day& d) noexcept; + constexpr year_month_day(const year_month_day_last& ymdl) noexcept; + constexpr year_month_day(const sys_days& dp) noexcept; + constexpr explicit year_month_day(const local_days& dp) noexcept; + + constexpr year_month_day& operator+=(const months& m) noexcept; + constexpr year_month_day& operator-=(const months& m) noexcept; + constexpr year_month_day& operator+=(const years& y) noexcept; + constexpr year_month_day& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::day day() const noexcept; + + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; + +constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; +constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; +constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; + +ostream& operator<<(ostream& os, const year_month_day& ymd); ++ +
+year_month_day
is a trivially copyable class type.
+year_month_day
is a standard-layout class type.
+year_month_day
is a literal class type.
+
+constexpr year_month_day::year_month_day(const chrono::year& y, const chrono::month& m, const chrono::day& d) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_day
by constructing +y_
withy
,m_
withm
, and, +d_
withd
. +
+constexpr year_month_day::year_month_day(const year_month_day_last& ymdl) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_day
by constructing +y_
withymdl.year()
,m_
with +ymdl.month()
, and,d_
withymdl.day()
. ++Note: This conversion from
+year_month_day_last
to +year_month_day
is more efficient than converting a +year_month_day_last
to asys_days
, and then converting that +sys_days
to ayear_month_day
. +
+constexpr year_month_day::year_month_day(const sys_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_day
which corresponds +to the date represented bydp
. ++Remarks: For any value of
+year_month_day
,ymd
, for which +ymd.ok()
istrue
, this equality will also betrue
: +ymd == year_month_day{sys_days{ymd}}
. +
+constexpr explicit year_month_day::year_month_day(const local_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_day
which corresponds +to the date represented bydp
. ++Remarks: Equivalent to constructing with
+sys_days{dp.time_since_epoch()}
. +
+constexpr year_month_day& year_month_day::operator+=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this + m;
. ++Returns:
+*this
. +
+constexpr year_month_day& year_month_day::operator-=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this - m;
. ++Returns:
+*this
. +
+constexpr year_month_day& year_month_day::operator+=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this + y;
. ++Returns:
+*this
. +
+constexpr year_month_day& year_month_day::operator-=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this - y;
. ++Returns:
+*this
. +
+constexpr year year_month_day::year() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr month year_month_day::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr day year_month_day::day() const noexcept; ++ +
++ ++Returns:
+d_
. +
+constexpr year_month_day::operator sys_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+sys_days
which represents the date represented by +*this
. ++Remarks: A
+sys_days
which is converted to ayear_month_day
, +shall have the same value when converted back to asys_days
. The round +trip conversion sequence shall be loss-less. +
+constexpr explicit year_month_day::operator local_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+local_days
which represents the date represented by +*this
. ++Remarks: Shall return a value equivalent to +
+local_days{static_cast<sys_days>(*this).time_since_epoch()}
. +
+constexpr bool year_month_day::ok() const noexcept; ++ +
++ ++Returns: If
+y_.ok()
istrue
, andm_.ok()
is +true
, andd_
is in the range +[1d, (y_/m_/last).day()]
, then returnstrue
, else returns +false
. +
+constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns:
+x.year() == y.year() && x.month() == y.month() && x.day() == y.day()
. +
+constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns: If
+x.year() < y.year()
, returnstrue
. Else +ifx.year() > y.year()
returnsfalse
. +Else ifx.month() < y.month()
, returnstrue
. +Else ifx.month() > y.month()
, returnsfalse
. +Else returnsx.day() < y.day()
. +
+constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; ++ +
++ ++Requires:
+ymd.month().ok()
istrue
. ++Returns:
+(ymd.year() / ymd.month() + dm) / ymd.day()
. ++Remarks: If
+ymd.day()
is in the range[1d, 28d]
, +the resultantyear_month_day
is guaranteed to returntrue
from +ok()
. +
+constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; ++ +
++ ++Returns:
+ymd + dm
. +
+constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; ++ +
++ ++Returns:
+ymd + (-dm)
. +
+constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; ++ +
++ ++Returns:
+(ymd.year() + dy) / ymd.month() / ymd.day()
. ++Remarks: If
+ymd.month()
isfeb
andymd.day()
+is not in the range[1d, 28d]
, the resultantyear_month_day
is +not guaranteed to returntrue
fromok()
. +
+constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; ++ +
++ ++Returns:
+ymd + dy
. +
+constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; ++ +
++ ++Returns:
+ymd + (-dy)
. +
+ostream& operator<<(ostream& os, const year_month_day& ymd); ++ +
++ ++Effects: Inserts
+yyyy-mm-dd
where the number of indicated digits +are prefixed with'0'
if necessary.. ++Returns:
+os
. +
year_month_day_last
[time.calendar.year_month_day_last]
+year_month_day_last
represents a specific year
,
+month
, and the last day
of the month
.
+year_month_day_last
is a field-based time point with a resolution of
+days
, except that it is restricted to pointing to the last day of a year and
+month. One can observe each field. The day
field is computed on demand.
+year_month_day_last
supports years
and months
+oriented arithmetic, but not days
oriented arithmetic. For the latter, there
+is a conversion to sys_days
which efficiently supports days
+oriented arithmetic. year_month_day_last
is equality and less-than
+comparable.
+
+class year_month_day_last +{ + chrono::year y_; // exposition only + chrono::month_day_last mdl_; // exposition only + +public: + constexpr year_month_day_last(const chrono::year& y, + const chrono::month_day_last& mdl) noexcept; + + constexpr year_month_day_last& operator+=(const months& m) noexcept; + constexpr year_month_day_last& operator-=(const months& m) noexcept; + constexpr year_month_day_last& operator+=(const years& y) noexcept; + constexpr year_month_day_last& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::month_day_last month_day_last() const noexcept; + constexpr chrono::day day() const noexcept; + + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept; +constexpr bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept; + +constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) noexcept; +constexpr year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) noexcept; + +ostream& operator<<(ostream& os, const year_month_day_last& ymdl); ++ +
+year_month_day_last
is a trivially copyable class type.
+year_month_day_last
is a standard-layout class type.
+year_month_day_last
is a literal class type.
+
+constexpr year_month_day_last::year_month_day_last(const chrono::year& y, + const chrono::month_day_last& mdl) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_day_last
by +constructingy_
withy
andmdl_
withmdl
. +
+constexpr year_month_day_last& year_month_day_last::operator+=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this + m;
. ++Returns:
+*this
. +
+constexpr year_month_day_last& year_month_day_last::operator-=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this - m;
. ++Returns:
+*this
. +
+constexpr year_month_day_last& year_month_day_last::operator+=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this + y;
. ++Returns:
+*this
. +
+constexpr year_month_day_last& year_month_day_last::operator-=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this - y;
. ++Returns:
+*this
. +
+constexpr year year_month_day_last::year() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr month year_month_day_last::month() const noexcept; ++ +
++ ++Returns:
+mdl_.month()
. +
+constexpr month_day_last year_month_day_last::month_day_last() const noexcept; ++ +
++ ++Returns:
+mdl_
. +
+constexpr day year_month_day_last::day() const noexcept; ++ +
++ ++Returns: A
+day
representing the last day of theyear
, +month
pair represented by*this
. +
+constexpr year_month_day_last::operator sys_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+sys_days
which represents the date represented by +*this
. +
+constexpr explicit year_month_day_last::operator local_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+local_days
which represents the date represented by +*this
. ++Remarks: Shall return a value equivalent to +
+local_days{static_cast<sys_days>(*this).time_since_epoch()}
. +
+constexpr bool year_month_day_last::ok() const noexcept; ++ +
++ ++Returns:
+y_.ok() && mdl_.ok()
. +
+constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns:
+x.year() == y.year() && x.month_day_last() == y.month_day_last()
. +
+constexpr bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns: If
+x.year() < y.year()
, returnstrue
. Else +ifx.year() > y.year()
returnsfalse
. +Else returnsx.month_day_last() < y.month_day_last()
. +
+constexpr bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns:
+y < x
. +
+constexpr bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(y < x)
. +
+constexpr bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept; ++ +
++ ++Returns:
+!(x < y)
. +
+constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) noexcept; ++ +
++ ++Requires:
+ymdl.ok()
istrue
. ++Returns:
+(ymdl.year() / ymdl.month() + dm) / last
. ++Postconditions: The resultant
+year_month_day_last
will return +true
fromok()
. ++Complexity: O(1) with respect to the value of
+dm
. +
+constexpr year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) noexcept; ++ +
++ ++Returns:
+ymdl + dm
. +
+constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) noexcept; ++ +
++ ++Returns:
+ymdl + (-dm)
. +
+constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) noexcept; ++ +
++ ++Returns:
+{ymdl.year()+dy, ymdl.month_day_last()}
. +
+constexpr year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) noexcept; ++ +
++ ++Returns:
+ymdl + dy
. +
+constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) noexcept; ++ +
++ ++Returns:
+ymdl + (-dy)
. +
+ostream& operator<<(ostream& os, const year_month_day_last& ymdl); ++ +
++ ++Effects: Inserts +
+os << ymdl.year() << '/' << ymdl.month_day_last()
. ++Returns:
+os
. +
year_month_weekday
[time.calendar.year_month_weekday]
+year_month_weekday
represents a specific year
,
+month
, and nth weekday
of the month
.
+year_month_weekday
is a field-based time point with a resolution of
+days
. One can observe each field. year_month_weekday
supports
+years
and months
oriented arithmetic, but not days
+oriented arithmetic. For the latter, there is a conversion to sys_days
which
+efficiently supports days
oriented arithmetic.
+year_month_weekday
is equality comparable.
+
+class year_month_weekday +{ + chrono::year y_; // exposition only + chrono::month m_; // exposition only + chrono::weekday_indexed wdi_; // exposition only + +public: + constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, + const chrono::weekday_indexed& wdi) noexcept; + constexpr year_month_weekday(const sys_days& dp) noexcept; + constexpr explicit year_month_weekday(const local_days& dp) noexcept; + + constexpr year_month_weekday& operator+=(const months& m) noexcept; + constexpr year_month_weekday& operator-=(const months& m) noexcept; + constexpr year_month_weekday& operator+=(const years& y) noexcept; + constexpr year_month_weekday& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday weekday() const noexcept; + constexpr unsigned index() const noexcept; + constexpr chrono::weekday_indexed weekday_indexed() const noexcept; + + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; +constexpr bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept; + +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept; +constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept; + +ostream& operator<<(ostream& os, const year_month_weekday& ymwdi); ++ +
+year_month_weekday
is a trivially copyable class type.
+year_month_weekday
is a standard-layout class type.
+year_month_weekday
is a literal class type.
+
+constexpr year_month_weekday::year_month_weekday(const chrono::year& y, const chrono::month& m, + const chrono::weekday_indexed& wdi) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_weekday
by +constructingy_
withy
,m_
withm
, +andwdi_
withwdi
. +
+constexpr year_month_weekday(const sys_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_weekday
which +corresponds to the date represented bydp
. ++Remarks: For any value of
+year_month_weekday
,ymdl
, for +whichymdl.ok()
istrue
, this equality will also be +true
:ymdl == year_month_weekday{sys_days{ymdl}}
. +
+constexpr explicit year_month_weekday(const local_days& dp) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_weekday
which +corresponds to the date represented bydp
. ++Remarks: Equivalent to constructing with
+sys_days{dp.time_since_epoch()}
. +
+constexpr year_month_weekday& year_month_weekday::operator+=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this + m;
. ++Returns:
+*this
. +
+constexpr year_month_weekday& year_month_weekday::operator-=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this - m;
. ++Returns:
+*this
. +
+constexpr year_month_weekday& year_month_weekday::operator+=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this + y;
. ++Returns:
+*this
. +
+constexpr year_month_weekday& year_month_weekday::operator-=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this - y;
. ++Returns:
+*this
. +
+constexpr year year_month_weekday::year() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr month year_month_weekday::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr weekday year_month_weekday::weekday() const noexcept; ++ +
++ ++Returns:
+wdi_.weekday()
. +
+constexpr unsigned year_month_weekday::index() const noexcept; ++ +
++ ++Returns:
+wdi_.index()
. +
+constexpr weekday_indexed year_month_weekday::weekday_indexed() const noexcept; ++ +
++ ++Returns:
+wdi_
. +
+constexpr year_month_weekday::operator sys_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+sys_days
which represents the date represented by +*this
. +
+constexpr explicit year_month_weekday::operator local_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+local_days
which represents the date represented by +*this
. ++Remarks: Shall return a value equivalent to +
+local_days{static_cast<sys_days>(*this).time_since_epoch()}
. +
+constexpr bool year_month_weekday::ok() const noexcept; ++ +
++ ++Returns: If
+y_.ok()
orm_.ok()
orwdi_.ok()
+returnsfalse
, returnsfalse
. Else if*this
+represents a valid date, returnstrue
, else returnsfalse
. +
+constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; ++ +
++ ++Returns:
+x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()
. +
+constexpr bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept; ++ +
++ ++Requires:
+ymwd.ok()
istrue
. ++Returns:
+(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()
. ++Postconditions: The resultant
+year_month_weekday
will return +true
fromok()
. ++Complexity: O(1) with respect to the value of
+dm
. +
+constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept; ++ +
++ ++Returns:
+ymwd + dm
. +
+constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept; ++ +
++ ++Returns:
+ymwd + (-dm)
. +
+constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept; ++ +
++ ++Returns:
+{ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}
. +
+constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept; ++ +
++ ++Returns:
+ymwd + dm
. +
+constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept; ++ +
++ ++Returns:
+ymwd + (-dm)
. +
+ostream& operator<<(ostream& os, const year_month_weekday& ymwd); ++ +
++ ++Effects: Inserts +
+os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed()
. ++Returns:
+os
. +
year_month_weekday_last
[time.calendar.year_month_weekday_last]
+year_month_weekday_last
represents a specific year
,
+month
, and last weekday
of the month
.
+year_month_weekday_last
is a field-based time point with a resolution of
+days
, except that it is restricted to pointing to the last weekday of a year
+and month. One can observe each field. year_month_weekday_last
supports
+years
and months
oriented arithmetic, but not days
+oriented arithmetic. For the latter, there is a conversion to sys_days
which
+efficiently supports days
oriented arithmetic.
+year_month_weekday_last
is equality comparable.
+
+class year_month_weekday_last +{ + chrono::year y_; // exposition only + chrono::month m_; // exposition only + chrono::weekday_last wdl_; // exposition only + +public: + constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; + + constexpr year_month_weekday_last& operator+=(const months& m) noexcept; + constexpr year_month_weekday_last& operator-=(const months& m) noexcept; + constexpr year_month_weekday_last& operator+=(const years& y) noexcept; + constexpr year_month_weekday_last& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday weekday() const noexcept; + constexpr chrono::weekday_last weekday_last() const noexcept; + + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; + constexpr bool ok() const noexcept; +}; + +constexpr +bool +operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; + +constexpr +bool +operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; + +constexpr +year_month_weekday_last +operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; + +constexpr +year_month_weekday_last +operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; + +constexpr +year_month_weekday_last +operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + +constexpr +year_month_weekday_last +operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; + +constexpr +year_month_weekday_last +operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; + +constexpr +year_month_weekday_last +operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + +ostream& operator<<(ostream& os, const year_month_weekday_last& ymwdl); ++ +
+year_month_weekday_last
is a trivially copyable class type.
+year_month_weekday_last
is a standard-layout class type.
+year_month_weekday_last
is a literal class type.
+
+constexpr year_month_weekday_last::year_month_weekday_last(const chrono::year& y, const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; ++ +
++ ++Effects: Constructs an object of type
+year_month_weekday_last
by +constructingy_
withy
,m_
withm
, +andwdl_
withwdl
. +
+constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this + m;
. ++Returns:
+*this
. +
+constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& m) noexcept; ++ +
++ ++Effects:
+*this = *this - m;
. ++Returns:
+*this
. +
+constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this + y;
. ++Returns:
+*this
. +
+constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& y) noexcept; ++ +
++ ++Effects:
+*this = *this - y;
. ++Returns:
+*this
. +
+constexpr year year_month_weekday_last::year() const noexcept; ++ +
++ ++Returns:
+y_
. +
+constexpr month year_month_weekday_last::month() const noexcept; ++ +
++ ++Returns:
+m_
. +
+constexpr weekday year_month_weekday_last::weekday() const noexcept; ++ +
++ ++Returns:
+wdl_.weekday()
. +
+constexpr weekday_last year_month_weekday_last::weekday_last() const noexcept; ++ +
++ ++Returns:
+wdl_
. +
+constexpr year_month_weekday_last::operator sys_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+sys_days
which represents the date represented by +*this
. +
+constexpr explicit year_month_weekday_last::operator local_days() const noexcept; ++ +
++ ++Requires:
+ok() == true
. ++Returns: A
+local_days
which represents the date represented by +*this
. ++Remarks: Shall return a value equivalent to +
+local_days{static_cast<sys_days>(*this).time_since_epoch()}
. +
+constexpr bool year_month_weekday_last::ok() const noexcept; ++ +
++ ++Returns: If
+y_.ok() && m_.ok() && wdl_.ok()
. +
+constexpr bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; ++ +
++ ++Returns:
+x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last()
. +
+constexpr bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept; ++ +
++ ++Returns:
+!(x == y)
. +
+constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; ++ +
++ ++Requires:
+ymwdl.ok()
istrue
. ++Returns:
+(ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()
. ++Postconditions: The resultant
+year_month_weekday_last
will return +true
fromok()
. ++Complexity: O(1) with respect to the value of
+dm
. +
+constexpr year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; ++ +
++ ++Returns:
+ymwdl + dm
. +
+constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; ++ +
++ ++Returns:
+ymwdl + (-dm)
. +
+constexpr year_month_weekday_last operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; ++ +
++ ++Returns:
+{ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}
. +
+constexpr year_month_weekday_last operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; ++ +
++ ++Returns:
+ymwdl + dy
. +
+constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; ++ +
++ ++Returns:
+ymwdl + (-dy)
. +
+ostream& operator<<(ostream& os, const year_month_weekday_last& ymwdl); ++ +
++ ++Effects: Inserts +
+os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last()
. ++Returns:
+os
. +
+A set of overloaded operator/()
provide a conventional syntax for the
+creation of civil calendar dates. The year, month and day ordering are accepted in
+any of the following 3 orders:
+
y/m/d
m/d/y
d/m/y
+Anywhere a "day" is required one can also specify one of: +
+ +last
weekday[i]
weekday[last]
+Partial-date-types such as year_month
and month_day
can be created
+by simply not applying the second division operator for any of the three orders. For
+example:
+
+ ++year_month ym = 2015y/apr; +month_day md1 = apr/4; +month_day md2 = 4d/apr; +
+Everything not intended as above is caught as a compile-time error, with the notable
+exception of an expression that consists of nothing but int
, which of course
+has type int
.
+
+ ++auto a = 2015/4/4; // a == int(125) +auto b = 2015y/4/4; // b == year_month_day{year(2015), month(4), day(4)} +auto c = 2015y/4d/apr; // error: invalid operands to binary expression ('chrono::year' and 'chrono::day') +auto d = 2015/apr/4; // error: invalid operands to binary expression ('int' and 'const chrono::month') +
+The last example may be clear to a human reader. But the compiler doesn't know if
+2015
refers to a year
or a day
. Instead of
+guessing, the compiler flags it as an error.
+
year_month
:
+constexpr year_month operator/(const year& y, const month& m) noexcept; ++ +
+Returns: {y, m}
.
+
+
++constexpr year_month operator/(const year& y, int m) noexcept; ++ +
+Returns: y / month(m)
.
+
+
+month_day
:
+constexpr month_day operator/(const month& m, const day& d) noexcept; ++ +
+Returns: {m, d}
.
+
+
++constexpr month_day operator/(const month& m, int d) noexcept; ++ +
+Returns: m / day(d)
.
+
+
++constexpr month_day operator/(int m, const day& d) noexcept; ++ +
+Returns: month(m) / d
.
+
+
++constexpr month_day operator/(const day& d, const month& m) noexcept; ++ +
+Returns: m / d
.
+
+
++constexpr month_day operator/(const day& d, int m) noexcept; ++ +
+Returns: month(m) / d
.
+
+
+month_day_last
:
+constexpr month_day_last operator/(const month& m, last_spec) noexcept; ++ +
+Returns: month_day_last{m}
.
+
+
++constexpr month_day_last operator/(int m, last_spec) noexcept; ++ +
+Returns: month(m) / last
.
+
+
++constexpr month_day_last operator/(last_spec, const month& m) noexcept; ++ +
+Returns: m / last
.
+
+
++constexpr month_day_last operator/(last_spec, int m) noexcept; ++ +
+Returns: month(m) / last
.
+
+
+month_weekday
:
+constexpr month_weekday operator/(const month& m, const weekday_indexed& wdi) noexcept; ++ +
+Returns: {m, wdi}
.
+
+
++constexpr month_weekday operator/(int m, const weekday_indexed& wdi) noexcept; ++ +
+Returns: month(m) / wdi
.
+
+
++constexpr month_weekday operator/(const weekday_indexed& wdi, const month& m) noexcept; ++ +
+Returns: m / wdi
.
+
+
++constexpr month_weekday operator/(const weekday_indexed& wdi, int m) noexcept; ++ +
+Returns: month(m) / wdi
.
+
+
+month_weekday_last
:
+constexpr month_weekday_last operator/(const month& m, const weekday_last& wdl) noexcept; ++ +
+Returns: {m, wdl}
.
+
+
++constexpr month_weekday_last operator/(int m, const weekday_last& wdl) noexcept; ++ +
+Returns: month(m) / wdl
.
+
+
++constexpr month_weekday_last operator/(const weekday_last& wdl, const month& m) noexcept; ++ +
+Returns: m / wdl
.
+
+
++constexpr month_weekday_last operator/(const weekday_last& wdl, int m) noexcept; ++ +
+Returns: month(m) / wdl
.
+
+
+year_month_day
:
+constexpr year_month_day operator/(const year_month& ym, const day& d) noexcept; ++ +
+Returns: {ym.year(), ym.month(), d}
.
+
+
++constexpr year_month_day operator/(const year_month& ym, int d) noexcept; ++ +
+Returns: ym / day(d)
.
+
+
++constexpr year_month_day operator/(const year& y, const month_day& md) noexcept; ++ +
+Returns: y / md.month() / md.day()
.
+
+
++constexpr year_month_day operator/(int y, const month_day& md) noexcept; ++ +
+Returns: year(y) / md
.
+
+
++constexpr year_month_day operator/(const month_day& md, const year& y) noexcept; ++ +
+Returns: y / md
.
+
+
++constexpr year_month_day operator/(const month_day& md, int y) noexcept; ++ +
+Returns: year(y) / md
.
+
+
+year_month_day_last
:
+constexpr year_month_day_last operator/(const year_month& ym, last_spec) noexcept; ++ +
+Returns: {ym.year(), month_day_last{ym.month()}}
.
+
+
++constexpr year_month_day_last operator/(const year& y, const month_day_last& mdl) noexcept; ++ +
+Returns: {y, mdl}
.
+
+
++constexpr year_month_day_last operator/(int y, const month_day_last& mdl) noexcept; ++ +
+Returns: year(y) / mdl
.
+
+
++constexpr year_month_day_last operator/(const month_day_last& mdl, const year& y) noexcept; ++ +
+Returns: y / mdl
.
+
+
++constexpr year_month_day_last operator/(const month_day_last& mdl, int y) noexcept; ++ +
+Returns: year(y) / mdl
.
+
+
+year_month_weekday
:
+constexpr year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; ++ +
+Returns: {ym.year(), ym.month(), wdi}
.
+
+
++constexpr year_month_weekday operator/(const year& y, const month_weekday& mwd) noexcept; ++ +
+Returns: {y, mwd.month(), mwd.weekday_indexed()}
.
+
+
++constexpr year_month_weekday operator/(int y, const month_weekday& mwd) noexcept; ++ +
+Returns: year(y) / mwd
.
+
+
++constexpr year_month_weekday operator/(const month_weekday& mwd, const year& y) noexcept; ++ +
+Returns: y / mwd
.
+
+
++constexpr year_month_weekday operator/(const month_weekday& mwd, int y) noexcept; ++ +
+Returns: year(y) / mwd
.
+
+
+year_month_weekday_last
:
+constexpr year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) noexcept; ++ +
+Returns: {ym.year(), ym.month(), wdl}
.
+
+
++constexpr year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) noexcept; ++ +
+Returns: {y, mwdl.month(), mwdl.weekday_last()}
.
+
+
++constexpr year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) noexcept; ++ +
+Returns: year(y) / mwdl
.
+
+
++constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept; ++ +
+Returns: y / mwdl
.
+
+
++constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept; ++ +
+Returns: year(y) / mwdl
.
+
+
++ ++Add new section [time.time_of_day] after 20.15.8 The civil calendar [time.calendar]: +
time_of_day
[time.time_of_day]
+The time_of_day
class breaks a duration
which
+represents the time elapsed since midnight, into a "broken" down time such as
+hours:minutes:seconds. The Duration
template parameter dictates the
+precision to which the time is broken down. This can vary from a course precision of
+hours to a very fine precision of nanoseconds. time_of_day
is primarily
+a formatting tool.
+
+template <class Duration> class time_of_day; ++
+There are 4 specializations of time_of_day
to handle four precisions:
+
+time_of_day<hours> ++
++This specialization handles hours since midnight. +
+time_of_day<minutes> ++
++This specialization handles hours:minutes since midnight. +
+time_of_day<seconds> ++
++This specialization handles hours:minutes:seconds since midnight. +
+time_of_day<duration<Rep, Period>> ++
++This specialization is restricted to
Period
s that are shorter than 1 +second. Typical uses are with milliseconds, microseconds and nanoseconds. This +specialization handles hours:minute:seconds.fractional_seconds since midnight. +
+Each specialization of time_of_day
is a trivially copyable class type.
+Each specialization of time_of_day
is a standard-layout class type.
+Each specialization of time_of_day
is a literal class type.
+
+time_of_day<hours> +{ +public: + using precision = hours; + + constexpr explicit time_of_day(hours since_midnight) noexcept; + constexpr time_of_day(hours h, unsigned md) noexcept; + + constexpr hours hours() const noexcept; + constexpr unsigned mode() const noexcept; + + constexpr explicit operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + void make24() noexcept; + void make12() noexcept; +}; ++ +
+constexpr explicit time_of_day<hours>::time_of_day(hours since_midnight) noexcept; ++ +
++ ++Effects: Constructs an object of type
+time_of_day
in 24-hour format +corresponding tosince_midnight
hours after 00:00:00. ++Postconditions:
+hours()
returns the integral number of hours +since_midnight
is after 00:00:00.mode()
returns0
. +
+constexpr time_of_day<hours>::time_of_day(hours h, unsigned md) noexcept; ++ +
++ ++Preconditions:
+md == am
ormd == pm
. ++Effects: Constructs an object of type
+time_of_day
in 12-hour format +corresponding toh
hours after 00:00:00. ++Postconditions:
+hours()
returnsh
, andmode()
+returnsmd
. +
+constexpr hours time_of_day<hours>::hours() const noexcept; ++ +
++ ++Returns: The stored hour of
+*this
. +
+constexpr unsigned time_of_day<hours>::mode() const noexcept; ++ +
++ ++Returns: 0 if
+*this
is in 24-hour format. Otherwise returns +am
orpm
corresponding to whether this represents a before-noon +time or afternoon time. +
+constexpr explicit time_of_day<hours>::operator precision() const noexcept; ++ +
++ ++Returns: The number of hours since midnight. +
+
+constexpr precision to_duration() const noexcept; ++ +
++ ++Returns:
+precision{*this}
. +
+void time_of_day<hours>::make24() noexcept; ++ +
++ ++Effects: If
+*this
is a 12-hour time, converts to a 24-hour time. +Otherwise, no effects. +
+void time_of_day<hours>::make12() noexcept; ++ +
++ ++Effects: If
+*this
is a 24-hour time, converts to a 12-hour time. +Otherwise, no effects. +
+ostream& operator<<(ostream& os, const time_of_day<hours>& t); ++ +
++ ++Effects: If
+t
is a 24-hour time, outputs toos
+according to thestrftime
format: "%H00". "%H" will emit a leading 0 for +hours less than 10. +Elset
is a 12-hour time, outputs toos
+according to thestrftime
format: "%I%p" according to the C locale, except +that no leading zero is output for hours less than 10. ++Returns:
+os
. ++Example: +
+++0100 // 1 in the morning in 24-hour format +1800 // 6 in the evening in 24-hour format +1am // 1 in the morning in 12-hour format +6pm // 6 in the evening in 12-hour format +
+time_of_day<minutes> +{ +public: + using precision = minutes; + + constexpr explicit time_of_day(minutes since_midnight) noexcept; + constexpr time_of_day(hours h, minutes m, + unsigned md) noexcept; + + constexpr hours hours() const noexcept; + constexpr minutes minutes() const noexcept; + constexpr unsigned mode() const noexcept; + + constexpr explicit operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + void make24() noexcept; + void make12() noexcept; +}; ++ +
+constexpr explicit time_of_day<minutes>::time_of_day(minutes since_midnight) noexcept; ++ +
++ ++Effects: Constructs an object of type
+time_of_day
in 24-hour format +corresponding tosince_midnight
minutes after 00:00:00. ++Postconditions:
+hours()
returns the integral number of hours +since_midnight
is after 00:00:00.minutes()
returns the +integral number of minutessince_midnight
is after (00:00:00 + +hours()
).mode()
returns0
. +
+constexpr time_of_day<minutes>::time_of_day(hours h, minutes m, + unsigned md) noexcept; ++ +
++ ++Preconditions:
+md == am
ormd == pm
. ++Effects: Constructs an object of type
+time_of_day
in 12-hour format +corresponding toh
hours andm
minutes after 00:00:00. ++Postconditions:
+hours()
returnsh
,minutes()
+returnsm
, andmode()
returnsmd
. +
+constexpr hours time_of_day<minutes>::hours() const noexcept; ++ +
++ ++Returns: The stored hour of
+*this
. +
+constexpr minutes time_of_day<minutes>::minutes() const noexcept; ++ +
++ ++Returns: The stored minute of
+*this
. +
+constexpr unsigned time_of_day<minutes>::mode() const noexcept; ++ +
++ ++Returns: 0 if
+*this
is in 24-hour format. Otherwise returns +am
orpm
corresponding to whether this represents a before-noon +time or afternoon time. +
+constexpr explicit time_of_day<minutes>::operator precision() const noexcept; ++ +
++ ++Returns: The number of minutes since midnight. +
+
+constexpr precision to_duration() const noexcept; ++ +
++ ++Returns:
+precision{*this}
. +
+void time_of_day<minutes>::make24() noexcept; ++ +
++ ++Effects: If
+*this
is a 12-hour time, converts to a 24-hour time. +Otherwise, no effects. +
+void time_of_day<minutes>::make12() noexcept; ++ +
++ ++Effects: If
+*this
is a 24-hour time, converts to a 12-hour time. +Otherwise, no effects. +
+ostream& operator<<(ostream& os, const time_of_day<minutes>& t); ++ +
++ ++Effects: If
+t
is a 24-hour time, outputs toos
+according to thestrftime
format: "%H:%M". "%H" will emit a leading 0 for +hours less than 10. +Elset
is a 12-hour time, outputs toos
+according to thestrftime
format: "%I:%M%p" according to the C locale, except +that no leading zero is output for hours less than 10. ++Returns:
+os
. ++Example: +
+++01:08 // 1:08 in the morning in 24-hour format +18:15 // 6:15 in the evening in 24-hour format +1:08am // 1:08 in the morning in 12-hour format +6:15pm // 6:15 in the evening in 12-hour format +
+time_of_day<seconds> +{ +public: + using precision = seconds; + + constexpr explicit time_of_day(seconds since_midnight) noexcept; + constexpr time_of_day(hours h, minutes m, + seconds s, unsigned md) noexcept; + + constexpr hours hours() const noexcept; + constexpr minutes minutes() const noexcept; + constexpr seconds seconds() const noexcept; + constexpr unsigned mode() const noexcept; + + constexpr explicit operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + void make24() noexcept; + void make12() noexcept; +}; ++ +
+constexpr explicit time_of_day<seconds>::time_of_day(seconds since_midnight) noexcept; ++ +
++ ++Effects: Constructs an object of type
+time_of_day
in 24-hour format +corresponding tosince_midnight
seconds after 00:00:00. ++Postconditions:
+hours()
returns the integral number of hours +since_midnight
is after 00:00:00.minutes()
returns the +integral number of minutessince_midnight
is after (00:00:00 + +hours()
).seconds()
returns the integral number of seconds +since_midnight
is after (00:00:00 +hours()
+ +minutes()
).mode()
returns0
. +
+constexpr time_of_day<seconds>::time_of_day(hours h, minutes m, + seconds s, unsigned md) noexcept; ++ +
++ ++Preconditions:
+md == am
ormd == pm
. ++Effects: Constructs an object of type
+time_of_day
in 12-hour format +corresponding toh
hours,m
minutes, ands
seconds +after 00:00:00. ++Postconditions:
+hours()
returnsh
.minutes()
+returnsm
.seconds()
returnss
. +mode()
returnsmd
. +
+constexpr hours time_of_day<seconds>::hours() const noexcept; ++ +
++ ++Returns: The stored hour of
+*this
. +
+constexpr minutes time_of_day<seconds>::minutes() const noexcept; ++ +
++ ++Returns: The stored minute of
+*this
. +
+constexpr seconds time_of_day<seconds>::seconds() const noexcept; ++ +
++ ++Returns: The stored second of
+*this
. +
+constexpr unsigned time_of_day<seconds>::mode() const noexcept; ++ +
++ ++Returns: 0 if
+*this
is in 24-hour format. Otherwise returns +am
orpm
corresponding to whether this represents a before-noon +time or afternoon time. +
+constexpr explicit time_of_day<seconds>::operator precision() const noexcept; ++ +
++ ++Returns: The number of seconds since midnight. +
+
+constexpr precision to_duration() const noexcept; ++ +
++ ++Returns:
+precision{*this}
. +
+void time_of_day<seconds>::make24() noexcept; ++ +
++ ++Effects: If
+*this
is a 12-hour time, converts to a 24-hour time. +Otherwise, no effects. +
+void time_of_day<seconds>::make12() noexcept; ++ +
++ ++Effects: If
+*this
is a 24-hour time, converts to a 12-hour time. +Otherwise, no effects. +
+ostream& operator<<(ostream& os, const time_of_day<seconds>& t); ++ +
++ ++Effects: If
+t
is a 24-hour time, outputs toos
+according to thestrftime
format: "%H:%M%S". "%H" will emit a leading 0 for +hours less than 10. +Elset
is a 12-hour time, outputs toos
+according to thestrftime
format: "%I:%M%S%p" according to the C locale, except +that no leading zero is output for hours less than 10. ++Returns:
+os
. ++Example: +
+++01:08:03 // 1:08:03 in the morning in 24-hour format +18:15:45 // 6:15:45 in the evening in 24-hour format +1:08:03am // 1:08:03 in the morning in 12-hour format +6:15:45pm // 6:15:45 in the evening in 12-hour format +
+time_of_day<duration<Rep, Period>> +{ +public: + using precision = duration<Rep, Period>; + + constexpr explicit time_of_day(precision since_midnight) noexcept; + constexpr time_of_day(hours h, minutes m, + seconds s, precision sub_s, unsigned md) noexcept; + + constexpr hours hours() const noexcept; + constexpr minutes minutes() const noexcept; + constexpr seconds seconds() const noexcept; + constexpr precision subseconds() const noexcept; + constexpr unsigned mode() const noexcept; + + constexpr explicit operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + void make24() noexcept; + void make12() noexcept; +}; ++ +
+This specialization shall not exist unless duration<Rep, Period>{1} < 1s
.
+
+constexpr explicit time_of_day<duration<Rep, Period>>::time_of_day(precision since_midnight) noexcept; ++ +
++ ++Effects: Constructs an object of type
+time_of_day
in 24-hour format +corresponding tosince_midnight precision
fractional seconds after 00:00:00. ++Postconditions:
+hours()
returns the integral number of hours +since_midnight
is after 00:00:00.minutes()
returns the +integral number of minutessince_midnight
is after (00:00:00 + +hours()
).seconds()
returns the integral number of seconds +since_midnight
is after (00:00:00 +hours()
+ +minutes()
).subseconds()
returns the integral number of +fractional precision secondssince_midnight
is after (00:00:00 + +hours()
+minutes()
+seconds
).mode()
+returns0
. +
+constexpr time_of_day<duration<Rep, Period>>::time_of_day(hours h, minutes m, + seconds s, precision sub_s, + unsigned md) noexcept; ++ +
++ ++Preconditions:
+md == am
ormd == pm
. ++Effects: Constructs an object of type
+time_of_day
in 12-hour format +corresponding toh
hours,m
minutes, ands + sub_s
+seconds after 00:00:00. ++Postconditions:
+hours()
returnsh
.minutes()
+returnsm
.seconds()
returnss
. +subseconds()
returnssub_s
.mode()
returns +md
. +
+constexpr hours time_of_day<duration<Rep, Period>>::hours() const noexcept; ++ +
++ ++Returns: The stored hour of
+*this
. +
+constexpr minutes time_of_day<duration<Rep, Period>>::minutes() const noexcept; ++ +
++ ++Returns: The stored minute of
+*this
. +
+constexpr seconds time_of_day<duration<Rep, Period>>::seconds() const noexcept; ++ +
++ ++Returns: The stored second of
+*this
. +
+constexpr +duration<Rep, Period> +time_of_day<duration<Rep, Period>>::subseconds() const noexcept; ++ +
++ ++Returns: The stored subsecond of
+*this
. +
+constexpr unsigned time_of_day<duration<Rep, Period>>::mode() const noexcept; ++ +
++ ++Returns: 0 if
+*this
is in 24-hour format. Otherwise returns +am
orpm
corresponding to whether this represents a before-noon +time or afternoon time. +
+constexpr explicit time_of_day<duration<Rep, Period>>::operator precision() const noexcept; ++ +
++ ++Returns: The number of subseconds since midnight. +
+
+constexpr precision to_duration() const noexcept; ++ +
++ ++Returns:
+precision{*this}
. +
+void time_of_day<duration<Rep, Period>>::make24() noexcept; ++ +
++ ++Effects: If
+*this
is a 12-hour time, converts to a 24-hour time. +Otherwise, no effects. +
+void time_of_day<duration<Rep, Period>>::make12() noexcept; ++ +
++ ++Effects: If
+*this
is a 24-hour time, converts to a 12-hour time. +Otherwise, no effects. +
+ostream& operator<<(ostream& os, const time_of_day<duration<Rep, Period>>& t); ++ +
++ ++Effects: If
+t
is a 24-hour time, outputs toos
+according to thestrftime
format: "%H:%M%S.%s". "%H" will emit a leading 0 for +hours less than 10. "%s" is not astrftime
code and represents the fractional +seconds. +Elset
is a 12-hour time, outputs toos
+according to thestrftime
format: "%I:%M%S.%s%p" according to the C locale, except +that no leading zero is output for hours less than 10. ++Returns:
+os
. ++Example: +
+++01:08:03.007 // 1:08:03.007 in the morning in 24-hour format (assuming millisecond precision) +18:15:45.123 // 6:15:45.123 in the evening in 24-hour format (assuming millisecond precision) +1:08:03.007am // 1:08:03.007 in the morning in 12-hour format (assuming millisecond precision) +6:15:45.123pm // 6:15:45.123 in the evening in 12-hour format (assuming millisecond precision) +
make_time
[time.time_of_day.make_time]
+These helper functions ease the construction of time_of_day
objects by
+deducing the precision for the time_of_day
return type from the argument to
+the helper function.
+
+template <class Rep, class Period> +constexpr +time_of_day<duration<Rep, Period>> +make_time(duration<Rep, Period> d) noexcept; ++ +
++ ++Returns:
+time_of_day<duration<Rep, Period>>(d)
. +
+constexpr +time_of_day<hours> +make_time(hours h, unsigned md) noexcept; ++ +
++ ++Returns:
+time_of_day<hours>(h, md)
. +
+constexpr +time_of_day<minutes> +make_time(hours h, minutes m, unsigned md) noexcept; ++ +
++ ++Returns:
+time_of_day<minutes>(h, m, md)
. +
+constexpr +time_of_day<seconds> +make_time(hours h, minutes m, seconds s, + unsigned md) noexcept; ++ +
++ ++Returns:
+time_of_day<seconds>(h, m, s, md)
. +
+template <class Rep, class Period, + class = enable_if_t<ratio_less<Period, ratio<1>>::value>> +constexpr +time_of_day<duration<Rep, Period>> +make_time(hours h, minutes m, seconds s, + duration<Rep, Period> sub_s, unsigned md) noexcept ++ +
++ ++Returns:
+time_of_day<duration<Rep, Period>>(h, m, s, sub_s, md)
. +
+ ++Add new section [time.timezone] after 20.15.9 Class
time_of_day
[time.time_of_day]: +
+This clause creates an API which exposes the IANA Time Zone database, and
+interfaces with sys_time
and local_time
. By using
+only this interface, time zone support is provided not only to the civil
+calendar types, but also to other user-written calendars that interface with
+sys_time
and local_time
.
+
+The following data structure is the time zone database, and the following +functions access it. +
+ ++struct TZ_DB +{ + string version; + vector<time_zone> zones; + vector<link> links; + vector<leap> leaps; +}; ++ +
+The reload_tzdb()
which re-initializes it.
+Each vector
is sorted to enable fast lookup. You can iterate over
+and inspect this database.
+
+const TZ_DB& get_tzdb(); ++
++ ++Effects: If this is the first access to the database, will initialize +the database. +
++Returns: A
+const
reference to the database. ++Thread Safety: It is safe to call this function from multiple threads at +one time. +
++Throws:
+runtime_error
if for any reason a reference can not +be returned to a validTZ_DB
. +
+const time_zone* locate_zone(const string& tz_name); ++
++ ++Effects: Calls
+get_tzdb()
which will initialize the timezone +database if this is the first reference to the database. ++Returns: If a
+time_zone
is found for which +name() == tz_name
, returns a pointer to thattime_zone
. +Otherwise if alink
is found wheretz_name == link.name()
, +then a pointer is returned to thetime_zone
for which +zone.name() == link.target()
[Note: Alink
is an +alternative name for atime_zone
. — end note] ++Throws: Any exception propagated from
+get_tzdb()
. If a +const time_zone*
can not be found as described in the +Returns clause, throws aruntime_error
. [Note: +On non-exceptional return, the return value is always a pointer to a +validtime_zone
. — end note] +
+const time_zone* current_zone(); ++
+Effects: Calls+ +locate_zone()
which will initialize the timezone +database if this is the first reference to the database. + ++Returns: A
+const time_zone*
referring to the time zone which your +computer has set as its local time zone. ++Throws: Any exception propagated from
locate_zone()
. +[Note: On non-exceptional return, the return value is always a +pointer to a validtime_zone
. — end note] +
+ ++This subsection is optional/seperable and needs further discussion in the LEWG. No +other sections depend upon this subsection. +
+const TZ_DB& reload_tzdb(); ++
++ ++Effects: This function first checks the latest version at the +IANA website. If the +IANA website is unavailable, or if the +latest version is already installed, there are no effects. Otherwise, a new version +is available. It is downloaded and installed, and then the program re-initializes +the
+TZ_DB
singleton from the new disk files. ++Returns: A
+const
reference to the database. ++Thread Safety: This function is not thread safe. You must +provide your own synchronization among threads accessing the time zone database +to safely use this function. If this function re-initializes the database, all outstanding +
+const time_zone*
are invalidated (including those held within +zoned_time
objects). And afterwards, all outstanding +sys_info
may hold obsolete data. ++Throws:
+runtime_error
if for any reason a reference can not +be returned to a validTZ_DB
. +
+string remote_version(); ++
++ ++Returns: The latest database version number from the +IANA website. If the +IANA website can not be reached, or +if it can be reached but the latest version number is unexpectedly not +available, the empty string is returned. +
++Note: If non-empty, this can be compared with
+get_tzdb().version
to +discover if you have the latest database installed. +
+bool remote_download(const string& version); ++
++ ++Effects: If
+version == remote_version()
this function will download +the compressed tar file holding the latest time zone database from the +IANA website. The tar file will be placed +at an unspecified location. ++Returns:
+true
if the database was successfully downloaded, else +false
. ++Thread safety: If called by multiple threads, there will be a race on the +creation of the tar file. +
+
+bool remote_install(const string& version); ++
++ ++Effects: If
+version
refers to the file successfully +downloaded byremote_download()
this function will remove the +existing time zone database, then extract a new database +from the tar file, and will then delete the tar file. ++This function does not cause your program to re-initialize itself from +this new database. In order to do that, you must call +
+reload_tzdb()
(orget_tzdb()
if the database has yet +to be initialized). ++Returns:
+true
if the database was successfully replaced by +the tar file , elsefalse
. ++Thread safety: If called by multiple threads, there will be a race on the +creation of the new database. +
+
+nonexistent_local_time
is thrown when one attempts to convert a
+non-existent local_time
to a sys_time
without specifying
+choose::earliest
or choose::latest
.
+
+class nonexistent_local_time + : public runtime_error +{ +public: + // Construction is undocumented +}; ++
+[Example: +
++++#include "tz.h" +#include <iostream> + +int +main() +{ + using namespace std::chrono; + try + { + auto zt = make_zoned("America/New_York", local_days{sun[2]/mar/2016} + 2h + 30min); + } + catch (const nonexistent_local_time& e) + { + std::cout << e.what() << '\n'; + } +} +++Which outputs: +
++2016-03-13 02:30:00 is in a gap between +2016-03-13 02:00:00 EST and +2016-03-13 03:00:00 EDT which are both equivalent to +2016-03-13 07:00:00 UTC ++
+— end example:] +
+ +
+ambiguous_local_time
is thrown when one attempts to convert an ambiguous
+local_time
to a sys_time
without specifying
+choose::earliest
or choose::latest
.
+
+class ambiguous_local_time + : public runtime_error +{ +public: + // Construction is undocumented +}; ++
+[Example: +
++++#include "tz.h" +#include <iostream> + +int +main() +{ + using namespace std::chrono; + try + { + auto zt = make_zoned("America/New_York", local_days{sun[1]/nov/2016} + 1h + 30min); + } + catch (const ambiguous_local_time& e) + { + std::cout << e.what() << '\n'; + } +} +++Which outputs: +
++2016-11-06 01:30:00 is ambiguous. It could be +2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or +2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC ++
+— end example:] +
+ +
+A sys_info
structure can be obtained from the combination of a time_zone
and
+either a sys_time
, or local_time
. It can also be obtained
+from a zoned_time
which is effectively a pair
of
+a time_zone
and sys_time
.
+
+This structure represents a lower-level API. Typical conversions from
+sys_time
to local_time
will use this structure
+implicitly, not explicitly.
+
+struct sys_info +{ + sys_seconds begin; + sys_seconds end; + seconds offset; + minutes save; + string abbrev; +}; ++
+The begin
and end
fields indicate that for the
+associated time_zone
and time_point
, the
+offset
and abbrev
are in effect in the range
+[begin, end)
. This information can be used to efficiently iterate the
+transitions of a time_zone
.
+
+The offset
field indicates the UTC offset in effect for the associated
+time_zone
and time_point
. The relationship between
+local_time
and sys_time
is:
+
+offset = local_time - sys_time ++
+The save
field is "extra" information not normally needed for
+conversion between local_time
and sys_time
. If
+save != 0min
, this sys_info
is said to be on "daylight
+saving" time, and offset - save
suggests what this
+time_zone
might use if it were off daylight saving. However
+this information should not be taken as authoritative. The only sure way to get
+such information is to query the time_zone
with a
+time_point
that returns an sys_info
where
+save == 0min
. There is no guarantee what time_point
might return such
+an sys_info
except that it is guaranteed not to be in the range
+[begin, end)
(if save != 0min
for this sys_info
).
+
+The abbrev
field indicates the current abbreviation used for the
+associated time_zone
and time_point
. Abbreviations
+are not unique among the time_zone
s, and so one can not reliably
+map abbreviations back to a time_zone
and UTC offset.
+
+A sys_info
can be streamed out in an unspecified format:
+
+ostream& operator<<(ostream& os, const sys_info& r); ++ + +
+A local_info
structure represents a lower-level API. Typical conversions from
+local_time
to sys_time
will use this structure
+implicitly, not explicitly.
+
+struct local_info +{ + enum {unique, nonexistent, ambiguous} result; + sys_info first; + sys_info second; +}; ++
+When a local_time
to sys_time
conversion is unique,
+result == unique
, first
will be filled out with the
+correct sys_info
and second
will be zero-initialized.
+If the conversion stems from a nonexistent local_time
then
+result == nonexistent
, first
will be filled out with
+the sys_info
that ends just prior to the local_time
+and second
will be filled out with the sys_info
that
+begins just after the local_time
. If the conversion stems from an
+ambiguous local_time
then result == ambiguous
,
+first
will be filled out with the sys_info
that ends
+just after the local_time
and second
will be filled
+out with the sys_info
that starts just before the
+local_time
.
+
+A local_info
can be streamed out in an unspecified format:
+
+ostream& operator<<(ostream& os, const local_info& r); ++ +
time_zone
[time.timezone.time_zone]
+A time_zone
represents all time zone transitions for a specific geographic
+area. time_zone
construction is undocumented, and done during
+the database initialization. You can gain const
access to a
+time_zone
via functions such as locate_zone
.
+
+class time_zone +{ +public: + time_zone(const time_zone&) = delete; + time_zone& operator=(const time_zone&) = delete; + + const string& name() const; + + template <class Duration> sys_info get_info(sys_time<Duration> st) const; + template <class Duration> local_info get_info(local_time<Duration> tp) const; + + template <class Duration> + sys_time<typename common_type<Duration, seconds>::type> + to_sys(local_time<Duration> tp) const; + + template <class Duration> + sys_time<typename common_type<Duration, seconds>::type> + to_sys(local_time<Duration> tp, choose z) const; + + template <class Duration> + local_time<typename common_type<Duration, seconds>::type> + to_local(sys_time<Duration> tp) const; +}; + +bool operator==(const time_zone& x, const time_zone& y); +bool operator!=(const time_zone& x, const time_zone& y); +bool operator< (const time_zone& x, const time_zone& y); +bool operator> (const time_zone& x, const time_zone& y); +bool operator<=(const time_zone& x, const time_zone& y); +bool operator>=(const time_zone& x, const time_zone& y); + +ostream& operator<<(ostream& os, const time_zone& z) ++
+const string& time_zone::name() const; ++
++ ++Returns: The name of the
+time_zone
. ++Example: "America/New_York". +
++Note: Here is an unofficial list of
+time_zone
names: +https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. +
+template <class Duration> sys_info time_zone::get_info(sys_time<Duration> st) const; ++
++ ++Returns: A
+sys_info
i
for whichst
is in the +range[i.begin, i.end)
. +
+template <class Duration> local_info time_zone::get_info(local_time<Duration> tp) const; ++
++ ++Returns: A
+local_info
fortp
. +
+template <class Duration> +sys_time<typename common_type<Duration, seconds>::type> +time_zone::to_sys(local_time<Duration> tp) const; ++
++ ++Returns: A
+sys_time
that is at least as fine asseconds
, +and will be finer if the argumenttp
has finer precision. This +sys_time
is the UTC equivalent oftp
according to the rules +of thistime_zone
. ++Throws: If the conversion from
+tp
to asys_time
+is ambiguous, throwsambiguous_local_time
. If the conversion from +tp
to asys_time
is nonexistent, throws +nonexistent_local_time
. +
+template <class Duration> +sys_time<typename common_type<Duration, seconds>::type> +time_zone::to_sys(local_time<Duration> tp, choose z) const; ++
++ ++Returns: A
+sys_time
that is at least as fine as +seconds
, and will be finer if the argumenttp
has +finer precision. Thissys_time
is the UTC equivalent of +tp
according to the rules of thistime_zone
. If the +conversion fromtp
to asys_time
is ambiguous, returns +the earliersys_time
ifz == choose::earliest
, and +returns the latersys_time
ifz == choose::latest
. If +thetp
represents a non-existent time between two UTC +time_point
s, then the two UTCtime_point
s will be the +same, and that UTCtime_point
will be returned. +
+template <class Duration> +local_time<typename common_type<Duration, seconds>::type> +time_zone::to_local(sys_time<Duration> tp) const; ++
++ ++Returns: The
+local_time
associated withtp
and this +time_zone
. +
+bool operator==(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+x.name() == y.name()
. +
+bool operator!=(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+!(x == y)
. +
+bool operator<(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+x.name() < y.name()
. +
+bool operator>(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+y < x
. +
+bool operator<=(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+!(y < x)
. +
+bool operator>=(const time_zone& x, const time_zone& y); ++
++ ++Returns:
+!(x < y)
. +
+ostream& operator<<(ostream& os, const time_zone& z) ++
++ ++Produces an unspecified output representing the
+time_zone
. +
zoned_time
[time.timezone.zoned_time]
+zoned_time
represents a logical paring of time_zone
and a
+time_point
with precision Duration
. If seconds
+is not implicitly convertible to Duration
, the instantiation is ill-formed.
+[Note: There exist time_zone
s with UTC offsets that require a
+precision of seconds
. — end note:]
+
+template <class Duration> +class zoned_time +{ + const time_zone* zone_; // exposition only + sys_time<Duration> tp_; // exposition only + +public: + zoned_time(const zoned_time&) = default; + zoned_time& operator=(const zoned_time&) = default; + + zoned_time(sys_time<Duration> st); + explicit zoned_time(const time_zone* z); + explicit zoned_time(const string& name); + + template <class Duration2> + zoned_time(const zoned_time<Duration2>& zt) noexcept; + + zoned_time(const time_zone* z, local_time<Duration> tp); + zoned_time(const string& name, local_time<Duration> tp); + zoned_time(const time_zone* z, local_time<Duration> tp, choose c); + zoned_time(const string& name, local_time<Duration> tp, choose c); + + zoned_time(const time_zone* z, const zoned_time<Duration>& zt); + zoned_time(const string& name, const zoned_time<Duration>& zt); + zoned_time(const time_zone* z, const zoned_time<Duration>& zt, choose); + zoned_time(const string& name, const zoned_time<Duration>& zt, choose); + + zoned_time(const time_zone* z, const sys_time<Duration>& st); + zoned_time(const string& name, const sys_time<Duration>& st); + + zoned_time& operator=(sys_time<Duration> st); + zoned_time& operator=(local_time<Duration> ut); + + operator sys_time<Duration>() const; + explicit operator local_time<Duration>() const; + + const time_zone* get_time_zone() const; + local_time<Duration> get_local_time() const; + sys_time<Duration> get_sys_time() const; + sys_info get_info() const; +}; + +template <class Duration1, class Duration2> +bool +operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); + +template <class Duration1, class Duration2> +bool +operator!=(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); ++ +
+An invariant of zoned_time<Duration>
is that it always refers
+to a valid time_zone
, and represents a point in time that exists
+and is not ambiguous.
+
+zoned_time<Duration>::zoned_time(const zoned_time&) = default; +zoned_time<Duration>& zoned_time<Duration>::operator=(const zoned_time&) = default; ++
++ ++The copy members transfer the associated
+time_zone
from the source +to the destination. After copying, source and destination compare equal. If +Duration
hasnoexcept
copy members, then +zoned_time<Duration>
hasnoexcept
copy +members. +
+zoned_time<Duration>::zoned_time(sys_time<Duration> st); ++
++ ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()->name() == "UTC"
, and +zt.get_sys_time() == st
. +
+explicit zoned_time<Duration>::zoned_time(const time_zone* z); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, and +zt.get_sys_time() == sys_seconds{}
. +
+explicit zoned_time<Duration>::zoned_time(const string& name); ++
++ ++Effects: Equivalent to construction with
+locate_zone(name)
. ++Throws: Any exception propagating out of
+locate_zone(name)
. +
+template <class Duration2> + zoned_time<Duration>::zoned_time(const zoned_time<Duration2>& y) noexcept; ++
++ ++Remarks: Does not participate in overload resolution unless +
+sys_time<Duration2>
is implicitly convertible to +sys_time<Duration>
. ++Effects: Constructs a
+zoned_time
x
such that +x == y
. +
+zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> tp); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, andzt.get_local_time() == tp
. ++Throws: Any exception that
+z->to_sys(tp)
would throw. +
+zoned_time<Duration>::zoned_time(const string& name, local_time<Duration> tp); ++
++ ++Effects: Equivalent to construction with
+{locate_zone(name), tp}
. +
+zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> tp, choose c); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, and +zt.get_sys_time() == z->to_sys(tp, c)
. +
+zoned_time<Duration>::zoned_time(const string& name, local_time<Duration> tp, choose c); ++
++ ++Effects: Equivalent to construction with
+{locate_zone(name), tp, c}
. +
+zoned_time<Duration>::zoned_time(const time_zone* z, const zoned_time<Duration>& y); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, and +zt.get_sys_time() == y.get_sys_time()
. +
+zoned_time<Duration>::zoned_time(const string& name, const zoned_time<Duration>& y); ++
++ ++Effects: Equivalent to construction with
+{locate_zone(name), y}
. +
+zoned_time<Duration>::zoned_time(const time_zone* z, const zoned_time<Duration>& y, choose); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, and +zt.get_sys_time() == y.get_sys_time()
. ++Note: The
+choose
parameter is allowed here, but has no impact. +
+zoned_time<Duration>::zoned_time(const string& name, const zoned_time<Duration>& y, choose); ++
++ ++Effects: Equivalent to construction with
+{locate_zone(name), y}
. ++Note: The
+choose
parameter is allowed here, but has no impact. +
+zoned_time<Duration>::zoned_time(const time_zone* z, const sys_time<Duration>& st); ++
++ ++Requires:
+z
refers to a validtime_zone
. ++Effects: Constructs a
+zoned_time
zt
such that +zt.get_time_zone()-> == z
, andzt.get_sys_time() == st
. +
+zoned_time<Duration>::zoned_time(const string& name, const sys_time<Duration>& st); ++
++ ++Effects: Equivalent to construction with
+{locate_zone(name), st}
. +
+zoned_time<Duration>& zoned_time<Duration>::operator=(sys_time<Duration> st); ++
++ ++Effects: After assignment
+get_sys_time() == st
. This assignment has +no effect on the return value ofget_time_zone()
. ++Returns:
+*this
. +
+zoned_time<Duration>& zoned_time<Duration>::operator=(local_time<Duration> lt); ++
++ ++Effects: After assignment
+get_local_time() == lt
. This assignment has +no effect on the return value ofget_time_zone()
. ++Returns:
+*this
. +
+zoned_time<Duration>::operator sys_time<Duration>() const; ++
++ ++Returns:
+get_sys_time()
. +
+explicit zoned_time<Duration>::operator local_time<Duration>() const; ++
++ ++Returns:
+get_local_time()
. +
+const time_zone* zoned_time<Duration>::get_time_zone() const; ++
++ ++Returns:
+zone_
. +
+local_time<Duration> zoned_time<Duration>::get_local_time() const; ++
++ ++Returns:
+zone_->to_local(tp_)
. +
+sys_time<Duration> zoned_time<Duration>::get_sys_time() const; ++
++ ++Returns:
+tp_
. +
+sys_info zoned_time<Duration>::get_info() const; ++
++ ++Returns:
+zone_->get_info(tp_)
. +
+template <class Duration1, class Duration2> +bool +operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); ++
++ ++Returns:
+x.zone_ == y.zone_ && x.tp_ == y.tp_
. +
+template <class Duration1, class Duration2> +bool +operator!=(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y); ++
++ ++Returns:
+!(x == y)
. +
+template++ostream& +operator<<(ostream& os, const zoned_time & t) +
++ ++Effects: Streams
+t
toos
using the format "%F %T %Z" +and the value returned fromt.get_local_time()
. ++Returns:
+os
. +
make_zoned
[time.timezone.make_zoned]
+There exist several overloaded functions named make_zoned
+which serve as factory functions for zoned_time<Duration>
and
+will deduce the correct Duration
from the argument list. In every
+case the correct return type is
+zoned_time<common_type_t<Duration, seconds>>
.
+
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(sys_time<Duration> tp) ++
++ + ++Returns:
+{tp}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, local_time<Duration> tp) ++
++ ++Returns:
+{zone, tp}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, local_time<Duration> tp) ++
++ ++Returns:
+{name, tp}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, local_time<Duration> tp, choose c) ++
++ ++Returns:
+{zone, tp, c}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, local_time<Duration> tp, choose c) ++
++ ++Returns:
+{name, tp, c}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt) ++
++ ++Returns:
+{zone, zt}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const zoned_time<Duration>& zt) ++
++ ++Returns:
+{name, zt}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt, choose c) ++
++ ++Returns:
+{zone, zt, c}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const zoned_time<Duration>& zt, choose c) ++
++ ++Returns:
+{name, zt, c}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const time_zone* zone, const sys_time<Duration>& st) ++
++ ++Returns:
+{zone, st}
. +
+template <class Duration> +zoned_time<common_type_t<Duration, seconds>> +make_zoned(const string& name, const sys_time<Duration>& st) ++
++ ++Returns:
+{name, st}
. +
+template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + local_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, local_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + const zoned_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, const zoned_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(const locale& loc, basic_string<class CharT, class Traits> format, + sys_time<Duration> tp); + +template <class CharT, class Traits, class Duration> +basic_string<class CharT, class Traits> +format(basic_string<class CharT, class Traits> format, sys_time<Duration> tp); + +// const CharT* formats + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, local_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, local_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, const zoned_time<Duration>& tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, const zoned_time<Duration>& tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const locale& loc, const CharT* format, sys_time<Duration> tp); + +template <class CharT, class Duration> +basic_string<class CharT> +format(const CharT* format, sys_time<Duration> tp); ++
++ ++Effects: These functions create a formatted time stamp using the +arguments, returning the result in a
+string
. +++ ++If a
+locale
is passed in, then thatlocale
is used for +any formatting that requires alocale
. If nolocale
+is passed in, then if alocale
is required for formatting, a +default constructedlocale
will be used (which makes a copy of the +globallocale
). ++The
+format
string follows the rules as specified for +time_put
with the following exceptions: ++
+ +- + +
+If
%S
or%T
appears in theformat
string +and the argumenttp
has precision finer than seconds, then seconds +are formatted as a decimal floating point number with a fixed format and a +precision matching that of the precision oftp
. The character for +the decimal point is localized according to thelocale
. +- + +
+If
+%z
appears in the format, the behavior depends on the type of +tp
: ++
+- +
+local_time
: An exception of typeruntime_error
is thrown. +- +
+zoned_time
: The offset associated withtp.get_time_zone()
is +used. +- +
+sys_time
:"+0000"
is used. +- + +
+If
+%Z
appears in the format, the behavior depends on the type of +tp
: ++
+- +
+local_time
: An exception of typeruntime_error
is thrown. +- +
+zoned_time
: The abbreviation associated with +tp.get_time_zone()
is used. +- +
+sys_time
:"UTC"
is used. ++For the overloads taking a
+zoned_time
it is the value returned by +tz.get_local_time()
that is formatted. ++Returns: The formatted string. +
+ +
+One can parse in a sys_time<Duration>
or a
+local_time<Duration>
. Optionally, one can also pass in a reference
+to a string
in order to capture the time zone abbreviation, or one
+can pass in a reference to a minutes
to capture a time zone
+UTC offset (formatted as +0000
), or one can pass in both in either order.
+
+template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, sys_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, + const basic_string<CharT, Traits>& format, local_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +// const CharT* formats + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + basic_string<CharT, Traits>& abbrev, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, sys_time<Duration>& tp, + minutes& offset, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, basic_string<CharT, Traits>& abbrev); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, basic_string<CharT, Traits>& abbrev, + minutes& offset); + +template <class CharT, class Traits, class Duration> +void +parse(basic_istream<CharT, Traits>& is, const CharT* format, + local_time<Duration>& tp, minutes& offset, + basic_string<CharT, Traits>& abbrev); ++
++ ++Effects: These functions attempt to parse a
+time_point
out of +is
according toformat
. If the parse is unsuccessful, +callsis.setstate(ios::failbit)
which may throw an exception. +tp
,abbrev
, andoffset
are altered only in +the event of a successful parse. ++++The
+format
string follows the rules as specified fortime_get
+with the following exceptions: ++
+- + +
+If
%S
or%T
appears in theformat
string +and the argumenttp
has precision finer than seconds, then the +seconds are parsed as adouble
, and if that parse is successful +contributes to the time stamp as if +round<Duration>(duration<double>{s})
where +s
is a local variable holding the parseddouble
. +- + +
+If
%z
appears in theformat
string and an offset is +successfully parsed, the overloads takingsys_time
interprets the +parsed time as a local time and subtracts the offset prior to assigning the +value totp
, resulting in a value oftp
representing a +UTC timestamp. The overloads takinglocal_time
require a valid +parse of the offset, but then ignore the offset in assigning a value to the +local_time<Duration>& tp
. Ifoffset
is +passed in, on successful parse it will hold the value represented by +%z
if present, or will be assigned0min
if +%z
is not present. +- +
+If
%Z
appears in theformat
string then an +abbreviation is required in that position for a successful parse. The +abbreviation will be parsed as astring
(delimited by white +space). The parsed abbreviation does not have to be a valid time zone +abbreviation, and has no impact on the value parsed intotp
. Using +the overloads that take astring&
one can discover what +that parsed abbreviation is. On successful parse,abbrev
will be +assigned the value represented by%Z
if present, or assigned the +empty string if%Z
is not present. ++Note: There is no unique mapping from a time zone abbreviation to a +
+time_zone
. But given a time zone abbreviation and asys_time
+orlocal_time
, one could make a list of potentialtime_zone
s. +Given a UTC offset, one might even narrow that list down further. +
+class utc_clock +{ +public: + using duration = system_clock::duration; + using rep = duration::rep; + using period = duration::period; + using time_point = chrono::time_point<utc_clock>; + static constexpr bool is_steady = true; + + static time_point now() noexcept; + + template <class Duration> + static + utc_time<common_type_t<Duration, seconds>> + sys_to_utc(sys_time<Duration> t); + + template <class Duration> + static + sys_time<common_type_t<Duration, seconds>> + utc_to_sys(utc_time<Duration> u); +}; ++ +
+In contrast to sys_time
which does not take leap seconds into
+account, utc_clock
and its associated time_point
,
+utc_time
, counts time, including leap seconds, since
+1970-01-01 00:00:00 UTC. It also provides functions for converting between
+utc_time
and sys_time
. These functions consult
+get_tzdb().leaps
to decide how many seconds to add/subtract
+in performing those conversions.
+
+static utc_clock::time_point utc_clock::now() noexcept; ++
++ ++Returns:
+sys_to_utc(system_clock::now())
. +
+template <class Duration> +static +utc_time<common_type_t<Duration, seconds>> +utc_clock::sys_to_utc(sys_time<Duration> t); ++
++ ++Returns: A
+utc_time
u
, such that +u.time_since_epoch() - t.time_since_epoch()
is equal to the number +of leap seconds that were inserted betweent
and 1970-01-01. If +t
is ambiguous on this issue (i.e. corresponds to the date of leap +second insertion), then the conversion counts that leap second as inserted. +
+template <class Duration> +static +sys_time<common_type_t<Duration, seconds>> +utc_clock::utc_to_sys(utc_time<Duration> u); ++
++ ++Returns: A
+sys_time
t
, such that +utc_clock::sys_to_utc(t) == u
. +
+template <class Duration> +utc_time<common_type_t<Duration, seconds>> +to_utc_time(sys_time<Duration> t) ++
++ ++Returns:
+utc_clock::sys_to_utc(t)
. +
+template <class Duration> +sys_time<common_type_t<Duration, seconds>> +to_sys_time(utc_time<Duration> u) ++
++ ++Returns:
+utc_clock::utc_to_sys(u)
. +
+[Example: +
+ ++ ++#include "tz.h" +#include <iostream> + +int +main() +{ + using namespace std::chrono; + auto t0 = sys_days{1972y/jul/1} - 1ms; + auto u0 = to_utc_time(t0); + auto t1 = to_sys_time(u0); + std::cout << t0 << ":\n"; + std::cout << (u0.time_since_epoch() - t0.time_since_epoch()).count() << "ms\n"; + std::cout << (t1 - t0).count() << "ms\n\n"; + + t0 += 1ms; + u0 = to_utc_time(t0); + t1 = to_sys_time(u0); + std::cout << t0 << ":\n"; + std::cout << (u0.time_since_epoch() - t0.time_since_epoch()).count() << "ms\n"; + std::cout << (t1 - t0).count() << "ms\n"; +} +++Output: +
++1972-06-30 23:59:59.999: +0ms +0ms + +1972-07-01 00:00:00.000: +1000ms +0ms ++
+— end example] +
+ +leap
[time.timezone.leap]+class leap +{ +public: + leap(const leap&) = default; + leap& operator=(const leap&) = default; + + // Undocumented constructors + + sys_seconds date() const; +}; + +bool operator==(const leap& x, const leap& y); +bool operator!=(const leap& x, const leap& y); +bool operator< (const leap& x, const leap& y); +bool operator> (const leap& x, const leap& y); +bool operator<=(const leap& x, const leap& y); +bool operator>=(const leap& x, const leap& y); + +template <class Duration> bool operator==(const const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator==(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator!=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator!=(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator< (const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator< (const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator> (const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator> (const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator<=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator<=(const sys_time<Duration>& x, const leap& y); +template <class Duration> bool operator>=(const leap& x, const sys_time<Duration>& y); +template <class Duration> bool operator>=(const sys_time<Duration>& x, const leap& y); ++ +
+leap
is a copyable class that is constructed and stored in the time zone
+database when initialized. You can explicitly convert it to a sys_seconds
+with the member function date()
and that will be the date of the leap second
+insertion. leap
is equality and less-than comparable, both with itself, and
+with sys_time<Duration>
.
+
link
[time.timezone.link]+class link +{ +public: + link(const link&) = default; + link& operator=(const link&) = default; + + // Undocumented constructors + + const string& name() const; + const string& target() const; +}; + +bool operator==(const link& x, const link& y); +bool operator!=(const link& x, const link& y); +bool operator< (const link& x, const link& y); +bool operator> (const link& x, const link& y); +bool operator<=(const link& x, const link& y); +bool operator>=(const link& x, const link& y); ++
+A link
is an alternative name for a time_zone
. The alternative
+name is name()
. The name of the time_zone
for which this is
+an alternative name is target()
. link
s will be constructed
+for you when the time zone database is initialized.
+
+A database parser is nothing without its database. I would like to thank the founding +contributor of the IANA Time Zone Database +Arthur David Olson. I would also like to thank the entire group of people who continually +maintain it, and especially the IESG-designated TZ Coordinator, Paul Eggert. Without the +work of these people, this software would have no data to parse. +
++I would also like to thank Jiangang Zhuang and Bjarne Stroustrup for invaluable +feedback for the timezone portion of this library, which ended up also +influencing the date.h library. Thanks also to Jonathan Wakely for agreeing to +present this paper in Oulu for me. +
++And I would also especially like to thank contributors to this library: gmcode, +Ivan Pizhenko, tomy2105 and Ville Voutilainen. +
+ ++N. Dershowitz and E. Reingold, Calendrical Calculations 3rd ed., Cambridge +University Press 2008. +
+