date/d0355r4.html
Howard Hinnant 7957b976bc Removed remote_download and remote_install.
* The implementation is now responsible for supplying
  run-time time zone database updates.
2017-10-15 14:26:27 -04:00

10693 lines
323 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Extending &lt;chrono&gt; to Calendars and Time Zones</title>
<style type="text/css">
p {text-align:justify}
li {text-align:justify}
blockquote.note
{
background-color:#E0E0E0;
padding-left: 15px;
padding-right: 15px;
padding-top: 1px;
padding-bottom: 1px;
}
p.note
{
background-color:#E0E0E0;
padding-left: 15px;
padding-right: 15px;
padding-top: 1px;
padding-bottom: 1px;
}
ins {color:#00A000}
del {color:#A00000}
address {text-align:right;}
h1 {text-align:center;}
span.comment {color:#C80000;}
code {white-space:pre;}
</style>
</head>
<body>
<address>
Document number: D0355R4<br>
<br>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br>
2017-10-15<br>
</address>
<hr>
<h1>Extending <code>&lt;chrono&gt;</code> to Calendars and Time Zones</h1>
<h2>Contents</h2>
<ul>
<li><a href="#Revision">Revision History</a></li>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Description">Description</a></li>
<li><a href="#Issues">Issues</a></li>
<li><a href="#Wording">Proposed Wording</a></li>
<li><a href="#Acknowledgements">Acknowledgements</a></li>
<li><a href="#References">References</a></li>
</ul>
<a name="Revision"></a><h2>Revision History</h2>
<h3>Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r3.html">R3</a></h3>
<ul>
<li>Presume that the time zone database is supplied only by the std::lib implementation,
but can be updated at run time. Removed <code>remote_download</code> and
<code>remote_install</code>. This functionality is now subsumed by the implementation.</li>
<li><code>to_stream</code> sets <code>failbit</code> if it is required to create a name
for an invalid month or weekday.</li>
<li>Add note to promise compatibility with <a href="https://wg21.link/p0645"><code>fmt</code> (P0645)</a></li>
<li>Have <code>format</code> throw an exception if anything happens so that it
could not return an accurate string.</li>
<li>Template <code>zoned_time</code> on <code>TimeZonePtr</code>.</li>
<li>Give <code>weekday_indexed</code> a defaulted default constructor.</li>
<li>Make <code>from_stream</code> and <code>to_stream</code> customization points.</li>
<li>Make the database singleton a singly linked list of <code>tzdb</code> with
an atomic head pointer, instead of a single <code>tzdb</code>.</li>
<li>Rewrite in terms of <code>string_view</code>.</li>
<li>Improve spec for operator-(const year_month&amp; x, const year_month&amp; y).</li>
<li>Refine constraints on conversions from calendar types to sys_days.</li>
<li>Added <code>zoned_time</code> default constructor.</li>
<li>Added <code>zoned_time</code> deduction guides.</li>
<li>Correct minor type-o's.</li>
<li>Correct html bugs.</li>
</ul>
<h3>Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r2.html">R2</a></h3>
<ul>
<li>Add <code>to_stream</code> and <code>from_stream</code> to
<code>utc_time&lt;Duration&gt;</code>, <code>tai_time&lt;Duration&gt;</code>, and
<code>gps_time&lt;Duration&gt;</code>.</li>
<li>Add <code>from_stream</code>, and rewrite <code>format</code> and
<code>parse</code> in terms of <code>to_stream</code> and
<code>from_stream</code>.</li>
<li>Add <code>to_stream</code> and <code>from_stream</code> for <code>year</code>,
<code>month</code>, <code>day</code>, <code>weekday</code>, <code>year_month</code>, and
<code>month_day</code>.</li>
<li><code>to_stream</code> will set <code>failbit</code> instead of <code>throw</code>.</li>
<li>Add <code>file_clock</code> and hook it into <code>filesytem</code>.</li>
<li>Relax <code>zoned_time</code> to be coarser than seconds.</li>
<li>Remove <code>make_time</code> and <code>make_zoned</code> in favor of the
implicit deduction guides.</li>
<li>Create <code>zoned_time(const char* name, ...)</code> overloads to enable
implicit deduction guides.</li>
<li>Give <code>time_of_day</code> default constructor.</li>
<li>Add <code>Alloc</code> to <code>basic_string</code> everywhere possible.</li>
<li>Deprecate <code>system_clock::to_time_t</code> and
<code>system_clock::from_time_t</code>.</li>
<li>Make duration streaming respect padding and alignment requests.</li>
<li>Add <code>is_clock</code> type trait.</li>
<li>Allow the Clock template parameter of <code>time_point</code> to be a Clock or
a <code>local_t</code>.</li>
<li>Make functions in [thread] that take a Clock template parameter ill-formed if
<code>is_clock<Clock>{}</code> is false.</li>
</ul>
<h3>Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0355r1.html">R1</a></h3>
<ul>
<li>Make <code>time_point</code> incremental and decrementable</li>
<li>Add unary operators + and - to <code>year</code></li>
<li>Remove <code>enum {am, pm}</code>, <code>time_of_day</code>
constructors which use it, and <code>make_time</code> factory functions
which use it.</li>
<li>Add <code>to_stream</code>.</li>
<li>Add <code>format</code> and <code>parse</code> for <code>duration</code>.</li>
</ul>
<h3>Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0355r0.html">R0</a></h3>
<ul>
<li>Tighten up <code>utc_clock::utc_to_sys</code> and <code>utc_clock::sys_to_utc</code>.</li>
<li>Eliminate <code>utc_clock::utc_to_sys</code> and <code>utc_clock::sys_to_utc</code>
in favor of free functions such as <code>to_sys_time</code> and <code>to_utc_time</code>.</li>
<li>Give <code>utc_time</code> a streaming operator.</li>
<li>Change <code>format</code> to take <code>time_point</code>s by <code>const&amp;</code>
instead of by value.</li>
<li>Add trivial default constructors to most calendar types.</li>
<li>Create %Ez & %Oz to put ':' in offset for format and parse.</li>
<li>Add %F to parse.</li>
<li>Changed parse functions to parse manipulators.</li>
<li>Excuse local_t from being a clock</li>
<li>Guarantee Unix Time.</li>
<li>Add duration stream insertion.</li>
<li>Introduce tai_clock.</li>
<li>Introduce gps_clock.</li>
<li>Removed <code>noexcept</code> from <code>make_time</code>.</li>
</ul>
<a name="Introduction"></a><h2>Introduction</h2>
<p>
The purpose of a calendar is to give a name to each day.<sup><a href="#refcc">1</a></sup>
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 <code>&lt;chrono&gt;</code>, the civil
calendar, and with time zones, all with a minimal coupling. For example:
</p>
<blockquote><pre>
#include "coptic.h" // not proposed, just an example
#include &lt;chrono&gt;
#include &lt;iostream&gt;
int
main()
{
using namespace std::chrono_literals;
auto date = 2016y/may/29;
cout &lt;&lt; date &lt;&lt; " is " &lt;&lt; coptic::year_month_day{date} &lt;&lt; " in the Coptic calendar\n";
// 2016-05-29 is 1732-09-21 in the Coptic calendar
}
</pre></blockquote>
<p>
The above example creates a date in the Gregorian calendar (proposed) with the
literal <code>2016y/may/29</code>. The meaning of this literal is without
question. It is conventional and 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 <code>&lt;chrono&gt;</code> library (specifically a
<code>system_clock::time_point</code> with a precision of days).
</p>
<p>
The paper proposes:
</p>
<ol>
<li>Minimal extensions to <code>&lt;chrono&gt;</code> to support calendar and
time zone libraries.</li>
<li>A <a
href="https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar">proleptic
Gregorian calendar</a>, hereafter referred to as the <i>civil</i> calendar.</li>
<li>A time zone library based on the
<a href="http://www.iana.org/time-zones">IANA Time Zone Database</a>.</li>
<li><code>strftime</code>-like formatting and parsing facilities with fully operational
support for fractional seconds, time zone abbreviations, and UTC offsets.</li>
<li>Several <code>&lt;chrono&gt;</code> clocks for computing with leap seconds which is
also supported by the <a href="http://www.iana.org/time-zones">IANA Time Zone
Database</a>.</li>
</ol>
<p>
Everything proposed herein has been fully implemented here:
</p>
<blockquote>
<a href="https://github.com/HowardHinnant/date">https://github.com/HowardHinnant/date</a>
</blockquote>
<p>
The implementation includes full documentation, and an active community of users with
positive field experience. The implementation has been ported to Windows, Linux, Android,
macOS and iOS.
</p>
<p>
The API stresses:
</p>
<ul>
<li>Seamless integration with the existing <code>&lt;chrono&gt;</code> library.</li>
<li>Type safety.</li>
<li>Detection of errors at compile time.</li>
<li>Performance.</li>
<li>Ease of use.</li>
<li>Readable code.</li>
<li>No artificial restrictions on precision. Note: current financial software is
currently in the middle of a transition from seconds precision to milliseconds
precision. This library handles that transition as seamlessly as
<code>&lt;chrono&gt;</code> does.</li>
</ul>
<p>
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:
</p>
<ul>
<li>
If <code>vector&lt;T&gt;::push_front(const T&amp;)</code> existed, that would
encourage inefficient code, even though it would be trivial to implement.
</li>
<li>
If <code>list&lt;T&gt;::operator[](size_type index)</code> existed, that would
encourage inefficient code, even though it would be trivial to implement (by
incrementing from <code>begin()</code> or decrementing from <code>end()</code>).
</li>
</ul>
<p>
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
<code>{year, month, day}</code> and a serial type such as
<code>{count-of-days}</code> is one of the more expensive operations when
dealing with calendrical computations. Both data structures are very useful
(just as both <code>vector</code> and <code>list</code> are very useful). So
this library puts <i>you</i> in control of when and how often that conversion
takes place, and makes it easy to avoid such conversions when not necessary.
</p>
<a name="Description"></a><h2>Description</h2>
<p>
One can create a <code>year</code> like this:
</p>
<blockquote><pre>
auto y = year{2016};
</pre></blockquote>
<p>
Just like <code>&lt;chrono&gt;</code>, type safety is taken very seriously. The
type <code>year</code> is distinct from type <code>int</code>, just as <code>3</code>
can never mean "3 seconds", unless it is <i>explicitly</i> typed to do so:
<code>seconds{3}</code>.
</p>
<p>
And just like <code>seconds</code>, there is a year literal suffix which can help make
your code more readable:
</p>
<blockquote><pre>
auto y = 2016y;
</pre></blockquote>
<p>
<code>year</code> is a <i>partial-calendar-type</i>. It can be combined with
other partial-calendar-types to create a <i>full-calendar-type</i> such as
<code>year_month_day</code>. Full-calendar-types can be converted to and from
the family of <code>system_clock::time_point</code>s. Full-calendar-types such
as <code>year_month_day</code> are time points with a precision of a day, but
they are also <i>field</i> types. They are composed of 3 fields under the hood:
<code>year</code>, <code>month</code> and <code>day</code>. Thus when you
construct a <code>year_month_day</code> from a <code>year</code>,
<code>month</code> and <code>day</code>, absolutely no computation takes place.
The only thing that happens is a <code>year</code>, <code>month</code> and
<code>day</code> are stored inside the <code>year_month_day</code>.
</p>
<blockquote><pre>
year_month_day ymd1{2016y, month{5}, day{29}};
</pre></blockquote>
<p>
This is a <i>very</i> simple operation and can even be made
<code>constexpr</code> when all of the inputs are compile-time constants. And
<i>conventional syntax</i> 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:
</p>
<blockquote><pre>
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);
</pre></blockquote>
<p>
<code>year_month_day</code> is a <i>very</i> simple, <i>very</i> understandable
<i>calendrical</i> data structure:
</p>
<blockquote><pre>
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&amp; y, const chrono::month&amp; m, const chrono::day&amp; d) noexcept;
// ...
</pre></blockquote>
<p>
By now you should be yawning and muttering "so what?"
</p>
<p>
Now we introduce a little <code>&lt;chrono&gt;</code> infrastructure that serves
as the communication channel with simplistic calendrical data structures such as
<code>year_month_day</code>.
</p>
<blockquote><pre>
using days = duration&lt;int32_t, ratio_multiply&lt;ratio&lt;24&gt;, hours::period&gt;&gt;;
template &lt;class Duration&gt; using sys_time = time_point&lt;system_clock, Duration&gt;;
using sys_days = sys_time&lt;days&gt;;
</pre></blockquote>
<p>
<code>sys_days</code> <b>is</b> a <code>std::chrono::time_point</code>. This
<code>time_point</code> is based on <code>system_clock</code> and has a very coarse
precision: 24 hours. Just as <code>system_clock::time_point</code> is nothing more
than a count of microseconds (or nanoseconds, or whatever), <code>sys_days</code> is
simply a count of days since the <code>system_clock</code> epoch. And
<code>sys_days</code> is <i>fully</i> interoperable with
<code>system_clock::time_point</code> in all of the ways normal to the
<code>&lt;chrono&gt;</code> library:
</p>
<ul>
<li><code>sys_days</code> implicitly converts to <code>system_clock::time_point</code>
with no truncation error.</li>
<li><code>system_clock::time_point</code> <i>does not</i> implicitly convert to
<code>sys_days</code> because it would involve truncation error.</li>
<li>Explicit conversion can be achieved from <code>system_clock::time_point</code> by
using the existing <code>&lt;chrono&gt;</code> facilities <code>time_point_cast</code>
or <code>floor</code>.</li>
</ul>
<blockquote><pre>
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&lt;days&gt;(tp)}; // Convert time_point to date
static_assert(ymd == 2016y/may/29d);
</pre></blockquote>
<p>
The calendrical type <code>year_month_day</code> provides conversions to and
from <code>sys_days</code>. This conversion is easy to do for std::lib
implementors using algorithms
<a href="http://howardhinnant.github.io/date_algorithms.html">such as these</a>.
If the committee standardizes existing practice and specifies that
<code>system_clock</code> measures
<a href="https://en.wikipedia.org/wiki/Unix_time">Unix Time</a>,
then it will be equally easy for
anyone to write their own calendar system which converts to and from
<code>sys_days</code> (e.g. the coptic example in the introduction).
</p>
<p>
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 <code>system_clock::time_point</code>, that it is nearly trivial
to include such functionality:
</p>
<blockquote><pre>
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&lt;days&gt;(tp)}; // Convert time_point to date
static_assert(ymd == sun[5]/may/2016);
</pre></blockquote>
<p>
The literal <code>sun[5]/may/2016</code> means "the 5th Sunday of May in 2016."
The <i>conventional</i> syntax is remarkably readable. Constructor syntax is
also available to do the same thing. The type constructed is
<code>year_month_weekday</code> which does nothing but store a
<code>year</code>, <code>month</code>, <code>weekday</code>, and the number 5.
This "auxiliary calendar" converts to and from <code>sys_days</code> just like
<code>year_month_day</code> as demonstrated above. As such,
<code>year_month_weekday</code> will interoperate with <code>year_month_day</code>
(by bouncing off of <code>sys_days</code>) just as it will with any other calendar
that interoperates with <code>sys_days</code>:
</p>
<blockquote><pre>
static_assert(2016y/may/29d == year_month_day{sun[5]/may/2016});
</pre></blockquote>
<p>
Since <code>year_month_day</code> is so easy to convert to (or from) a
<code>time_point</code> it makes sense to convert to a <code>time_point</code> when
you need to talk about a date and time-of-day:
</p>
<blockquote><pre>
constexpr auto tp = sys_days{2016y/may/29d} + 7h + 30min; // 2016-05-29 07:30 UTC
</pre></blockquote>
<p>
The time zone is implicitly UTC because <code>system_clock</code> tracks <a
href="https://en.wikipedia.org/wiki/Unix_time">Unix Time</a> which is (a very
close approximation to) UTC. If you need another time zone, no worries, we'll
get there. And remember, <code>tp</code> above is a
<code>system_clock::time_point</code>, except with minutes precision. You can
compare it with <code>system_clock::now()</code> to find out if the date is in
the past or the future. Also note that the syntax above (like
<code>&lt;chrono&gt;</code>) is <i>precision neutral</i>. That's because the
syntax above <b>is</b> <code>&lt;chrono&gt;</code>, except for the part
converting a calendar type into the <code>&lt;chrono&gt;</code> 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 <code>&lt;chrono&gt;</code> system:
</p>
<blockquote><pre>
constexpr auto tp = sys_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 UTC
</pre></blockquote>
<p>
Simple streaming is provided:
</p>
<blockquote><pre>
cout &lt;&lt; tp &lt;&lt; '\n'; // 2016-05-29 07:30:06.153
</pre></blockquote>
<p>
But I need the time in Tokyo!
</p>
<blockquote><pre>
auto tp = sys_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 UTC
zoned_time zt = {"Asia/Tokyo", tp};
cout &lt;&lt; zt &lt;&lt; '\n'; // 2016-05-29 16:30:06.153 JST
</pre></blockquote>
<p>
<code>zoned_time</code> is templated on the duration type of <code>tp</code>, which is
automatically deduced from the initialization expression (milliseconds 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 <code>sys_time</code> (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 <code>zoned_time</code>.
</p>
<p>
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 7:30 UTC:
</p>
<blockquote><pre>
auto tp = local_days{2016y/may/29d} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153
auto zt = zoned_time{"Asia/Tokyo", tp};
cout &lt;&lt; zt &lt;&lt; '\n'; // 2016-05-29 07:30:06.153 JST
</pre></blockquote>
<p>
The <i>only</i> change to the code is the use of <code>local_days</code> in
place of <code>sys_days</code>. <code>local_days</code> is also a
<code>std::chrono::time_point</code> but its "clock type" <code>local_t</code>
has no <code>now()</code> function. This <code>time_point</code> is called
<code>local_time</code>. A <code>local_time</code> can refer to <i>any</i> time
zone. In the above example when we pair "Asia/Tokyo" with the
<code>local_time</code>, the result becomes a <code>zoned_time</code> with the
local time specified by the <code>local_time</code>.
</p>
<p>
To interoperate with time zones, calendrical types must convert to and from
<code>local_days</code> as well as <code>sys_days</code>. 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.
</p>
<p>
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 <code>local_days</code> and <code>sys_days</code>. Here
is an example that sets up a meeting at 9am on the third Tuesday of June, 2016
in New York:
</p>
<blockquote><pre>
auto zt = zoned_time{"America/New_York", local_days{tue[3]/jun/2016} + 9h};
cout &lt;&lt; zt &lt;&lt; '\n'; // 2016-06-21 09:00:00 EDT
</pre></blockquote>
<p>
Need to set up a video conference with your partners in Helsinki?
</p>
<blockquote><pre>
cout &lt;&lt; zoned_time{"Europe/Helsinki", zt} &lt;&lt; '\n';
</pre></blockquote>
<p>
This converts one <code>zoned_time</code> into another <code>zoned_time</code> where
the only difference is changing from "America/New_York" to "Europe/Helsinki". The
conversion preserves the UTC equivalent in both <code>zoned_time</code>s, and
therefore outputs:
</p>
<blockquote><pre>
2016-06-21 16:00:00 EEST
</pre></blockquote>
<p>
And if this is not the formatting you prefer, that is easily fixed too:
</p>
<blockquote><pre>
cout &lt;&lt; format("%F %H:%M %z", zoned_time{"Europe/Helsinki", zt}) &lt;&lt; '\n';
// 2016-06-21 16:00 +0300
</pre></blockquote>
<p>
Or perhaps properly localized:
</p>
<blockquote><pre>
cout &lt;&lt; format(locale{"fi_FI"}, "%c", zoned_time{"Europe/Helsinki", zt}) &lt;&lt; '\n';
// Ti 21 Kes 16:00:00 2016
</pre></blockquote>
<p>
Wait, slow down, this is too much information! Let's start at the beginning.
How do I get the current time?
</p>
<blockquote><pre>
cout &lt;&lt; system_clock::now() &lt;&lt; " UTC\n";
// 2016-05-30 17:57:30.694574 UTC
</pre></blockquote>
<p>
My current local time?
</p>
<blockquote><pre>
cout &lt;&lt; zoned_time{current_zone(), system_clock::now()} &lt;&lt; '\n';
// 2016-05-30 13:57:30.694574 EDT
</pre></blockquote>
<p>
Current time in Budapest?
</p>
<blockquote><pre>
cout &lt;&lt; zoned_time{"Europe/Budapest", system_clock::now()} &lt;&lt; '\n';
// 2016-05-30 19:57:30.694574 CEST
</pre></blockquote>
<p>
For more documentation about the calendar portion of this proposal, including more
details, more examples, and performance analyses, please see:
</p>
<blockquote>
<a href="http://howardhinnant.github.io/date/date.html">http://howardhinnant.github.io/date/date.html</a>
</blockquote>
<p>
For a video introduction to the calendar portion, please see:
</p>
<blockquote>
<a href="https://www.youtube.com/watch?v=tzyGjOm8AKo">https://www.youtube.com/watch?v=tzyGjOm8AKo</a>
</blockquote>
<p>
For a video introduction to the time zone portion, please see:
</p>
<blockquote>
<a href="https://www.youtube.com/watch?v=Vwd3pduVGKY">https://www.youtube.com/watch?v=Vwd3pduVGKY</a>
</blockquote>
<p>
For more documentation about the time zone portion of this proposal, including more
details, and more examples, please see:
</p>
<blockquote>
<a href="http://howardhinnant.github.io/date/tz.html">http://howardhinnant.github.io/date/tz.html</a>
</blockquote>
<p>
For more examples, some of which are written by users of this library, please see:
</p>
<blockquote>
<a href="https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes">https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes</a>
</blockquote>
<p>
For another example calendar which models the
<a href="https://en.wikipedia.org/wiki/ISO_week_date">ISO week-based calendar</a>,
please see:
</p>
<blockquote>
<a href="http://howardhinnant.github.io/date/iso_week.html">http://howardhinnant.github.io/date/iso_week.html</a>
</blockquote>
<a name="Wording"></a><h2>Proposed Wording</h2>
<h3>Table of Contents for Proposed Wording</h3>
<pre>
[time] 23.17
[time.general] 23.17.1
<a href="#time.syn">[time.syn] 23.17.2</a>
[time.clock.req] 23.17.3
[time.traits] 23.17.4
[time.traits.is_fp] 23.17.4.1
[time.traits.duration_values] 23.17.4.2
[time.traits.specializations] 23.17.4.3
<a href="#time.traits.is_clock">[time.traits.is_clock]</a>
[time.duration] 23.17.5
[time.duration.cons] 23.17.5.1
[time.duration.observer] 23.17.5.2
[time.duration.arithmetic] 23.17.5.3
[time.duration.special] 23.17.5.4
[time.duration.nonmember] 23.17.5.5
[time.duration.comparisons] 23.17.5.6
[time.duration.cast] 23.17.5.7
[time.duration.literals] 23.17.5.8
[time.duration.alg] 23.17.5.9
<a href="#time.duration.io">[time.duration.io]</a>
<a href="#time.point">[time.point] 23.17.6</a>
[time.point.cons] 23.17.6.1
[time.point.observer] 23.17.6.2
<a href="#time.point.arithmetic">[time.point.arithmetic] 23.17.6.3</a>
[time.point.special] 23.17.6.4
[time.point.nonmember] 23.17.6.5
[time.point.comparisons] 23.17.6.6
[time.point.cast] 23.17.6.7
<a href="#time.clock">[time.clock] 23.17.7</a>
<a href="#time.clock.system">[time.clock.system] 23.17.7.1</a>
<a href="#time.clock.utc">[time.clock.utc]</a>
<a href="#time.clock.tai">[time.clock.tai]</a>
<a href="#time.clock.gps">[time.clock.gps]</a>
<a href="#time.clock.file">[time.clock.file]</a>
[time.clock.steady] 23.17.7.2
[time.clock.hires] 23.17.7.3
<a href="#time.clock.local_time">[time.clock.local_time]</a>
<a href="#time.format">[time.format]</a>
<a href="#time.parse">[time.parse]</a>
<a href="#time.calendar">[time.calendar]</a>
<a href="#time.calendar.last">[time.calendar.last]</a>
<a href="#time.calendar.day">[time.calendar.day]</a>
<a href="#time.calendar.month">[time.calendar.month]</a>
<a href="#time.calendar.year">[time.calendar.year]</a>
<a href="#time.calendar.weekday">[time.calendar.weekday]</a>
<a href="#time.calendar.weekday_indexed">[time.calendar.weekday_indexed]</a>
<a href="#time.calendar.weekday_last">[time.calendar.weekday_last]</a>
<a href="#time.calendar.month_day">[time.calendar.month_day]</a>
<a href="#time.calendar.month_day_last">[time.calendar.month_day_last]</a>
<a href="#time.calendar.month_weekday">[time.calendar.month_weekday]</a>
<a href="#time.calendar.month_weekday_last">[time.calendar.month_weekday_last]</a>
<a href="#time.calendar.year_month">[time.calendar.year_month]</a>
<a href="#time.calendar.year_month_day">[time.calendar.year_month_day]</a>
<a href="#time.calendar.year_month_day_last">[time.calendar.year_month_day_last]</a>
<a href="#time.calendar.year_month_weekday">[time.calendar.year_month_weekday]</a>
<a href="#time.calendar.year_month_weekday_last">[time.calendar.year_month_weekday_last]</a>
<a href="#time.calendar.operators">[time.calendar.operators]</a>
<a href="#time.time_of_day">[time.time_of_day]</a>
<a href="#time.timezone">[time.timezone]</a>
<a href="#time.timezone.database">[time.timezone.database]</a>
<a href="#time.timezone.database.remote">[time.timezone.database.remote]</a>
<a href="#time.timezone.exception">[time.timezone.exception]</a>
<a href="#time.timezone.info">[time.timezone.info]</a>
<a href="#time.timezone.time_zone">[time.timezone.time_zone]</a>
<a href="#time.timezone.zoned_traits">[time.timezone.zoned_traits]</a>
<a href="#time.timezone.zoned_time">[time.timezone.zoned_time]</a>
<a href="#time.timezone.leap">[time.timezone.leap]</a>
<a href="#time.timezone.link">[time.timezone.link]</a>
[ctime.syn] 23.17.8
<a href="#fs.filesystem.syn">[fs.filesystem.syn] 30.10.6</a>
<a href="#thread.req.paramname">[thread.req.paramname] 33.2.1</a>
</pre>
<p class = note>
Text in grey boxes is not proposed wording.
</p>
<a name="time.syn"></a><p class = note>
Insert into synopsis in 23.17.2 Header <code>&lt;chrono&gt;</code> synopsis [time.syn]:
</p>
<blockquote><pre>
namespace std {
namespace chrono {
// ...
// customization traits
// ...
template &lt;class T&gt; struct is_clock;
template &lt;class T&gt; inline constexpr bool is_clock_v = is_clock&lt;T&gt;::value;
// duration I/O
template &lt;class charT, class traits, class Rep, class Period&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
const duration&lt;Rep, Period&gt;&amp; d);
template &lt;class charT, class traits, class Rep, class Period&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const duration&lt;Rep, Period&gt;&amp; d);
template &lt;class charT, class traits, class Rep, class Period, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
duration&lt;Rep, Period&gt;&amp; d,
basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
// ...
// convenience typedefs
// ...
using days = duration&lt;<i>signed integer type of at least 25 bits</i>, ratio_multiply&lt;ratio&lt;24&gt;, hours::period&gt;&gt;;
using weeks = duration&lt;<i>signed integer type of at least 22 bits</i>, ratio_multiply&lt;ratio&lt;7&gt;, days::period&gt;&gt;;
using years = duration&lt;<i>signed integer type of at least 17 bits</i>, ratio_multiply&lt;ratio&lt;146097, 400&gt;, days::period&gt;&gt;;
using months = duration&lt;<i>signed integer type of at least 20 bits</i>, ratio_divide&lt;years::period, ratio&lt;12&gt;&gt;&gt;;
// ...
// clocks
// ...
class utc_clock;
class tai_clock;
class gps_clock;
class file_clock;
// time_point families
template &lt;class Duration&gt;
using sys_time = time_point&lt;system_clock, Duration&gt;;
using sys_seconds = sys_time&lt;seconds&gt;;
using sys_days = sys_time&lt;days&gt;;
struct local_t {};
template &lt;class Duration&gt;
using local_time = time_point&lt;local_t, Duration&gt;;
using local_seconds = local_time&lt;seconds&gt;;
using local_days = local_time&lt;days&gt;;
template &lt;class Duration&gt;
using utc_time = time_point&lt;utc_clock, Duration&gt;;
using utc_seconds = utc_time&lt;seconds&gt;;
template &lt;class Duration&gt;
using tai_time = time_point&lt;tai_clock, Duration&gt;;
using tai_seconds = tai_time&lt;seconds&gt;;
template &lt;class Duration&gt;
using gps_time = time_point&lt;gps_clock, Duration&gt;;
using gps_seconds = gps_time&lt;seconds&gt;;
template &lt;class Duration&gt;
using file_time = time_point&lt;file_clock, Duration&gt;;
// time_point conversions
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const utc_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const tai_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const gps_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
sys_time&lt;Duration&gt;
to_sys_time(const file_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const sys_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const tai_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const gps_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const file_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const sys_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const utc_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const gps_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const file_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const sys_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const utc_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const tai_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const file_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
file_time&lt;Duration&gt;
to_file_time(const sys_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const utc_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const tai_time&lt;Duration&gt;&amp; t);
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const gps_time&lt;Duration&gt;&amp; t);
// time_point I/O
// operator<<
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const local_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_days&amp; dp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const utc_time&lt;Duration&gt;&amp; t);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const tai_time&lt;Duration&gt;&amp; t);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const gps_time&lt;Duration&gt;&amp; t);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const file_time&lt;Duration&gt;&amp; tp);
// to_stream
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const sys_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const local_time&lt;Duration&gt;&amp; tp,
const string* abbrev = nullptr, const seconds* offset_sec = nullptr);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const utc_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const tai_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const gps_time&lt;Duration&gt;&amp; tp);
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const file_time&lt;Duration&gt;&amp; tp);
// from_stream
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
sys_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
local_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
utc_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
tai_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
gps_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
file_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
// Calendrical types
struct last_spec;
class day;
constexpr bool operator==(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator!=(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&lt; (const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&gt; (const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&lt;=(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&gt;=(const day&amp; x, const day&amp; y) noexcept;
constexpr day operator+(const day&amp; x, const days&amp; y) noexcept;
constexpr day operator+(const days&amp; x, const day&amp; y) noexcept;
constexpr day operator-(const day&amp; x, const days&amp; y) noexcept;
constexpr days operator-(const day&amp; x, const day&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const day&amp; d);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const day&amp; d);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
day&amp; d, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class month;
constexpr bool operator==(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator!=(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&lt; (const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&gt; (const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&lt;=(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&gt;=(const month&amp; x, const month&amp; y) noexcept;
constexpr month operator+(const month&amp; x, const months&amp; y) noexcept;
constexpr month operator+(const months&amp; x, const month&amp; y) noexcept;
constexpr month operator-(const month&amp; x, const months&amp; y) noexcept;
constexpr months operator-(const month&amp; x, const month&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month&amp; m);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month&amp; m);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month&amp; m, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class year;
constexpr bool operator==(const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator!=(const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&lt; (const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&gt; (const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&lt;=(const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&gt;=(const year&amp; x, const year&amp; y) noexcept;
constexpr year operator+(const year&amp; x, const years&amp; y) noexcept;
constexpr year operator+(const years&amp; x, const year&amp; y) noexcept;
constexpr year operator-(const year&amp; x, const years&amp; y) noexcept;
constexpr years operator-(const year&amp; x, const year&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year&amp; y);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year&amp; y);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year&amp; y, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class weekday;
constexpr bool operator==(const weekday&amp; x, const weekday&amp; y) noexcept;
constexpr bool operator!=(const weekday&amp; x, const weekday&amp; y) noexcept;
constexpr weekday operator+(const weekday&amp; x, const days&amp; y) noexcept;
constexpr weekday operator+(const days&amp; x, const weekday&amp; y) noexcept;
constexpr weekday operator-(const weekday&amp; x, const days&amp; y) noexcept;
constexpr days operator-(const weekday&amp; x, const weekday&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday&amp; wd);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const weekday&amp; wd);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
weekday&amp; wd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class weekday_indexed;
constexpr bool operator==(const weekday_indexed&amp; x, const weekday_indexed&amp; y) noexcept;
constexpr bool operator!=(const weekday_indexed&amp; x, const weekday_indexed&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_indexed&amp; wdi);
class weekday_last;
constexpr bool operator==(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
constexpr bool operator!=(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_last&amp; wdl);
class month_day;
constexpr bool operator==(const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator!=(const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&lt; (const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&gt; (const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&lt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&gt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day&amp; md);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month_day&amp; md);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month_day&amp; md, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class month_day_last;
constexpr bool operator==(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator!=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&lt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&gt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&lt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&gt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day_last&amp; mdl);
class month_weekday;
constexpr bool operator==(const month_weekday&amp; x, const month_weekday&amp; y) noexcept;
constexpr bool operator!=(const month_weekday&amp; x, const month_weekday&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday&amp; mwd);
class month_weekday_last;
constexpr bool operator==(const month_weekday_last&amp; x, const month_weekday_last&amp; y) noexcept;
constexpr bool operator!=(const month_weekday_last&amp; x, const month_weekday_last&amp; y) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday_last&amp; mwdl);
class year_month;
constexpr bool operator==(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator!=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&lt; (const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&gt; (const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr year_month operator+(const year_month&amp; ym, const months&amp; dm) noexcept;
constexpr year_month operator+(const months&amp; dm, const year_month&amp; ym) noexcept;
constexpr year_month operator-(const year_month&amp; ym, const months&amp; dm) noexcept;
constexpr months operator-(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr year_month operator+(const year_month&amp; ym, const years&amp; dy) noexcept;
constexpr year_month operator+(const years&amp; dy, const year_month&amp; ym) noexcept;
constexpr year_month operator-(const year_month&amp; ym, const years&amp; dy) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month&amp; ym);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month&amp; ym);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month&amp; ym, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class year_month_day;
constexpr bool operator==(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator!=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&lt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&gt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr year_month_day operator+(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
constexpr year_month_day operator+(const months&amp; dm, const year_month_day&amp; ymd) noexcept;
constexpr year_month_day operator+(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
constexpr year_month_day operator+(const years&amp; dy, const year_month_day&amp; ymd) noexcept;
constexpr year_month_day operator-(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
constexpr year_month_day operator-(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day&amp; ymd);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month_day&amp; ymd);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month_day&amp; ymd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
class year_month_day_last;
constexpr bool operator==(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator!=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&lt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&gt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
constexpr year_month_day_last operator+(const months&amp; dm, const year_month_day_last&amp; ymdl) noexcept;
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
constexpr year_month_day_last operator+(const years&amp; dy, const year_month_day_last&amp; ymdl) noexcept;
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day_last&amp; ymdl);
class year_month_weekday;
constexpr bool operator==(const year_month_weekday&amp; x, const year_month_weekday&amp; y) noexcept;
constexpr bool operator!=(const year_month_weekday&amp; x, const year_month_weekday&amp; y) noexcept;
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
constexpr year_month_weekday operator+(const months&amp; dm, const year_month_weekday&amp; ymwd) noexcept;
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
constexpr year_month_weekday operator+(const years&amp; dy, const year_month_weekday&amp; ymwd) noexcept;
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday&amp; ymwdi);
class year_month_weekday_last;
constexpr bool operator==(const year_month_weekday_last&amp; x, const year_month_weekday_last&amp; y) noexcept;
constexpr bool operator!=(const year_month_weekday_last&amp; x, const year_month_weekday_last&amp; y) noexcept;
constexpr year_month_weekday_last operator+(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
constexpr year_month_weekday_last operator+(const months&amp; dm, const year_month_weekday_last&amp; ymwdl) noexcept;
constexpr year_month_weekday_last operator+(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
constexpr year_month_weekday_last operator+(const years&amp; dy, const year_month_weekday_last&amp; ymwdl) noexcept;
constexpr year_month_weekday_last operator-(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
constexpr year_month_weekday_last operator-(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday_last&amp; ymwdl);
// civil calendar conventional syntax operators
constexpr year_month operator/(const year&amp; y, const month&amp; m) noexcept;
constexpr year_month operator/(const year&amp; y, int m) noexcept;
constexpr month_day operator/(const month&amp; m, const day&amp; d) noexcept;
constexpr month_day operator/(const month&amp; m, int d) noexcept;
constexpr month_day operator/(int m, const day&amp; d) noexcept;
constexpr month_day operator/(const day&amp; d, const month&amp; m) noexcept;
constexpr month_day operator/(const day&amp; d, int m) noexcept;
constexpr month_day_last operator/(const month&amp; m, last_spec) noexcept;
constexpr month_day_last operator/(int m, last_spec) noexcept;
constexpr month_day_last operator/(last_spec, const month&amp; m) noexcept;
constexpr month_day_last operator/(last_spec, int m) noexcept;
constexpr month_weekday operator/(const month&amp; m, const weekday_indexed&amp; wdi) noexcept;
constexpr month_weekday operator/(int m, const weekday_indexed&amp; wdi) noexcept;
constexpr month_weekday operator/(const weekday_indexed&amp; wdi, const month&amp; m) noexcept;
constexpr month_weekday operator/(const weekday_indexed&amp; wdi, int m) noexcept;
constexpr month_weekday_last operator/(const month&amp; m, const weekday_last&amp; wdl) noexcept;
constexpr month_weekday_last operator/(int m, const weekday_last&amp; wdl) noexcept;
constexpr month_weekday_last operator/(const weekday_last&amp; wdl, const month&amp; m) noexcept;
constexpr month_weekday_last operator/(const weekday_last&amp; wdl, int m) noexcept;
constexpr year_month_day operator/(const year_month&amp; ym, const day&amp; d) noexcept;
constexpr year_month_day operator/(const year_month&amp; ym, int d) noexcept;
constexpr year_month_day operator/(const year&amp; y, const month_day&amp; md) noexcept;
constexpr year_month_day operator/(int y, const month_day&amp; md) noexcept;
constexpr year_month_day operator/(const month_day&amp; md, const year&amp; y) noexcept;
constexpr year_month_day operator/(const month_day&amp; md, int y) noexcept;
constexpr year_month_day_last operator/(const year_month&amp; ym, last_spec) noexcept;
constexpr year_month_day_last operator/(const year&amp; y, const month_day_last&amp; mdl) noexcept;
constexpr year_month_day_last operator/(int y, const month_day_last&amp; mdl) noexcept;
constexpr year_month_day_last operator/(const month_day_last&amp; mdl, const year&amp; y) noexcept;
constexpr year_month_day_last operator/(const month_day_last&amp; mdl, int y) noexcept;
constexpr year_month_weekday operator/(const year_month&amp; ym, const weekday_indexed&amp; wdi) noexcept;
constexpr year_month_weekday operator/(const year&amp; y, const month_weekday&amp; mwd) noexcept;
constexpr year_month_weekday operator/(int y, const month_weekday&amp; mwd) noexcept;
constexpr year_month_weekday operator/(const month_weekday&amp; mwd, const year&amp; y) noexcept;
constexpr year_month_weekday operator/(const month_weekday&amp; mwd, int y) noexcept;
constexpr year_month_weekday_last operator/(const year_month&amp; ym, const weekday_last&amp; wdl) noexcept;
constexpr year_month_weekday_last operator/(const year&amp; y, const month_weekday_last&amp; mwdl) noexcept;
constexpr year_month_weekday_last operator/(int y, const month_weekday_last&amp; mwdl) noexcept;
constexpr year_month_weekday_last operator/(const month_weekday_last&amp; mwdl, const year&amp; y) noexcept;
constexpr year_month_weekday_last operator/(const month_weekday_last&amp; mwdl, int y) noexcept;
// time_of_day
template &lt;class Duration&gt; class time_of_day;
template &lt;&gt; class time_of_day&lt;hours&gt;;
template &lt;&gt; class time_of_day&lt;minutes&gt;;
template &lt;&gt; class time_of_day&lt;seconds&gt;;
template &lt;class Rep, class Period&gt; class time_of_day&lt;duration&lt;Rep, Period&gt;&gt;;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;hours&gt;&amp; t);
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;minutes&gt;&amp; t);
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;seconds&gt;&amp; t);
template&lt;class charT, class traits, class Rep, class Period&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;duration&lt;Rep, Period&gt;&gt;&amp; t);
// time zone database
struct tzdb;
class tzdb_list;
const tzdb&amp; get_tzdb();
tzdb_list&amp; get_tzdb_list();
const time_zone* locate_zone(string_view tz_name);
const time_zone* current_zone();
// Remote time zone database -- Needs discussion
const tzdb&amp; reload_tzdb();
string remote_version();
bool remote_download(string_view version);
bool remote_install(string_view version);
// exception classes
class nonexistent_local_time;
class ambiguous_local_time;
// information classes
struct sys_info;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_info&amp; si);
struct local_info;
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const local_info&amp; li);
// time_zone
enum class choose {earliest, latest};
class time_zone;
bool operator==(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator!=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&lt;(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&gt;(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&lt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&gt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
// zoned_time
template &lt;class Duration, class TimeZonePtr = const time_zone*&gt; class zoned_time;
using zoned_seconds = zoned_time&lt;seconds&gt;;
template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool
operator==(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class Duration1, class Duration, class TimeZonePtr2&gt;
bool
operator!=(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
const zoned_time&lt;Duration, TimeZonePtr&gt;& t);
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp);
// format
template &lt;class charT, class Streamable&gt;
basic_string&lt;charT&gt;
format(const charT* fmt, const Streamable&amp; s);
template &lt;class charT, class Streamable&gt;
basic_string&lt;charT&gt;
format(const locale&amp; loc, const charT* fmt, const Streamable&amp; s);
template &lt;class charT, class traits, class Alloc, class Streamable&gt;
basic_string&lt;charT, traits, Alloc&gt;
format(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, const Streamable&amp; s);
template &lt;class charT, class traits, class Alloc, class Streamable&gt;
basic_string&lt;charT, traits, Alloc&gt;
format(const locale&amp; loc, const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, const Streamable&amp; s);
// parse
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp);
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
minutes&amp; offset);
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);
// leap second support
class leap;
bool operator==(const leap&amp; x, const leap&amp; y);
bool operator!=(const leap&amp; x, const leap&amp; y);
bool operator&lt; (const leap&amp; x, const leap&amp; y);
bool operator&gt; (const leap&amp; x, const leap&amp; y);
bool operator&lt;=(const leap&amp; x, const leap&amp; y);
bool operator&gt;=(const leap&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator==(const const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator==(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator!=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator!=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&lt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&lt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&gt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&gt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&lt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&lt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&gt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&gt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
class link;
bool operator==(const link&amp; x, const link&amp; y);
bool operator!=(const link&amp; x, const link&amp; y);
bool operator&lt; (const link&amp; x, const link&amp; y);
bool operator&gt; (const link&amp; x, const link&amp; y);
bool operator&lt;=(const link&amp; x, const link&amp; y);
bool operator&gt;=(const link&amp; x, const link&amp; y);
} // namespace chrono
inline namespace literals {
inline namespace chrono_literals {
// ...
inline constexpr chrono::last_spec last{};
inline constexpr chrono::weekday sun{0};
inline constexpr chrono::weekday mon{1};
inline constexpr chrono::weekday tue{2};
inline constexpr chrono::weekday wed{3};
inline constexpr chrono::weekday thu{4};
inline constexpr chrono::weekday fri{5};
inline constexpr chrono::weekday sat{6};
inline constexpr chrono::month jan{1};
inline constexpr chrono::month feb{2};
inline constexpr chrono::month mar{3};
inline constexpr chrono::month apr{4};
inline constexpr chrono::month may{5};
inline constexpr chrono::month jun{6};
inline constexpr chrono::month jul{7};
inline constexpr chrono::month aug{8};
inline constexpr chrono::month sep{9};
inline constexpr chrono::month oct{10};
inline constexpr chrono::month nov{11};
inline 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;
}
}
</pre>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.traits.is_clock"></a><p class = note>
Add new section [time.is_clock] after 23.17.4.3 Specializations of <code>common_type</code>
[time.traits.specializations]:
</p>
<blockquote>
<h3>23.17.4.4 <code>is_clock</code> [time.traits.is_clock]</h3>
<pre>
template &lt;class T&gt; struct is_clock;
</pre>
<p>
<code>is_clock</code> is a <code>UnaryTypeTrait</code> ([meta.rqmts]) with a base
characteristic of <code>true_type</code> if <code>T</code> meets the <code>Clock</code>
requirements ([time.clock.req]), otherwise <code>false_type</code>. For the purposes of
the specification of this trait, the extent to which an implementation determines that a
type cannot meet the clock requirements is unspecified, except that as a minimum a type
<code>T</code> shall not qualify as a clock unless it satisfies all of the following
conditions:
</p>
<ul>
<li>the <i>qualified-id</i>s <code>T::rep</code>, <code>T::period</code>,
<code>T::duration</code>, and <code>T::time_point</code> are valid and
each denotes a type ([temp.deduct]),</li>
<li>the expression <code>T::is_steady</code> is well-formed when treated as
an unevaluated operand,</li>
<li>the expression <code>T::now()</code> is well-formed when treated as an
unevaluated operand.</li>
</ul>
<p>
The behavior of a program that adds specializations for <code>is_clock</code> is undefined.
</p>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.duration.io"></a><p class = note>
Add new section [time.duration.io] after 23.17.5.9 duration algorithms [time.duration.alg]:
</p>
<blockquote>
<h3>23.17.5.10 duration stream insertion [time.duration.io]</h3>
<pre>
template &lt;class charT, class traits, class Rep, class Period&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const duration&lt;Rep, Period&gt;&amp; d);
</pre>
<blockquote>
<p>
<i>Effects:</i> Forms a <code>basic_string&lt;charT, traits&gt;</code> from
<code>d.count()</code> appended with
<code>get_units&lt;charT, traits&gt;(typename Period::type{})</code> (described below) and
inserts that <code>basic_string</code> into <code>os</code>. [<i>Note:</i> this
specification assures that the result of this streaming operation will obey the
width and alignment properties of the stream. &mdash; <i>end note</i>]
</p>
<blockquote>
<p>
<code>get_units&lt;charT, traits&gt;(typename Period::type{})</code> is an
exposition-only function which returns a null-terminated string of
<code>charT</code> which depends on <code>Period::type</code> as follows
(let <code>period</code> be the type <code>Period::type</code>):
</p>
<ul>
<li>If <code>period</code> is type <code>atto</code>, <code>as</code>, else</li>
<li>if <code>period</code> is type <code>femto</code>, <code>fs</code>, else</li>
<li>if <code>period</code> is type <code>pico</code>, <code>ps</code>, else</li>
<li>if <code>period</code> is type <code>nano</code>, <code>ns</code>, else</li>
<li>if <code>period</code> is type <code>micro</code>, <code>&micro;s</code> (U+00B5), else</li>
<li>if <code>period</code> is type <code>milli</code>, <code>ms</code>, else</li>
<li>if <code>period</code> is type <code>centi</code>, <code>cs</code>, else</li>
<li>if <code>period</code> is type <code>deci</code>, <code>ds</code>, else</li>
<li>if <code>period</code> is type <code>ratio&lt;1&gt;</code>, <code>s</code>, else</li>
<li>if <code>period</code> is type <code>deca</code>, <code>das</code>, else</li>
<li>if <code>period</code> is type <code>hecto</code>, <code>hs</code>, else</li>
<li>if <code>period</code> is type <code>kilo</code>, <code>ks</code>, else</li>
<li>if <code>period</code> is type <code>mega</code>, <code>Ms</code>, else</li>
<li>if <code>period</code> is type <code>giga</code>, <code>Gs</code>, else</li>
<li>if <code>period</code> is type <code>tera</code>, <code>Ts</code>, else</li>
<li>if <code>period</code> is type <code>peta</code>, <code>Ps</code>, else</li>
<li>if <code>period</code> is type <code>exa</code>, <code>Es</code>, else</li>
<li>if <code>period</code> is type <code>ratio&lt;60&gt;</code>, <code>min</code>, else</li>
<li>if <code>period</code> is type <code>ratio&lt;3600&gt;</code>, <code>h</code>, else</li>
<li>if <code>period::den == 1</code>, <code>[num]s</code>, else</li>
<li><code>[num/den]s</code>.</li>
</ul>
<p>
In the list above the use of <code>num</code> and <code>den</code> refer to the
static data members of <code>period</code> which are converted to arrays of
<code>charT</code> using a decimal conversion with no leading zeroes.
</p>
<p>
For streams with <code>charT</code> which has a representation of 8 bits
<code>&micro;s</code> should be encoded as UTF-8. Otherwise UTF-16 or UTF-32
is encouraged. The implementation may substitute other encodings, including
<code>us</code>.
</p>
</blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Rep, class Period&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const duration&lt;Rep, Period&gt;&amp; d);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>d</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Rep, class Period, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
duration&lt;Rep, Period&gt;&amp; d,
basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the duration
<code>d</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse parses everything specified by the parsing format flags without error, and
yet none of the flags impacts a duration, <code>d</code> will be assigned a zero value.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.point"></a><p class = note>
Add to synopsis in section [time.point] 23.17.6 Class template <code>time_point</code>:
</p>
<blockquote><pre>
template &lt;class Clock, class Duration = typename Clock::duration&gt;
class time_point {
public:
...
// 23.17.6.3, arithmetic
<ins>constexpr time_point&amp; operator++();</ins>
<ins>constexpr time_point operator++(int);</ins>
<ins>constexpr time_point&amp; operator--();</ins>
<ins>constexpr time_point operator--(int);</ins>
constexpr time_point&amp; operator+=(const duration&amp; d);
constexpr time_point&amp; operator-=(const duration&amp; d);
...
};
</pre>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<p class = note>
Modify section 23.17.6 Class template <code>time_point</code> [time.point]/p1:
</p>
<blockquote>
<p>
1 <code>Clock</code> shall meet the Clock requirements ([time.clock.req])<ins>
or <code>Clock</code> shall be <code>local_t</code></ins>.
</p>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.point.arithmetic"></a><p class = note>
Add to section [time.point.arithmetic] 23.17.6.3 <code>time_point</code> arithmetic:
</p>
<blockquote>
<pre>
constexpr time_point&amp; operator++();
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++d_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr time_point operator++(int);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>time_point{d_++}</code>.
</p>
</blockquote>
<pre>
constexpr time_point&amp; operator--();
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--d_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr time_point operator--(int);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>time_point{d_--}</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock"></a><p class = note>
Modify 23.17.7 [time.clock]:
</p>
<blockquote>
<p>
1 The types defined in this subclause shall satisfy the TrivialClock requirements (23.17.3)
<ins>unless otherwise specified</ins>.
</p>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.system"></a><p class = note>
Modify 23.17.7.1 [time.clock.system]:
</p>
<blockquote>
<p>
1 Objects of class <code>system_clock</code> represent wall clock time from the
system-wide realtime clock.
<ins><code>sys_time&lt;Duration&gt;</code> measures time since (and before) 1970-01-01
00:00:00 UTC <i>excluding</i> leap seconds. This measure is commonly referred to
as <i>Unix Time</i>. This measure facilitates an efficient mapping between
<code>sys_time</code> and calendar types ([time.calendar])</ins>
</p>
<ins><p>
[<i>Example:</i>
</p>
<blockquote><pre>
sys_seconds{sys_days{1970y/jan/1}}.time_since_epoch() is 0s
sys_seconds{sys_days{2000y/jan/1}}.time_since_epoch() is 946'684'800s which is 10'957 * 86'400s
</pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p></ins>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<p class = note>
Deprecate the <code>to_time_t</code> and <code>from_time_t</code> static member functions of
<code>system_clock</code> in 23.17.7.1 [time.clock.system] by moving their declaration
and specification to Annex D.
</p>
<blockquote>
<p class = note>
<i>Rationale:</i> This proposal removes all need for using the C
<code>&lt;time.h&gt;</code> API except to translate <code>system_clock::time_point</code>
to legacy code. That translation can now be portably done by converting a
<code>system_clock::time_point</code> to a <code>year_month_day</code> and
<code>time_of_day&lt;seconds&gt;</code> and translating that information into a
<code>tm</code>. The C API is error prone with its lack of type safe distinctions
between local time and UTC, and suffers from a lack of handling precisions finer than
seconds. Furthermore the newer <code>timespec</code> API makes no distinction between
time points and time durations, further eroding type safety.
</p>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<p class = note>
Append new paragraphs after 23.17.7.1 [time.clock.system]/p4:
</p>
<blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const utc_time&lt;Duration&gt;&amp; u);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>sys_time t</code>, such that <code>to_utc_time(t) == u</code>
if such a mapping exists. Otherwise <code>u</code> represents a
time_point during a leap second insertion and the last representable value of
<code>sys_time prior</code> to the insertion of the leap second is returned.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
auto t = sys_days{jul/1/2015} - 500ms;
auto u = to_utc_time(t);
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25001ms);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25251ms);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25501ms);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 25751ms);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
u += 250ms;
t = to_sys_time(u);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
cout &lt;&lt; t &lt;&lt; " SYS == " &lt;&lt; u &lt;&lt; " UTC\n";
</pre></blockquote>
<p>
Output:
</p>
<blockquote><pre>
2015-06-30 23:59:59.500 SYS == 2015-06-30 23:59:59.500 UTC
2015-06-30 23:59:59.750 SYS == 2015-06-30 23:59:59.750 UTC
2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.000 UTC
2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.250 UTC
2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.500 UTC
2015-06-30 23:59:59.999 SYS == 2015-06-30 23:59:60.750 UTC
2015-07-01 00:00:00.000 SYS == 2015-07-01 00:00:00.000 UTC
2015-07-01 00:00:00.250 SYS == 2015-07-01 00:00:00.250 UTC
</pre></blockquote>
<p>
<i>&mdash; end example</i>]
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const tai_time&lt;Duration&gt;&amp; u);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to: <code>return to_sys_time(to_utc_time(u));</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_sys_time(const gps_time&lt;Duration&gt;&amp; u);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to: <code>return to_sys_time(to_utc_time(u));</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;Duration&gt;
to_sys_time(const file_time&lt;Duration&gt;&amp; u);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>sys_time t</code>, such that <code>to_file_time(t) == u</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This operator shall not participate in overload resolution if
<code>treat_as_floating_point&lt;typename Duration::rep&gt;::value</code> is
true, or if <code>Duration{1} &gt;= days{1}</code>.
</p>
<p>
<i>Effects:</i>
</p>
<blockquote><pre>
auto const dp = floor&lt;days&gt;(tp);
os &lt;&lt; year_month_day{dp} &lt;&lt; ' ' &lt;&lt; time_of_day{tp-dp};
</pre></blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
cout &lt;&lt; sys_seconds{0s} &lt;&lt; '\n'; // 1970-01-01 00:00:00
cout &lt;&lt; sys_seconds{946'684'800s} &lt;&lt; '\n'; // 2000-01-01 00:00:00
</pre></blockquote>
<p>
&mdash; <i>end example:</i>]
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_days&amp; dp);
</pre>
<blockquote>
<p>
<i>Effects:</i>
</p>
<blockquote><pre>
os &lt;&lt; year_month_day{dp};
</pre></blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const sys_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>"UTC"</code>. If <code>%z</code> is used (or a modified form of <code>%z</code>),
an offset of <code>0min</code> will be formatted.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
sys_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>sys_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
Additionally, the parsed offset will be subtracted from the successfully parsed time stamp
prior to assigning that difference to <code>tp</code>.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.utc"></a><p class = note>
Add new section [time.clock.utc] after 23.17.7.1 Class system_clock [time.clock.system]:
</p>
<blockquote>
<h3>23.17.7.2 Class utc_clock [time.clock.utc]</h3>
<pre>
class utc_clock
{
public:
using duration = system_clock::duration;
using rep = duration::rep;
using period = duration::period;
using time_point = chrono::time_point&lt;utc_clock&gt;;
static constexpr bool is_steady = <i>unspecified</i>;
static time_point now();
};
</pre>
<p>
In contrast to <code>sys_time</code> which does not take leap seconds into
account, <code>utc_clock</code> and its associated <code>time_point</code>,
<code>utc_time</code>, counts time, <i>including</i> leap seconds, since
1970-01-01 00:00:00 UTC.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
to_utc_time(sys_seconds{sys_days{1970y/jan/1}}).time_since_epoch() is 0s
to_utc_time(sys_seconds{sys_days{2000y/jan/1}}).time_since_epoch() is 946'684'822s which is 10'957 * 86'400s + 22s
</pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
<p>
<code>utc_clock</code> is not a <code>TrivialClock</code> unless the implementation
can guarantee that <code>utc_clock::now()</code> does not propagate an exception.
[<i>Note:</i> <code>noexcept(to_utc_time(system_clock::now()))</code> is
<code>false</code>. &mdash; <i>end note</i>]
</p>
<pre>
static utc_clock::time_point utc_clock::now();
</pre>
<blockquote>
<p>
<i>Returns:</i> The implementations should supply the best measure available.
This may be approximated with <code>to_utc_time(system_clock::now())</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const sys_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>utc_time</code> <code>u</code>, such that
<code>u.time_since_epoch() - t.time_since_epoch()</code> is equal to the number
of leap seconds that were inserted between <code>t</code> and 1970-01-01. If
<code>t</code> is exactly the date of leap second insertion, then the conversion
counts that leap second as inserted.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
auto t = sys_days{jul/1/2015} - 2ns;
auto u = to_utc_time(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = to_utc_time(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = to_utc_time(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
t += 1ns;
u = to_utc_time(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
</pre></blockquote>
<p>
<i>&mdash; end example</i>]
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const tai_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} - 378691210s</code>
</p>
<p>
<i>Note:</i> <code>378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const gps_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} + 315964809s</code>
</p>
<p>
<i>Note:</i> <code>315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
utc_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_utc_time(const file_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>utc_time t</code>, such that <code>to_file_time(t) == u</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const utc_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Calls <code>to_stream(os, fmt, t)</code>, where <code>fmt</code> is a
null-terminated array of <code>char_t</code> containing <code>"%F %T"</code> widened
for <code>charT</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const utc_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>"UTC"</code>. If <code>%z</code> is used (or a modified form of <code>%z</code>),
an offset of <code>0min</code> will be formatted. If <code>tp</code> represents a time
during a leap second insertion, and if a seconds field is formatted, the integral portion
of that format shall be <code>"60"</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
auto t = sys_days{jul/1/2015} - 500ms;
auto u = to_utc_time(t);
for (auto i = 0; i &lt; 8; ++i, u += 250ms)
cout &lt;&lt; u &lt;&lt; " UTC\n";
</pre></blockquote>
<p>
Output:
</p>
<blockquote><pre>
2015-06-30 23:59:59.500 UTC
2015-06-30 23:59:59.750 UTC
2015-06-30 23:59:60.000 UTC
2015-06-30 23:59:60.250 UTC
2015-06-30 23:59:60.500 UTC
2015-06-30 23:59:60.750 UTC
2015-07-01 00:00:00.000 UTC
2015-07-01 00:00:00.250 UTC
</pre></blockquote>
<p>
<i>&mdash; end example</i>]
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
utc_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>utc_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
Additionally, the parsed offset will be subtracted from the successfully parsed time stamp
prior to assigning that difference to <code>tp</code>.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.tai"></a><p class = note>
Add new section [time.clock.tai] after 23.17.7.2 Class utc_clock [time.clock.utc]:
</p>
<blockquote>
<h3>23.17.7.3 Class tai_clock [time.clock.tai]</h3>
<pre>
class tai_clock
{
public:
using duration = system_clock::duration;
using rep = duration::rep;
using period = duration::period;
using time_point = chrono::time_point&lt;tai_clock&gt;;
static constexpr bool is_steady = <i>unspecified</i>;
static time_point now();
};
</pre>
<p>
The clock <code>tai_clock</code> measures seconds since 1958-01-01 00:00:00 and is
offset 10s ahead of UTC at this date. That is, 1958-01-01 00:00:00 TAI is equivalent
to 1957-12-31 23:59:50 UTC. Leap seconds are not inserted into TAI. Therefore every
time a leap second is inserted into UTC, UTC falls another second behind TAI. For
example by 2000-01-01 there had been 22 leap seconds inserted so 2000-01-01 00:00:00 UTC
is equivalent to 2000-01-01 00:00:32 TAI (22s plus the initial 10s offset).
</p>
<p>
<code>tai_clock</code> is not a <code>TrivialClock</code> unless the implementation
can guarantee that <code>tai_clock::now()</code> does not propagate an exception.
[<i>Note:</i> <code>noexcept(to_tai_time(system_clock::now()))</code> is
<code>false</code>. &mdash; <i>end note</i>]
</p>
<pre>
static tai_clock::time_point tai_clock::now();
</pre>
<blockquote>
<p>
<i>Returns:</i> The implementations should supply the best measure available. This may
be approximated with <code>to_tai_time(system_clock::now())</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const sys_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to: <code>return to_tai_time(to_utc_time(t));</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const utc_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} + 378691210s</code>
</p>
<p>
<i>Note:</i> <code>378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const gps_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} + 694656019s</code>
</p>
<p>
<i>Note:</i> <code>694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
tai_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_tai_time(const file_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>tai_time t</code>, such that <code>to_file_time(t) == u</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const tai_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Calls <code>to_stream(os, fmt, t)</code>, where <code>fmt</code> is a
null-terminated array of <code>char_t</code> containing <code>"%F %T"</code> widened
for <code>charT</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const tai_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>"TAI"</code>. If <code>%z</code> is used (or a modified form of <code>%z</code>),
an offset of <code>0min</code> will be formatted. The date and time formatted shall be
equivalent to that formatted by a <code>sys_time</code> initialized with:
</p>
<blockquote><pre>
sys_time&lt;Duration&gt;{tp.time_since_epoch()} - (sys_days{1970y/jan/1} - sys_days{1958y/jan/1})
</pre></blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
auto st = sys_days{2000_y/jan/1};
auto tt = to_tai_time(st);
cout &lt;&lt; format("%F %T %Z == ", st) &lt;&lt; format("%F %T %Z\n", tt);
</pre></blockquote>
<p>
Output:
</p>
<blockquote><pre>
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI
</pre></blockquote>
<p>
<i>&mdash; end example</i>]
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
tai_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>tai_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
Additionally, the parsed offset will be subtracted from the successfully parsed time stamp
prior to assigning that difference to <code>tp</code>.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.gps"></a><p class = note>
Add new section [time.clock.gps] after 23.17.7.3 Class tai_clock [time.clock.tai]:
</p>
<blockquote>
<h3>23.17.7.4 Class gps_clock [time.clock.gps]</h3>
<pre>
class gps_clock
{
public:
using duration = system_clock::duration;
using rep = duration::rep;
using period = duration::period;
using time_point = chrono::time_point&lt;gps_clock&gt;;
static constexpr bool is_steady = <i>unspecified</i>;
static time_point now();
};
</pre>
<p>
The clock <code>gps_clock</code> measures seconds since The first Sunday of January,
1980 00:00:00 UTC. Leap seconds are not inserted into GPS. Therefore every
time a leap second is inserted into UTC, UTC falls another second behind GPS. Aside
from the offset from 1958y/jan/1 to 1980y/jan/sun[1] GPS is behind TAI by 19s due to
the 10s offset between 1958 and 1970 and the additional 9 leap seconds inserted between
1970 and 1980.
</p>
<p>
<code>gps_clock</code> is not a <code>TrivialClock</code> unless the implementation
can guarantee that <code>gps_clock::now()</code> does not propagate an exception.
[<i>Note:</i> <code>noexcept(to_gps_time(system_clock::now()))</code> is
<code>false</code>. &mdash; <i>end note</i>]
</p>
<pre>
static gps_clock::time_point gps_clock::now();
</pre>
<blockquote>
<p>
<i>Returns:</i> The implementations should supply the best measure available. This may
be approximated with <code>to_gps_time(system_clock::now())</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const sys_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to: <code>return to_gps_time(to_utc_time(t));</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const utc_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} - 315964809s</code>
</p>
<p>
<i>Note:</i> <code>315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const tai_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;{t.time_since_epoch()} - 694656019s</code>
</p>
<p>
<i>Note:</i> <code>694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s</code>
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
gps_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_gps_time(const file_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>gps_time t</code>, such that <code>to_file_time(t) == u</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const gps_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Calls <code>to_stream(os, fmt, t)</code>, where <code>fmt</code> is a
null-terminated array of <code>char_t</code> containing <code>"%F %T"</code> widened
for <code>charT</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const gps_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>"GPS"</code>. If <code>%z</code> is used (or a modified form of <code>%z</code>),
an offset of <code>0min</code> will be formatted. The date and time formatted shall be
equivalent to that formatted by a <code>sys_time</code> initialized with:
</p>
<blockquote><pre>
sys_time&lt;Duration&gt;{tp.time_since_epoch()} + (sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1})
</pre></blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
auto st = sys_days{2000_y/jan/1};
auto gt = to_gps_time(st);
cout &lt;&lt; format("%F %T %Z == ", st) &lt;&lt; format("%F %T %Z\n", gt);
</pre></blockquote>
<p>
Output:
</p>
<blockquote><pre>
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS
</pre></blockquote>
<p>
<i>&mdash; end example</i>]
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
gps_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>gps_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
Additionally, the parsed offset will be subtracted from the successfully parsed time stamp
prior to assigning that difference to <code>tp</code>.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.file"></a><p class = note>
Add new section [time.clock.file] after 23.17.7.4 Class gps_clock [time.clock.gps]:
</p>
<blockquote>
<h3>23.17.7.5 Class file_clock [time.clock.file]</h3>
<pre>
class file_clock
{
public:
using rep = <i>unspecified</i>;
using period = ratio&lt;<i>unspecified</i>, <i>unspecified</i>&gt;;
using duration = chrono::duration&lt;rep, period&gt;;
using time_point = chrono::time_point&lt;file_clock&gt;;
static constexpr bool is_steady = <i>unspecified</i>;
static time_point now() noexcept;
};
</pre>
<p>
The clock <code>file_clock</code> is used to create the <code>time_point</code> system
used for <code>file_time_type</code> ([filesystems]). It's epoch is unspecified.
</p>
<pre>
template &lt;class Duration&gt;
file_time&lt;Duration&gt;
to_file_time(const sys_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>file_time u</code>, such that <code>to_sys_time(u) == t</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const utc_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>file_time u</code>, such that <code>to_utc_time(u) == t</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const tai_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>file_time u</code>, such that <code>to_tai_time(u) == t</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
file_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;
to_file_time(const gps_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>file_time t</code>, such that <code>to_gps_time(t) == u</code> if
such a mapping exists. <code>t</code> and <code>u</code> should represent the same point
in time, even though they may have different epochs.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const file_time&lt;Duration&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> Calls <code>to_stream(os, fmt, t)</code>, where <code>fmt</code> is a
null-terminated array of <code>char_t</code> containing <code>"%F %T"</code> widened
for <code>charT</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const file_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>"UTC"</code>. If <code>%z</code> is used (or a modified form of <code>%z</code>),
an offset of <code>0min</code> will be formatted. The date and time formatted shall be
equivalent to that formatted by a <code>sys_time</code> initialized with <code>to_sys_time(tp)</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
file_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>file_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
Additionally, the parsed offset will be subtracted from the successfully parsed time stamp
prior to assigning that difference to <code>tp</code>.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.clock.local_time"></a><p class = note>
Add new section [time.clock.local_time] after 23.17.7.3 Class high_resolution_clock [time.clock.hres]:
</p>
<blockquote>
<h3>23.17.7.8 local_time [time.clock.local_time]</h3>
<p>
The family of time points denoted by <code>local_time&lt;Duration&gt;</code> are
based on the <i>pseudo clock</i> <code>local_t</code>. <code>local_t</code> has
no member <code>now()</code> and thus does not meet the clock requirements.
Nevertheless <code>local_time&lt;Duration&gt;</code> serves the vital role of
representing local time with respect to a not-yet-specified time zone. Aside
from being able to get the current time, the complete <code>time_point</code>
algebra is available for <code>local_time&lt;Duration&gt;</code> (just as for
<code>sys_time&lt;Duration&gt;</code>).
</p>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const local_time&lt;Duration&gt;&amp; lt);
</pre>
<blockquote>
<p>
<i>Effects:</i>
</p>
<blockquote><pre>
os &lt;&lt; sys_time&lt;Duration&gt;{lt.time_since_epoch()};
</pre></blockquote>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const local_time&lt;Duration&gt;&amp; tp,
const string* abbrev = nullptr, const seconds* offset_sec = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>tp</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format]. If <code>%Z</code> is used, it will be replaced with
<code>*abbrev</code> if <code>abbrev</code> is not equal to <code>nullptr</code>. If
<code>abbrev</code> is equal to <code>nullptr</code> (and <code>%Z</code> is used),
<code>ios_base::failbit</code> will be set. If <code>%z</code> is used (or a modified form of
<code>%z</code>), it will be formatted with the value of <code>*offset_sec</code> if
<code>offset_sec</code> is not equal to <code>nullptr</code>. If <code>%z</code>
(or a modified form of <code>%z</code>) is used, and <code>offset_sec</code> is equal to
<code>nullptr</code>, then <code>ios_base::failbit</code> is set.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
local_time&lt;Duration&gt;&amp; tp, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the <code>local_time</code>
<code>tp</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid date, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.format"></a><p class = note>
Add a new section 23.17.8 Formatting [time.format]:
</p>
<p class = note>
If <a href="https://wg21.link/p0645"><code>fmt</code> (P0645)</a> moves forward
within the LEWG, this section can easily be reworked to plug into that facility
without loss of functionality. This will avoid two unrelated
<code>format</code> facilities in the standard.
</p>
<blockquote>
<h3>23.17.8 Formatting [time.format]</h3>
<p>
Each <code>format</code> overload specified in this section calls <code>to_stream</code>
unqualified, so as to enable argument dependent lookup ([basic.lookup.argdep]).
</p>
<pre>
template &lt;class charT, class Streamable&gt;
basic_string&lt;charT&gt;
format(const charT* fmt, const Streamable&amp; s);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>to_stream(declval&lt;basic_ostream&lt;charT&gt;&amp;&gt;(), fmt, s)</code>
is a valid expression.
</p>
<p>
<i>Effects:</i> Constructs a local variable of type
<code>basic_ostringstream&lt;charT&gt;</code> (for exposition purposes, named
<code>os</code>). Executes <code>os.exceptions(ios::failbit | ios::badbit)</code>.
Then calls <code>to_stream(os, fmt, s)</code>.
</p>
<p>
<i>Returns:</i> <code>os.str()</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class Streamable&gt;
basic_string&lt;charT&gt;
format(const locale&amp; loc, const charT* fmt, const Streamable&amp; s);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>to_stream(declval&lt;basic_ostream&lt;charT&gt;&amp;&gt;(), fmt, s)</code>
is a valid expression.
</p>
<p>
<i>Effects:</i> Constructs a local variable of type
<code>basic_ostringstream&lt;charT&gt;</code> (for exposition purposes, named
<code>os</code>). Executes <code>os.exceptions(ios::failbit | ios::badbit)</code>.
Then calls <code>os.imbue(loc)</code>. Then calls <code>to_stream(os, fmt, s)</code>.
</p>
<p>
<i>Returns:</i> <code>os.str()</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc, class Streamable&gt;
basic_string&lt;charT, traits, Alloc&gt;
format(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, const Streamable&amp; s);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>to_stream(declval&lt;basic_ostringstream&lt;charT, traits, Alloc&gt;&amp;&gt;(), fmt.c_str(), s)</code>
is a valid expression.
</p>
<p>
<i>Effects:</i> Constructs a local variable of type
<code>basic_ostringstream&lt;charT, traits, Alloc&gt;</code> (for exposition purposes, named
<code>os</code>). Executes <code>os.exceptions(ios::failbit | ios::badbit)</code>.
Then calls <code>to_stream(os, fmt.c_str(), s)</code>.
</p>
<p>
<i>Returns:</i> <code>os.str()</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc, class Streamable&gt;
basic_string&lt;charT, traits, Alloc&gt;
format(const locale&amp; loc, const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, const Streamable&amp; s);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>to_stream(declval&lt;basic_ostringstream&lt;charT, traits, Alloc&gt;&amp;&gt;(), fmt.c_str(), s)</code>
is a valid expression.
</p>
<p>
<i>Effects:</i> Constructs a local variable of type
<code>basic_ostringstream&lt;charT, traits, Alloc&gt;</code> (for exposition purposes, named
<code>os</code>). Then calls <code>os.imbue(loc)</code>.
Executes <code>os.exceptions(ios::failbit | ios::badbit)</code>.
Then calls <code>to_stream(os, fmt.c_str(), s)</code>.
</p>
<p>
<i>Returns:</i> <code>os.str()</code>.
</p>
</blockquote>
<p>
The <code>format</code> functions call a <code>to_stream</code> function with a
<code>basic_ostream</code>, a formatting string specifier, and a <code>Streamable</code>
argument. Each <code>to_stream</code> overload is customized for each
<code>Streamable</code> type. However all <code>to_stream</code> overloads treat the
formatting string specifier according to the following specification:
</p>
<p>
The <code>fmt</code> string consists of zero or more conversion specifiers and ordinary
multibyte characters. A conversion specifier consists of a <code>%</code> character,
possibly followed by an <code>E</code> or <code>O</code> modifier character (described
below), followed by a character that determines the behavior of the conversion specifier.
All ordinary multibyte characters (excluding the terminating null character) are streamed
unchanged into the <code>basic_ostream</code>.
</p>
<p>
Each conversion specifier is replaced by appropriate characters as described in the
following list. Some of the conversion specifiers depend on the locale which is imbued
to the <code>basic_ostream</code>. If the <code>Streamable</code> object does not contain
the information the conversion specifier refers to, the value streamed to the
<code>basic_ostream</code> is unspecified.
</p>
<p>
Unless explicitly specified, <code>Streamable</code> types will not contain time zone
abbreviation and time zone offset information. If available, the conversion specifiers
<code>%Z</code> and <code>%z</code> will format this information (respectively). If
the information is not available, and <code>%Z</code> or <code>%z</code> are contained
in <code>fmt</code>, <code>ios_base::failbit</code> will be set on <code>os</code>.
</p>
<blockquote>
<table cellspacing="10">
<tr>
<td><code>%a</code></td>
<td>The locale's abbreviated weekday name. If the value does not contain a valid
<code>weekday</code>, <code>ios::failbit</code> is set.</td>
</tr>
<tr>
<td><code>%A</code></td>
<td>The locale's full weekday name. If the value does not contain a valid
<code>weekday</code>, <code>ios::failbit</code> is set.</td>
</tr>
<tr>
<td><code>%b</code></td>
<td>The locale's abbreviated month name. If the value does not contain a valid
<code>month</code>, <code>ios::failbit</code> is set.</td>
</tr>
<tr>
<td><code>%B</code></td>
<td>The locale's full month name. If the value does not contain a valid
<code>month</code>, <code>ios::failbit</code> is set.</td>
</tr>
<tr>
<td><code>%c</code></td>
<td>The locale's date and time representation. The modified command <code>%Ec</code>
produces the locale's alternate date and time representation.</td>
</tr>
<tr>
<td><code>%C</code></td>
<td>The year divided by 100 using floored division. If the result is a single decimal
digit, it is prefixed with <code>0</code>. The modified command <code>%EC</code>
produces the locale's alternative representation of the century.</td>
</tr>
<tr>
<td><code>%d</code></td>
<td>The day of month as a decimal number. If the result is a single decimal
digit, it is prefixed with <code>0</code>. The modified command <code>%Od</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%D</code></td>
<td>Equivalent to <code>%m/%d/%y</code>.</td>
</tr>
<tr>
<td><code>%e</code></td>
<td>The day of month as a decimal number. If the result is a single decimal
digit, it is prefixed with a space. The modified command <code>%Oe</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%F</code></td>
<td>Equivalent to <code>%Y-%m-%d</code>.</td>
</tr>
<tr>
<td><code>%g</code></td>
<td>The last two decimal digits of the ISO week-based year. If the result is a single
digit it is prefixed by <code>0</code>.</td>
</tr>
<tr>
<td><code>%G</code></td>
<td>The ISO week-based year as a decimal number. If the result is less than four
digits it is left-padded with <code>0</code> to four digits.</td>
</tr>
<tr>
<td><code>%h</code></td>
<td>Equivalent to <code>%b</code>.</td>
</tr>
<tr>
<td><code>%H</code></td>
<td>The hour (24-hour clock) as a decimal number. If the result is a single
digit, it is prefixed with <code>0</code>. The modified command <code>%OH</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%I</code></td>
<td>The hour (12-hour clock) as a decimal number. If the result is a single
digit, it is prefixed with <code>0</code>. The modified command <code>%OI</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%j</code></td>
<td>The day of the year as a decimal number. Jan 1 is <code>001</code>. If the result
is less than three digits, it is left-padded with <code>0</code> to three digits.</td>
</tr>
<tr>
<td><code>%m</code></td>
<td>The month as a decimal number. Jan is <code>01</code>. If the result is a single
digit, it is prefixed with <code>0</code>. The modified command <code>%Om</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%M</code></td>
<td>The minute as a decimal number. If the result is a single
digit, it is prefixed with <code>0</code>. The modified command <code>%OM</code>
produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%n</code></td>
<td>A newline character.</td>
</tr>
<tr>
<td><code>%p</code></td>
<td>The locale's equivalent of the AM/PM designations associated with a 12-hour
clock.</td>
</tr>
<tr>
<td><code>%r</code></td>
<td>The locale's 12-hour clock time.</td>
</tr>
<tr>
<td><code>%R</code></td>
<td>Equivalent to <code>%H:%M</code>.</td>
</tr>
<tr>
<td><code>%S</code></td>
<td>Seconds as a decimal number. If the number of seconds is less than 10, the result is
prefixed with <code>0</code>. If the precision of the input can not be exactly
represented with seconds, then the format is a decimal floating point number with a fixed
format and a precision matching that of the precision of the input (or to a microseconds
precision if the conversion to floating point decimal seconds can not be made within 18
fractional digits). The character for the decimal point is localized according to the
locale. The modified command <code>%OS</code> produces the locale's alternative
representation.</td>
</tr>
<tr>
<td><code>%t</code></td>
<td>A horizontal-tab character.</td>
</tr>
<tr>
<td><code>%T</code></td>
<td>Equivalent to <code>%H:%M:%S</code>.</td>
</tr>
<tr>
<td><code>%u</code></td>
<td>The ISO weekday as a decimal number (1-7), where Monday is 1. The modified command
<code>%Ou</code> produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%U</code></td>
<td>The week number of the year as a decimal number. The first Sunday of the year is the
first day of week <code>01</code>. Days of the same year prior to that are in week
<code>00</code>. If the result is a single digit, it is prefixed with <code>0</code>.
The modified command <code>%OU</code> produces the locale's alternative
representation.</td>
</tr>
<tr>
<td><code>%V</code></td>
<td>The ISO week-based week number as a decimal number. If the result is a single digit,
it is prefixed with <code>0</code>. The modified command <code>%OV</code> produces the
locale's alternative representation.</td>
</tr>
<tr>
<td><code>%w</code></td>
<td>The weekday as a decimal number (0-6), where Sunday is 0. The modified command
<code>%Ow</code> produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%W</code></td>
<td>The week number of the year as a decimal number. The first Monday of the year is the
first day of week <code>01</code>. Days of the same year prior to that are in week
<code>00</code>. If the result is a single digit, it is prefixed with <code>0</code>. The
modified command <code>%OW</code> produces the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%x</code></td>
<td>The locale's date representation. The modified command <code>%Ex</code>
produces the locale's alternate date representation.</td>
</tr>
<tr>
<td><code>%X</code></td>
<td>The locale's time representation. The modified command <code>%Ex</code>
produces the locale's alternate time representation.</td>
</tr>
<tr>
<td><code>%y</code></td>
<td>The last two decimal digits of the year. If the result is a single digit it is
prefixed by <code>0</code>.</td>
</tr>
<tr>
<td><code>%Y</code></td>
<td>The year as a decimal number. If the result is less than four digits it is
left-padded with <code>0</code> to four digits.</td>
</tr>
<tr>
<td><code>%z</code></td>
<td>The offset from UTC in the ISO 8601 format. For example <code>-0430</code> refers to
4 hours 30 minutes behind UTC. If the offset is zero, <code>+0000</code> is used.
The modified commands <code>%Ez</code> and <code>%Oz</code> insert a <code>:</code>
between the hours and minutes: <code>-04:30</code>. If the offset information is not
available, <code>ios_base::failbit</code> will be set.</td>
</tr>
<tr>
<td><code>%Z</code></td>
<td>The time zone abbreviation. If the time zone abbreviation is not available,
<code>ios_base::failbit</code> will be set.</td>
</tr>
<tr>
<td><code>%%</code></td>
<td>A <code>%</code> character.</td>
</tr>
</table>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.parse"></a><p class = note>
Add a new section 23.17.9 Parsing [time.parse]:
</p>
<blockquote>
<h3>23.17.9 Parsing [time.parse]</h3>
<p>
Each <code>parse</code> overload specified in this section calls <code>from_stream</code>
unqualified, so as to enable argument dependent lookup ([basic.lookup.argdep]).
</p>
<pre>
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.c_str(), tp)</code>
is a valid expression.
</p>
<p>
<i>Returns:</i> A manipulator that when extracted from a
<code>basic_istream&lt;charT, traits&gt; is</code> calls
<code>from_stream(is, fmt.c_str(), tp)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.c_str(), tp, &amp;abbrev)</code>
is a valid expression.
</p>
<p>
<i>Returns:</i> A manipulator that when extracted from a
<code>basic_istream&lt;charT, traits&gt; is</code> calls
<code>from_stream(is, fmt.c_str(), tp, &amp;abbrev)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
minutes&amp; offset);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.c_str(), tp, nullptr, &amp;offset)</code>
is a valid expression.
</p>
<p>
<i>Returns:</i> A manipulator that when extracted from a
<code>basic_istream&lt;charT, traits&gt; is</code> calls
<code>from_stream(is, fmt.c_str(), tp, nullptr, &amp;offset)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This function shall not participate in overload resolution unless
<code>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.c_str(), tp, &amp;abbrev, &amp;offset)</code>
is a valid expression.
</p>
<p>
<i>Returns:</i> A manipulator that when extracted from a
<code>basic_istream&lt;charT, traits&gt; is</code> calls
<code>from_stream(is, fmt.c_str(), tp, &amp;abbrev, &amp;offset)</code>.
</p>
</blockquote>
<p>
All <code>from_stream</code> overloads behave as an unformatted input function. Each
overload takes a format string containing ordinary characters and flags which have special
meaning. Each flag begins with a <code>%</code>. Some flags can be modified by
<code>E</code> or <code>O</code>. During parsing each flag interprets characters as parts
of date and time type according to the table below. Some flags can be modified by a width
parameter which governs how many characters are parsed from the stream in interpreting the
flag. All characters in the format string which are not represented in the table below,
except for white space, are parsed unchanged from the stream. A white space character
matches zero or more white space characters in the input stream.
</p>
<p>
If the <code>from_stream</code> overload fails to parse everything
specified by the format string, or if insufficient information is
parsed to specify a complete duration, time point, or calendrical data
structure, <code>ios_base::failbit</code> is set in the
<code>basic_istream</code>.
</p>
<blockquote>
<table cellspacing="10">
<tr>
<td><code>%a</code></td>
<td>The locale's full or abbreviated case-insensitive weekday name.</td>
</tr>
<tr>
<td><code>%A</code></td>
<td>Equivalent to <code>%a</code>.</td>
</tr>
<tr>
<td><code>%b</code></td>
<td>The locale's full or abbreviated case-insensitive month name.</td>
</tr>
<tr>
<td><code>%B</code></td>
<td>Equivalent to <code>%b</code>.</td>
</tr>
<tr>
<td><code>%c</code></td>
<td>The locale's date and time representation. The modified command <code>%Ec</code>
interprets the locale's alternate date and time representation.</td>
</tr>
<tr>
<td><code>%C</code></td>
<td>The century as a decimal number. The modified command <code>%NC</code> where
<code>N</code> is a positive decimal integer specifies the maximum number of characters to
read. If not specified, the default is 2. Leading zeroes are permitted but not required.
The modified commands <code>%EC</code> and <code>%OC</code> interpret the locale's
alternative representation of the century.</td>
</tr>
<tr>
<td><code>%d</code></td>
<td>The day of the month as a decimal number. The modified command <code>%Nd</code> where
<code>N</code> is a positive decimal integer specifies the maximum number of characters to
read. If not specified, the default is 2. Leading zeroes are permitted but not required.
The modified command <code>%EC</code> interprets the locale's alternative representation
of the day of the month.</td>
</tr>
<tr>
<td><code>%D</code></td>
<td>Equivalent to <code>%m/%d/%y</code>.</td>
</tr>
<tr>
<td><code>%e</code></td>
<td>Equivalent to <code>%d</code> and can be modified like <code>%d</code>.</td>
</tr>
<tr>
<td><code>%F</code></td>
<td>Equivalent to <code>%Y-%m-%d</code>. If modified with a width, the width is applied
to only <code>%Y</code>.</td>
</tr>
<tr>
<td><code>%g</code></td>
<td>The last two decimal digits of the ISO week-based year. The modified command
<code>%Ng</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 2. Leading zeroes are
permitted but not required.</td>
</tr>
<tr>
<td><code>%G</code></td>
<td>The ISO week-based year as a decimal number. The modified command <code>%NG</code>
where <code>N</code> is a positive decimal integer specifies the maximum number of
characters to read. If not specified, the default is 4. Leading zeroes are permitted
but not required.</td>
</tr>
<tr>
<td><code>%h</code></td>
<td>Equivalent to <code>%b</code>.</td>
</tr>
<tr>
<td><code>%H</code></td>
<td>The hour (24-hour clock) as a decimal number. The modified command <code>%NH</code>
where <code>N</code> is a positive decimal integer specifies the maximum number of
characters to read. If not specified, the default is 2. Leading zeroes are permitted
but not required. The modified command <code>%OH</code> interprets the locale's
alternative representation.</td>
</tr>
<tr>
<td><code>%I</code></td>
<td>The hour (12-hour clock) as a decimal number. The modified command <code>%NI</code>
where <code>N</code> is a positive decimal integer specifies the maximum number of
characters to read. If not specified, the default is 2. Leading zeroes are permitted
but not required.</td>
</tr>
<tr>
<td><code>%j</code></td>
<td>The day of the year as a decimal number. Jan 1 is <code>1</code>. The modified
command <code>%Nj</code> where <code>N</code> is a positive decimal integer specifies the
maximum number of characters to read. If not specified, the default is 3. Leading zeroes
are permitted but not required.</td>
</tr>
<tr>
<td><code>%m</code></td>
<td>The month as a decimal number. Jan is <code>1</code>. The modified command
<code>%Nm</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 2. Leading zeroes are
permitted but not required. The modified command <code>%Om</code> interprets the locale's
alternative representation.</td>
</tr>
<tr>
<td><code>%M</code></td>
<td>The minutes as a decimal number. The modified command
<code>%NM</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 2. Leading zeroes are
permitted but not required. The modified command <code>%OM</code> interprets the locale's
alternative representation.</td>
</tr>
<tr>
<td><code>%n</code></td>
<td>Matches one white space character.
[<i>Note:</i> <code>%n</code>, <code>%t</code> and a space, can be combined to match
a wide range of white-space patterns. For example <code>"%n "</code> matches one or
more white space characters, and <code>"%n%t%t"</code> matches one to three white
space characters. &mdash; <i>end note</i>]</td>
</tr>
<tr>
<td><code>%p</code></td>
<td>The locale's equivalent of the AM/PM designations associated with a 12-hour clock.
The command <code>%I</code> must precede <code>%p</code> in the format string.</td>
</tr>
<tr>
<td><code>%r</code></td>
<td>The locale's 12-hour clock time.</td>
</tr>
<tr>
<td><code>%R</code></td>
<td>Equivalent to <code>%H:%M</code>.</td>
</tr>
<tr>
<td><code>%S</code></td>
<td>The seconds as a decimal number. The modified command <code>%NS</code> where
<code>N</code> is a positive decimal integer specifies the maximum number of characters to
read. If not specified, the default is 2 if the input time has a precision convertible to
seconds. Otherwise the default width is determined by the decimal precision of the input
and the field is interpreted as a long double in a fixed format. If encountered, the
locale determines the decimal point character. Leading zeroes are permitted but not
required. The modified command <code>%OS</code> interprets the locale's alternative
representation.</td>
</tr>
<tr>
<td><code>%t</code></td>
<td>Matches zero or one white space characters.</td>
</tr>
<tr>
<td><code>%T</code></td>
<td>Equivalent to <code>%H:%M:%S</code>.</td>
</tr>
<tr>
<td><code>%u</code></td>
<td>The ISO weekday as a decimal number (1-7), where Monday is 1. The modified command
<code>%Nu</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 1. Leading zeroes are
permitted but not required. The modified command <code>%Ou</code> interprets the locale's
alternative representation.</td>
</tr>
<tr>
<td><code>%U</code></td>
<td>The week number of the year as a decimal number. The first Sunday of the year is the
first day of week <code>01</code>. Days of the same year prior to that are in week
<code>00</code>. The modified command <code>%NU</code> where <code>N</code> is a
positive decimal integer specifies the maximum number of characters to read. If not
specified, the default is 2. Leading zeroes are permitted but not required.</td>
</tr>
<tr>
<td><code>%V</code></td>
<td>The ISO week-based week number as a decimal number. The modified command
<code>%NV</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 2. Leading zeroes are
permitted but not required.</td>
</tr>
<tr>
<td><code>%w</code></td>
<td>The weekday as a decimal number (0-6), where Sunday is 0. The modified command
<code>%Nw</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 1. Leading zeroes are
permitted but not required. The modified command <code>%Ow</code> interprets the locale's
alternative representation.</td>
</tr>
<tr>
<td><code>%W</code></td>
<td>The week number of the year as a decimal number. The first Monday of the year is the
first day of week <code>01</code>. Days of the same year prior to that are in week
<code>00</code>. The modified command <code>%NW</code> where <code>N</code> is a positive
decimal integer specifies the maximum number of characters to read. If not specified, the
default is 2. Leading zeroes are permitted but not required.</td>
</tr>
<tr>
<td><code>%x</code></td>
<td>The locale's date representation. The modified command <code>%Ex</code>
produces the locale's alternate date representation.</td>
</tr>
<tr>
<td><code>%X</code></td>
<td>The locale's time representation. The modified command <code>%Ex</code>
produces the locale's alternate time representation.</td>
</tr>
<tr>
<td><code>%y</code></td>
<td>The last two decimal digits of the year.
If the century is not otherwise specified (e.g. with <code>%C</code>), values in the range
[69 - 99] are presumed to refer to the years [1969 - 1999], and values in the range [00 -
68] are presumed to refer to the years [2000 - 2068]. The modified command
<code>%Ny</code> where <code>N</code> is a positive decimal integer specifies the maximum
number of characters to read. If not specified, the default is 2. Leading zeroes are
permitted but not required. The modified commands <code>%Ey</code> and <code>%Oy</code>
interpret the locale's alternative representation.</td>
</tr>
<tr>
<td><code>%Y</code></td>
<td>The year as a decimal number. The modified command <code>%NY</code> where
<code>N</code> is a positive decimal integer specifies the maximum number of characters to
read. If not specified, the default is 4. Leading zeroes are permitted but not required.
The modified command <code>%EY</code> interprets the locale's alternative
representation.</td>
</tr>
<tr>
<td><code>%z</code></td>
<td>The offset from UTC in the ISO 8601 format. For example <code>-0430</code> refers to
4 hours 30 minutes behind UTC. The modified commands <code>%Ez</code> and <code>%Ez</code>
parse a <code>:</code> between the hours and minutes and leading zeroes on the hour field
are optional: <code>-4:30</code>.</td>
</tr>
<tr>
<td><code>%Z</code></td>
<td>The time zone abbreviation or name. A single word is parsed. This word can only
contain characters from the <i>basic source character set</i> ([lex.charset] in the
C++ standard) that are alphanumeric, or one of <code>'_'</code>, <code>'/'</code>,
<code>'-'</code> or <code>'+'</code>.</td>
</tr>
<tr>
<td><code>%%</code></td>
<td>A <code>%</code> character is extracted.</td>
</tr>
</table>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.calendar"></a><p class = note>
Add new section [time.calendar] after 23.17.9 Clocks [time.parse]:
</p>
<blockquote>
<h3>23.17.10 The civil calendar [time.calendar]</h3>
<p>
The types in this subclause describe the civil (Gregorian) calendar and its relationship
to <code>sys_days</code> and <code>local_days</code>.
</p>
<a name="time.calendar.last"></a><h3>23.17.10.1 Class <code>last_spec</code> [time.calendar.last]</h3>
<p>
The struct <code>last_spec</code> is used in conjunction with other calendar types to
specify the last in a sequence. For example, depending on context, it can represent
the last day of a month, or the last day of the week of a month.
</p>
<p>
There is an <code>constexpr</code> object of this type named <code>last</code> in the
<code>chrono_literals</code> namespace.
</p>
<pre>
struct last_spec
{
explicit last_spec() = default;
};
</pre>
<a name="time.calendar.day"></a><h3>23.17.10.2 Class <code>day</code> [time.calendar.day]</h3>
<p>
<code>day</code> 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 <code>unsigned</code> value, which will be subsequently truncated to fit into
<code>day</code>'s unspecified internal storage. <code>day</code> is equality and less-than
comparable, and participates in basic arithmetic with <code>days</code> representing the
quantity between any two <code>day</code>'s. One can form a <code>day</code> literal with
<code>d</code>. And one can stream out a <code>day</code>.
<code>day</code> has explicit conversions to and from <code>unsigned</code>.
</p>
<pre>
class day
{
unsigned char d_; // exposition only
public:
day() = default;
explicit constexpr day(unsigned d) noexcept;
constexpr day&amp; operator++() noexcept;
constexpr day operator++(int) noexcept;
constexpr day&amp; operator--() noexcept;
constexpr day operator--(int) noexcept;
constexpr day&amp; operator+=(const days&amp; d) noexcept;
constexpr day&amp; operator-=(const days&amp; d) noexcept;
constexpr explicit operator unsigned() const noexcept;
constexpr bool ok() const noexcept;
};
constexpr bool operator==(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator!=(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&lt; (const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&gt; (const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&lt;=(const day&amp; x, const day&amp; y) noexcept;
constexpr bool operator&gt;=(const day&amp; x, const day&amp; y) noexcept;
constexpr day operator+(const day&amp; x, const days&amp; y) noexcept;
constexpr day operator+(const days&amp; x, const day&amp; y) noexcept;
constexpr day operator-(const day&amp; x, const days&amp; y) noexcept;
constexpr days operator-(const day&amp; x, const day&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const day&amp; d);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const day&amp; d);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
day&amp; d, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>day</code> is a trivially copyable class type.<br>
<code>day</code> is a standard-layout class type.<br>
</p>
<pre>
explicit constexpr day::day(unsigned d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>day</code> by constructing
<code>d_</code> with <code>d</code>.
</p>
</blockquote>
<pre>
constexpr day&amp; day::operator++() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++d_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr day day::operator++(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr day&amp; day::operator--() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--d_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr day day::operator--(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr day&amp; day::operator+=(const days&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + d</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr day&amp; day::operator-=(const days&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - d</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit day::operator unsigned() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>d_</code>.
</p>
</blockquote>
<pre>
constexpr bool day::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>1 <= d_ && d_ <= 31</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>unsigned{x} &lt; unsigned{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr day operator+(const day&amp; x, const days&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>day{unsigned{x} + y.count()}</code>.
</p>
</blockquote>
<pre>
constexpr day operator+(const days&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y + x</code>.
</p>
</blockquote>
<pre>
constexpr day operator-(const day&amp; x, const days&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x + -y</code>.
</p>
</blockquote>
<pre>
constexpr days operator-(const day&amp; x, const day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>days{static_cast&lt;days::rep&gt;(unsigned{x} - unsigned{y})}</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const day&amp; d);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts a decimal integral text representation of <code>d</code> into
<code>os</code>. Single digit values are prefixed with <code>'0'</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const day&amp; d);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>d</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
day&amp; d, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>day d</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid day, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<pre>
constexpr day operator "" d(unsigned long long d) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>day{static_cast&lt;unsigned&gt;(d)}</code>.
</p>
</blockquote>
<a name="time.calendar.month"></a><h3>23.17.10.3 Class <code>month</code> [time.calendar.month]</h3>
<p>
<code>month</code> 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 <code>unsigned</code> value, which will be
subsequently truncated to fit into <code>month</code>'s unspecified internal
storage. <code>month</code> is equality and less-than comparable, and
participates in basic arithmetic with <code>months</code> representing the
quantity between any two <code>month</code>'s. One can stream out a
<code>month</code>. <code>month</code> has explicit conversions to and from
<code>unsigned</code>. There are 12 <code>month</code> constants, one for each
month of the year in the <code>chrono_literals</code> namespace.
</p>
<pre>
class month
{
unsigned char m_; // exposition only
public:
month() = default;
explicit constexpr month(unsigned m) noexcept;
constexpr month&amp; operator++() noexcept;
constexpr month operator++(int) noexcept;
constexpr month&amp; operator--() noexcept;
constexpr month operator--(int) noexcept;
constexpr month&amp; operator+=(const months&amp; m) noexcept;
constexpr month&amp; operator-=(const months&amp; m) noexcept;
constexpr explicit operator unsigned() const noexcept;
constexpr bool ok() const noexcept;
};
constexpr bool operator==(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator!=(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&lt; (const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&gt; (const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&lt;=(const month&amp; x, const month&amp; y) noexcept;
constexpr bool operator&gt;=(const month&amp; x, const month&amp; y) noexcept;
constexpr month operator+(const month&amp; x, const months&amp; y) noexcept;
constexpr month operator+(const months&amp; x, const month&amp; y) noexcept;
constexpr month operator-(const month&amp; x, const months&amp; y) noexcept;
constexpr months operator-(const month&amp; x, const month&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month&amp; m);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month&amp; m);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month&amp; m, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>month</code> is a trivially copyable class type.<br>
<code>month</code> is a standard-layout class type.<br>
</p>
<pre>
explicit constexpr month::month(unsigned m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>month</code> by constructing
<code>m_</code> with <code>m</code>.
</p>
</blockquote>
<pre>
constexpr month&amp; month::operator++() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>m_ &lt; 12</code>, <code>++m_</code>. Otherwise sets
<code>m_</code> to 1.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr month month::operator++(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr month&amp; month::operator--() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>m_ &gt; 1</code>, <code>--m_</code>. Otherwise sets
<code>m_</code> to 12.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr month month::operator--(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr month&amp; month::operator+=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + m</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr month&amp; month::operator-=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - m</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit month::operator unsigned() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr bool month::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>1 <= m_ && m_ <= 12</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>unsigned{x} &lt; unsigned{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr month operator+(const month&amp; x, const months&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>month</code> for which <code>ok() == true</code> and is found as
if by incrementing (or decrementing if <code>y &lt; months{0}</code>) <code>x</code>,
<code>y</code> times. If <code>month.ok() == false</code> prior to this operation,
behaves as if <code>*this</code> is first brought into the range [1, 12] by modular
arithmetic. [<i>Note:</i> For example <code>month{0}</code> becomes <code>month{12}</code>,
and <code>month{13}</code> becomes <code>month{1}</code>. &mdash; <i>end note</i>]
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>y</code>.
[<i>Note:</i> Repeated
increments or decrements is not a valid implementation. &mdash; <i>end note</i>]
</p>
<p>
<i>Example:</i> <code>feb + months{11} == jan</code>.
</p>
</blockquote>
<pre>
constexpr month operator+(const months&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y + x</code>.
</p>
</blockquote>
<pre>
constexpr month operator-(const month&amp; x, const months&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x + -y</code>.
</p>
</blockquote>
<pre>
constexpr months operator-(const month&amp; x, const month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>x.ok() == true</code> and <code>y.ok() == true</code>.
</p>
<p>
<i>Returns:</i> A value of <code>months</code> in the range of <code>months{0}</code> to
<code>months{11}</code> inclusive.
</p>
<p>
<i>Remarks:</i> The returned value <code>m</code> shall satisfy the equality:
<code>y + m == x</code>.
</p>
<p>
<i>Example:</i> <code>jan - feb == months{11} </code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month&amp; m);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>ok() == true</code> outputs the same string that would be
output for the month field by <code>asctime</code>. Otherwise outputs
<code>unsigned{m} &lt;&lt; " is not a valid month"</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month&amp; m);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>m</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month&amp; m, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>month m</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid month, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<a name="time.calendar.year"></a><h3>23.17.10.4 Class <code>year</code> [time.calendar.year]</h3>
<p>
<code>year</code> represents a year in the civil calendar. It shall represent values
in the range <code>[min(), max()]</code>. It can be constructed with any
<code>int</code> value, which will be subsequently truncated to fit into
<code>year</code>'s internal unspecified storage. <code>year</code> is equality and less-than
comparable, and participates in basic arithmetic with <code>years</code> representing the
quantity between any two <code>year</code>'s. One can form a <code>year</code> literal
with <code>y</code>. And one can stream out a <code>year</code>.
<code>year</code> has explicit conversions to and from <code>int</code>.
</p>
<pre>
class year
{
short y_; // exposition only
public:
year() = default;
explicit constexpr year(int y) noexcept;
constexpr year&amp; operator++() noexcept;
constexpr year operator++(int) noexcept;
constexpr year&amp; operator--() noexcept;
constexpr year operator--(int) noexcept;
constexpr year&amp; operator+=(const years&amp; y) noexcept;
constexpr year&amp; operator-=(const years&amp; y) noexcept;
constexpr year operator+() const noexcept;
constexpr year operator-() const 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&amp; x, const year&amp; y) noexcept;
constexpr bool operator!=(const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&lt; (const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&gt; (const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&lt;=(const year&amp; x, const year&amp; y) noexcept;
constexpr bool operator&gt;=(const year&amp; x, const year&amp; y) noexcept;
constexpr year operator+(const year&amp; x, const years&amp; y) noexcept;
constexpr year operator+(const years&amp; x, const year&amp; y) noexcept;
constexpr year operator-(const year&amp; x, const years&amp; y) noexcept;
constexpr years operator-(const year&amp; x, const year&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year&amp; y);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year&amp; y);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year&amp; y, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>year</code> is a trivially copyable class type.<br>
<code>year</code> is a standard-layout class type.<br>
</p>
<pre>
explicit constexpr year::year(int y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year</code> by constructing
<code>y_</code> with <code>y</code>.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator++() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++y_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year::operator++(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator--() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--y_</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year::operator--(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator+=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + y</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator-=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - y</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator+() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year&amp; year::operator-() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>year{-y_}</code>.
</p>
</blockquote>
<pre>
constexpr bool year::is_leap() const noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to: <code>return y_ % 4 == 0 &amp;&amp; (y_ % 100 != 0 || y_ % 400 == 0);</code>
</p>
</blockquote>
<pre>
constexpr explicit year::operator int() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr bool year::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>min() &lt;= y_ &amp;&amp; y_ &lt;= max()</code>.
</p>
</blockquote>
<pre>
static constexpr year year::min() noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>-32767</code>.
</p>
</blockquote>
<pre>
static constexpr year year::max() noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>32767</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>int{x} == int{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>int{x} &lt; int{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr year operator+(const year&amp; x, const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>year{int{x} + y.count()}</code>.
</p>
</blockquote>
<pre>
constexpr year operator+(const years&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y + x</code>.
</p>
</blockquote>
<pre>
constexpr year operator-(const year&amp; x, const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x + -y</code>.
</p>
</blockquote>
<pre>
constexpr years operator-(const year&amp; x, const year&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>years{int{x} - int{y}}</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year&amp; y);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts a signed decimal integral text representation of <code>y</code>
into <code>os</code>. If the year is in the range [-999, 999], prefixes the year with
<code>'0'</code> to four digits. If the year is negative, prefixes with <code>'-'</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year&amp; y);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>y</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year&amp; y, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>year y</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid year, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<pre>
constexpr year operator "" y(unsigned long long y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>year{static_cast&lt;int&gt;(y)}</code>.
</p>
</blockquote>
<a name="time.calendar.weekday"></a><h3>23.17.10.5 Class <code>weekday</code> [time.calendar.weekday]</h3>
<p>
<code>weekday</code> represents a day of the week in the civil calendar. It
normally holds values in the range 0 to 6, corresponding to Sunday through
Saturday. However it may hold non-negative values outside this range. It can be
constructed with any <code>unsigned</code> value, which will be subsequently
truncated to fit into <code>weekday</code>'s unspecified internal storage.
<code>weekday</code> is equality comparable. <code>weekday</code> is not
less-than comparable because there is no universal consensus on which day is the
first day of the week. This design chooses the encoding of 0 to 6 to represent
Sunday through Saturday only because this is consistent with existing C and C++
practice. However <code>weekday</code>'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 <code>weekday</code>. <code>weekday</code> has explicit
conversions to and from <code>unsigned</code>. There are 7 <code>weekday</code>
constants, one for each day of the week in the <code>chrono_literals</code>
namespace.
</p>
<p>
A <code>weekday</code> can be implicitly constructed from a <code>sys_days</code>. This
is the computation that discovers the day of the week of an arbitrary date.
</p>
<p>
A <code>weekday</code> can be indexed with either <code>unsigned</code> or
<code>last</code>. This produces new types which represent the first, second, third,
fourth, fifth or last weekdays of a month.
</p>
<pre>
class weekday
{
unsigned char wd_; // exposition only
public:
weekday() = default;
explicit constexpr weekday(unsigned wd) noexcept;
constexpr weekday(const sys_days&amp; dp) noexcept;
constexpr explicit weekday(const local_days&amp; dp) noexcept;
constexpr weekday&amp; operator++() noexcept;
constexpr weekday operator++(int) noexcept;
constexpr weekday&amp; operator--() noexcept;
constexpr weekday operator--(int) noexcept;
constexpr weekday&amp; operator+=(const days&amp; d) noexcept;
constexpr weekday&amp; operator-=(const days&amp; 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&amp; x, const weekday&amp; y) noexcept;
constexpr bool operator!=(const weekday&amp; x, const weekday&amp; y) noexcept;
constexpr weekday operator+(const weekday&amp; x, const days&amp; y) noexcept;
constexpr weekday operator+(const days&amp; x, const weekday&amp; y) noexcept;
constexpr weekday operator-(const weekday&amp; x, const days&amp; y) noexcept;
constexpr days operator-(const weekday&amp; x, const weekday&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday&amp; wd);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const weekday&amp; wd);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
weekday&amp; wd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>weekday</code> is a trivially copyable class type.<br>
<code>weekday</code> is a standard-layout class type.<br>
</p>
<pre>
explicit constexpr weekday::weekday(unsigned wd) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>weekday</code> by constructing
<code>wd_</code> with <code>wd</code>.
</p>
</blockquote>
<pre>
constexpr weekday(const sys_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>weekday</code> by computing what day
of the week corresponds to the <code>sys_days dp</code>, and representing that day of
the week in <code>wd_</code>.
</p>
<p>
<i>Example:</i> If <code>dp</code> represents 1970-01-01, the constructed
<code>weekday</code> represents Thursday by storing 4 in <code>wd_</code>.
</p>
</blockquote>
<pre>
constexpr explicit weekday(const local_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>weekday</code> by computing what day
of the week corresponds to the <code>local_days dp</code>, and representing that day of
the week in <code>wd_</code>.
</p>
<p>
The value after construction shall be identical to that constructed from
<code>sys_days{dp.time_since_epoch()}</code>.
</p>
</blockquote>
<pre>
constexpr weekday&amp; weekday::operator++() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>wd_ != 6</code>, <code>++wd_</code>. Otherwise sets
<code>wd_</code> to 0.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr weekday weekday::operator++(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>++(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr weekday&amp; weekday::operator--() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>wd_ != 0</code>, <code>--wd_</code>. Otherwise sets
<code>wd_</code> to 6.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr weekday weekday::operator--(int) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>--(*this)</code>.
</p>
<p>
<i>Returns:</i> A copy of <code>*this</code> as it existed on entry to this member
function.
</p>
</blockquote>
<pre>
constexpr weekday&amp; weekday::operator+=(const days&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + d</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr weekday&amp; weekday::operator-=(const days&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - d</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit weekday::operator unsigned() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_</code>.
</p>
</blockquote>
<pre>
constexpr bool weekday::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_ <= 6</code>.
</p>
</blockquote>
<pre>
constexpr weekday_indexed weekday::operator[](unsigned index) const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>{*this, index}</code>.
</p>
</blockquote>
<pre>
constexpr weekday_last weekday::operator[](last_spec) const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>weekday_last{*this}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const weekday&amp; x, const weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const weekday&amp; x, const weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr weekday operator+(const weekday&amp; x, const days&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>weekday</code> for which <code>ok() == true</code> and is found as
if by incrementing (or decrementing if <code>y &lt; days{0}</code>) <code>x</code>,
<code>y</code> times. If <code>weekday.ok() == false</code> prior to this operation,
behaves as if <code>*this</code> is first brought into the range [0, 6] by modular
arithmetic. [<i>Note:</i> For example <code>weekday{7}</code> becomes
<code>weekday{0}</code>. &mdash; <i>end note</i>]
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>y</code>.
[<i>Note:</i> Repeated
increments or decrements is not a valid implementation. &mdash; <i>end note</i>]
</p>
<p>
<i>Example:</i> <code>mon + days{6} == sun</code>.
</p>
</blockquote>
<pre>
constexpr weekday operator+(const days&amp; x, const weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y + x</code>.
</p>
</blockquote>
<pre>
constexpr weekday operator-(const weekday&amp; x, const days&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x + -y</code>.
</p>
</blockquote>
<pre>
constexpr days operator-(const weekday&amp; x, const weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>x.ok() == true</code> and <code>y.ok() == true</code>.
</p>
<p>
<i>Returns:</i> A value of <code>days</code> in the range of <code>days{0}</code> to
<code>days{6}</code> inclusive.
</p>
<p>
<i>Remarks:</i> The returned value <code>d</code> shall satisfy the equality:
<code>y + d == x</code>.
</p>
<p>
<i>Example:</i> <code>sun - mon == days{6}</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday&amp; wd);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>ok() == true</code> outputs the same string that would be
output for the weekday field by <code>asctime</code>. Otherwise outputs
<code>unsigned{wd} &lt;&lt; " is not a valid weekday"</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const weekday&amp; wd);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>wd</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
weekday&amp; wd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>weekday wd</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid weekday, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<a name="time.calendar.weekday_indexed"></a><h3>23.17.10.6 Class <code>weekday_indexed</code> [time.calendar.weekday_indexed]</h3>
<p>
<code>weekday_indexed</code> represents a <code>weekday</code> 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 <code>weekday</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
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);
</pre></blockquote>
<p>
&mdash; <i>end example:</i>]
</p>
<pre>
class weekday_indexed
{
chrono::weekday wd_; // exposition only
unsigned char index_; // exposition only
public:
weekday_indexed() = default;
constexpr weekday_indexed(const chrono::weekday&amp; 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&amp; x, const weekday_indexed&amp; y) noexcept;
constexpr bool operator!=(const weekday_indexed&amp; x, const weekday_indexed&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_indexed&amp; wdi);
</pre>
<p>
<code>weekday_indexed</code> is a trivially copyable class type.<br>
<code>weekday_indexed</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr weekday_indexed::weekday_indexed(const chrono::weekday&amp; wd, unsigned index) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>weekday_indexed</code> by constructing
<code>wd_</code> with <code>wd</code> and <code>index_</code> with <code>index</code>.
</p>
</blockquote>
<pre>
constexpr weekday weekday_indexed::weekday() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_</code>.
</p>
</blockquote>
<pre>
constexpr unsigned weekday_indexed::index() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>index_</code>.
</p>
</blockquote>
<pre>
constexpr bool weekday_indexed::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_.ok() &amp;&amp; 1 &lt;= index_ && index_ &lt;= 5</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const weekday_indexed&amp; x, const weekday_indexed&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.weekday() == y.weekday() && x.index() == y.index()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const weekday_indexed&amp; x, const weekday_indexed&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_indexed&amp; wdi);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; wdi.weekday() &lt;&lt; '[' &lt;&lt; wdi.index() &lt;&lt; ']';
</pre></blockquote>
</blockquote>
<a name="time.calendar.weekday_last"></a><h3>23.17.10.7 Class <code>weekday_last</code> [time.calendar.weekday_last]</h3>
<p>
<code>weekday_last</code> represents the last <code>weekday</code> of a month.
It is most easily constructed by indexing a <code>weekday</code> with <code>last</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
constexpr auto wdl = sun[last]; // wdl is the last Sunday of an as yet unspecified month
static_assert(wdl.weekday() == sun);
</pre></blockquote>
<p>
&mdash; <i>end example:</i>]
</p>
<pre>
class weekday_last
{
chrono::weekday wd_; // exposition only
public:
explicit constexpr weekday_last(const chrono::weekday&amp; wd) noexcept;
constexpr chrono::weekday weekday() const noexcept;
constexpr bool ok() const noexcept;
};
constexpr bool operator==(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
constexpr bool operator!=(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_last&amp; wdl);
</pre>
<p>
<code>weekday_last</code> is a trivially copyable class type.<br>
<code>weekday_last</code> is a standard-layout class type.<br>
</p>
<pre>
explicit constexpr weekday_last::weekday_last(const chrono::weekday&amp; wd) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>weekday_last</code> by constructing
<code>wd_</code> with <code>wd</code>.
</p>
</blockquote>
<pre>
constexpr weekday weekday_last::weekday() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_</code>.
</p>
</blockquote>
<pre>
constexpr bool weekday_last::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wd_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.weekday() == y.weekday()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const weekday_last&amp; x, const weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const weekday_last&amp; wdl);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; wdi.weekday() &lt;&lt; "[last]";
</pre></blockquote>
</blockquote>
<a name="time.calendar.month_day"></a><h3>23.17.10.8 Class <code>month_day</code> [time.calendar.month_day]</h3>
<p>
<code>month_day</code> represents a specific <code>day</code> of a specific
<code>month</code>, but with an unspecified <code>year</code>. One can observe the
different components. One can assign a new value. <code>month_day</code> is equality
comparable and less-than comparable. One can stream out a <code>month_day</code>.
</p>
<pre>
class month_day
{
chrono::month m_; // exposition only
chrono::day d_; // exposition only
public:
month_day() = default;
constexpr month_day(const chrono::month&amp; m, const chrono::day&amp; 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&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator!=(const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&lt; (const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&gt; (const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&lt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
constexpr bool operator&gt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day&amp; md);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month_day&amp; md);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month_day&amp; md, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>month_day</code> is a trivially copyable class type.<br>
<code>month_day</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr month_day::month_day(const chrono::month&amp; m, const chrono::day&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>month_day</code> by constructing
<code>m_</code> with <code>m</code>, and <code>d_</code> with <code>d</code>.
</p>
</blockquote>
<pre>
constexpr month month_day::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr day month_day::day() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>d_</code>.
</p>
</blockquote>
<pre>
constexpr bool month_day::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>true</code> if <code>m_.ok()</code> is true, and if
<code>1d &lt;= d_</code>, and if <code>d_ &lt;=</code> the number of days in month
<code>m_</code>. For <code>m_ == feb</code> the number of days is considered to be 29.
Otherwise returns <code>false</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.month() == y.month() &amp;&amp; x.day() == y.day()</code>
</p>
</blockquote>
<pre>
constexpr bool operator!=(const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>x.month() &lt; y.month()</code> returns <code>true</code>. Else
if <code>x.month() &gt; y.month()</code> returns <code>false</code>. Else returns
<code>x.day() &lt; y.day()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const month_day&amp; x, const month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day&amp; md);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; md.month() &lt;&lt; '/' &lt;&lt; md.day();
</pre></blockquote>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const month_day&amp; md);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>md</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
month_day&amp; md, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>month_day md</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid <code>month_day</code>, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<a name="time.calendar.month_day_last"></a><h3>23.17.10.9 Class <code>month_day_last</code> [time.calendar.month_day_last]</h3>
<p>
<code>month_day_last</code> represents the last <code>day</code> of a <code>month</code>.
It is most easily constructed using the expression <code>m/last</code> or
<code>last/m</code>, where <code>m</code> is an expression with type <code>month</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote><pre>
constexpr auto mdl = feb/last; // mdl is the last day of February of an as yet unspecified year
static_assert(mdl.month() == feb);
</pre></blockquote>
<p>
&mdash; <i>end example:</i>]
</p>
<pre>
class month_day_last
{
chrono::month m_; // exposition only
public:
constexpr explicit month_day_last(const chrono::month&amp; m) noexcept;
constexpr chrono::month month() const noexcept;
constexpr bool ok() const noexcept;
};
constexpr bool operator==(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator!=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&lt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&gt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&lt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
constexpr bool operator&gt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day_last&amp; mdl);
</pre>
<p>
<code>month_day_last</code> is a trivially copyable class type.<br>
<code>month_day_last</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr explicit month_day_last::month_day_last(const chrono::month&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>month_day_last</code> by constructing
<code>m_</code> with <code>m</code>.
</p>
</blockquote>
<pre>
constexpr month month_day_last::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr bool month_day_last::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.month() == y.month()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.month() &lt; y.month()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const month_day_last&amp; x, const month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_day_last&amp; mdl);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; mdl.month() &lt;&lt; "/last";
</pre></blockquote>
</blockquote>
<a name="time.calendar.month_weekday"></a><h3>23.17.10.10 Class <code>month_weekday</code> [time.calendar.month_weekday]</h3>
<p>
<code>month_weekday</code> represents the nth <code>weekday</code> of a
<code>month</code>, of an as yet unspecified <code>year</code>. To do this the
<code>month_weekday</code> stores a <code>month</code> and a <code>weekday_indexed</code>.
</p>
<pre>
class month_weekday
{
chrono::month m_; // exposition only
chrono::weekday_indexed wdi_; // exposition only
public:
constexpr month_weekday(const chrono::month&amp; m, const chrono::weekday_indexed&amp; 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&amp; x, const month_weekday&amp; y) noexcept;
constexpr bool operator!=(const month_weekday&amp; x, const month_weekday&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday&amp; mwd);
</pre>
<p>
<code>month_weekday</code> is a trivially copyable class type.<br>
<code>month_weekday</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr month_weekday::month_weekday(const chrono::month&amp; m, const chrono::weekday_indexed&amp; wdi) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>month_weekday</code> by constructing
<code>m_</code> with <code>m</code>, and <code>wdi_</code> with <code>wdi</code>.
</p>
</blockquote>
<pre>
constexpr month month_weekday::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr weekday_indexed month_weekday::weekday_indexed() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdi_</code>.
</p>
</blockquote>
<pre>
constexpr bool month_weekday::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_.ok() &amp;&amp; wdi_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const month_weekday&amp; x, const month_weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.month() == y.month() &amp;&amp; x.weekday_indexed() == y.weekday_indexed()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const month_weekday&amp; x, const month_weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday&amp; mwd);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; mwd.month() &lt;&lt; '/' &lt;&lt; mwd.weekday_indexed();
</pre></blockquote>
</blockquote>
<a name="time.calendar.month_weekday_last"></a><h3>23.17.10.11 Class <code>month_weekday_last</code> [time.calendar.month_weekday_last]</h3>
<p>
<code>month_weekday_last</code> represents the last <code>weekday</code> of a
<code>month</code>, of an as yet unspecified <code>year</code>. To do this the
<code>month_weekday_last</code> stores a <code>month</code> and a
<code>weekday_last</code>.
</p>
<pre>
class month_weekday_last
{
chrono::month m_; // exposition only
chrono::weekday_last wdl_; // exposition only
public:
constexpr month_weekday_last(const chrono::month&amp; m,
const chrono::weekday_last&amp; 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&amp; x, const month_weekday_last&amp; y) noexcept;
constexpr bool operator!=(const month_weekday_last&amp; x, const month_weekday_last&amp; y) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday_last&amp; mwdl);
</pre>
<p>
<code>month_weekday_last</code> is a trivially copyable class type.<br>
<code>month_weekday_last</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr month_weekday_last::month_weekday_last(const chrono::month&amp; m,
const chrono::weekday_last&amp; wdl) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>month_weekday_last</code> by constructing
<code>m_</code> with <code>m</code>, and <code>wdl_</code> with <code>wdl</code>.
</p>
</blockquote>
<pre>
constexpr month month_weekday_last::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr weekday_last month_weekday_last::weekday_last() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdl_</code>.
</p>
</blockquote>
<pre>
constexpr bool month_weekday_last::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_.ok() &amp;&amp; wdl_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const month_weekday_last&amp; x, const month_weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.month() == y.month() &amp;&amp; x.weekday_last() == y.weekday_last()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const month_weekday_last&amp; x, const month_weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const month_weekday_last&amp; mwdl);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; mwdl.month() &lt;&lt; '/' &lt;&lt; mwdl.weekday_last();
</pre></blockquote>
</blockquote>
<a name="time.calendar.year_month"></a><h3>23.17.10.12 Class <code>year_month</code> [time.calendar.year_month]</h3>
<p>
<code>year_month</code> represents a specific <code>month</code> of a specific
<code>year</code>, but with an unspecified <code>day</code>. <code>year_month</code> is a
field-based time point with a resolution of <code>months</code>. One can observe the
different components. One can assign a new value. <code>year_month</code> is equality
comparable and less-than comparable. One can stream out a <code>year_month</code>.
</p>
<pre>
class year_month
{
chrono::year y_; // exposition only
chrono::month m_; // exposition only
public:
year_month() = default;
constexpr year_month(const chrono::year&amp; y, const chrono::month&amp; m) noexcept;
constexpr chrono::year year() const noexcept;
constexpr chrono::month month() const noexcept;
constexpr year_month&amp; operator+=(const months&amp; dm) noexcept;
constexpr year_month&amp; operator-=(const months&amp; dm) noexcept;
constexpr year_month&amp; operator+=(const years&amp; dy) noexcept;
constexpr year_month&amp; operator-=(const years&amp; dy) noexcept;
constexpr bool ok() const noexcept;
};
constexpr bool operator==(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator!=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&lt; (const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&gt; (const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr year_month operator+(const year_month&amp; ym, const months&amp; dm) noexcept;
constexpr year_month operator+(const months&amp; dm, const year_month&amp; ym) noexcept;
constexpr year_month operator-(const year_month&amp; ym, const months&amp; dm) noexcept;
constexpr months operator-(const year_month&amp; x, const year_month&amp; y) noexcept;
constexpr year_month operator+(const year_month&amp; ym, const years&amp; dy) noexcept;
constexpr year_month operator+(const years&amp; dy, const year_month&amp; ym) noexcept;
constexpr year_month operator-(const year_month&amp; ym, const years&amp; dy) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month&amp; ym);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month&amp; ym);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month&amp; ym, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>year_month</code> is a trivially copyable class type.<br>
<code>year_month</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr year_month::year_month(const chrono::year&amp; y, const chrono::month&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month</code> by constructing
<code>y_</code> with <code>y</code>, and <code>m_</code> with <code>m</code>.
</p>
</blockquote>
<pre>
constexpr year year_month::year() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr month year_month::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr year_month&amp; operator+=(const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + dm</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month&amp; operator-=(const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - dm</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month&amp; operator+=(const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + dy</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month&amp; operator-=(const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - dy</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr bool year_month::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_.ok() &amp;&amp; m_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() == y.year() &amp;&amp; x.month() == y.month()</code>
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>x.year() &lt; y.year()</code> returns <code>true</code>. Else
if <code>x.year() &gt; y.year()</code> returns <code>false</code>. Else returns
<code>x.month() &lt; y.month()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>year_month</code> value <code>z</code> such that
<code>z - ym == dm</code>.
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ym + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ym + -dm</code>.
</p>
</blockquote>
<pre>
constexpr months operator-(const year_month&amp; x, const year_month&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() - y.year() + months{static_cast&lt;int&gt;(unsigned{x.month()}) -
static_cast&lt;int&gt;(unsigned{y.month()})}</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>(ym.year() + dy) / ym.month()</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ym + dy</code>.
</p>
</blockquote>
<pre>
constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ym + -dy</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month&amp; ym);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; ym.year() &lt;&lt; '/' &lt;&lt; ym.month();
</pre></blockquote>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month&amp; ym);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>ym</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month&amp; ym, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>year_month ym</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid <code>year_month</code>, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<a name="time.calendar.year_month_day"></a><h3>23.17.10.13 Class <code>year_month_day</code> [time.calendar.year_month_day]</h3>
<p>
<code>year_month_day</code> represents a specific <code>year</code>, <code>month</code>,
and <code>day</code>. <code>year_month_day</code> is a field-based time point with a
resolution of <code>days</code>. One can observe each field. <code>year_month_day</code>
supports <code>years</code> and <code>months</code> oriented arithmetic, but not
<code>days</code> oriented arithmetic. For the latter, there is a conversion to
<code>sys_days</code> which efficiently supports <code>days</code> oriented arithmetic.
There is also a conversion <i>from</i> <code>sys_days</code>.
<code>year_month_day</code> is equality and less-than comparable.
</p>
<pre>
class year_month_day
{
chrono::year y_; // exposition only
chrono::month m_; // exposition only
chrono::day d_; // exposition only
public:
year_month_day() = default;
constexpr year_month_day(const chrono::year&amp; y, const chrono::month&amp; m, const chrono::day&amp; d) noexcept;
constexpr year_month_day(const year_month_day_last&amp; ymdl) noexcept;
constexpr year_month_day(const sys_days&amp; dp) noexcept;
constexpr explicit year_month_day(const local_days&amp; dp) noexcept;
constexpr year_month_day&amp; operator+=(const months&amp; m) noexcept;
constexpr year_month_day&amp; operator-=(const months&amp; m) noexcept;
constexpr year_month_day&amp; operator+=(const years&amp; y) noexcept;
constexpr year_month_day&amp; operator-=(const years&amp; 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&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator!=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&lt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&gt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
constexpr year_month_day operator+(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
constexpr year_month_day operator+(const months&amp; dm, const year_month_day&amp; ymd) noexcept;
constexpr year_month_day operator+(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
constexpr year_month_day operator+(const years&amp; dy, const year_month_day&amp; ymd) noexcept;
constexpr year_month_day operator-(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
constexpr year_month_day operator-(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day&amp; ymd);
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month_day&amp; ymd);
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month_day&amp; ymd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<p>
<code>year_month_day</code> is a trivially copyable class type.<br>
<code>year_month_day</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr year_month_day::year_month_day(const chrono::year&amp; y, const chrono::month&amp; m, const chrono::day&amp; d) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_day</code> by constructing
<code>y_</code> with <code>y</code>, <code>m_</code> with <code>m</code>, and,
<code>d_</code> with <code>d</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day::year_month_day(const year_month_day_last&amp; ymdl) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_day</code> by constructing
<code>y_</code> with <code>ymdl.year()</code>, <code>m_</code> with
<code>ymdl.month()</code>, and, <code>d_</code> with <code>ymdl.day()</code>.
</p>
<p>
<i>Note:</i> This conversion from <code>year_month_day_last</code> to
<code>year_month_day</code> is more efficient than converting a
<code>year_month_day_last</code> to a <code>sys_days</code>, and then converting that
<code>sys_days</code> to a <code>year_month_day</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day::year_month_day(const sys_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_day</code> which corresponds
to the date represented by <code>dp</code>.
</p>
<p>
<i>Remarks:</i> For any value of <code>year_month_day</code>, <code>ymd</code>, for which
<code>ymd.ok()</code> is <code>true</code>, this equality will also be <code>true</code>:
<code>ymd == year_month_day{sys_days{ymd}}</code>.
</p>
</blockquote>
<pre>
constexpr explicit year_month_day::year_month_day(const local_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_day</code> which corresponds
to the date represented by <code>dp</code>.
</p>
<p>
<i>Remarks:</i> Equivalent to constructing with <code>sys_days{dp.time_since_epoch()}</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day&amp; year_month_day::operator+=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day&amp; year_month_day::operator-=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day&amp; year_month_day::operator+=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day&amp; year_month_day::operator-=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year_month_day::year() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr month year_month_day::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr day year_month_day::day() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>d_</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day::operator sys_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>y_.ok() &amp;&amp; m_.ok() == true</code>.
</p>
<p>
<i>Returns:</i> If <code>ok()</code>, returns a <code>sys_days</code>
holding a count of <code>days</code> from the <code>sys_days</code> epoch to
<code>*this</code> (a negative value if <code>*this</code> represents a date
prior to the <code>sys_days</code> epoch). Otherwise returns a
<code>sys_days</code> which is offset from
<code>sys_days{y_/m_/last}</code> by the number of <code>days</code>
<code>d_</code> is offset from <code>sys_days{y_/m_/last}.day()</code>.
</p>
<p>
<i>Remarks:</i> A <code>sys_days</code> in the range
<code>[days{-12687428}, days{11248737}]</code> which is converted to a
<code>year_month_day</code>, shall have the same value when converted
back to a <code>sys_days</code>.
</p>
<p>
[<i>Example</i>:
</p>
<blockquote><pre>
static_assert(year_month_day{sys_days{2017y/jan/0}} == 2016y/dec/31);
static_assert(year_month_day{sys_days{2017y/jan/31}} == 2017y/jan/31);
static_assert(year_month_day{sys_days{2017y/jan/32}} == 2017y/feb/1);
</pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>
<pre>
constexpr explicit year_month_day::operator local_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>y_.ok() &amp;&amp; m_.ok() == true</code>.
</p>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return local_days{sys_days{*this}.time_since_epoch()};
</pre></blockquote>
</blockquote>
<pre>
constexpr bool year_month_day::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>y_.ok()</code> is <code>true</code>, and <code>m_.ok()</code> is
<code>true</code>, and <code>d_</code> is in the range
<code>[1d, (y_/m_/last).day()]</code>, then returns <code>true</code>, else returns
<code>false</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() == y.year() &amp;&amp; x.month() == y.month() &amp;&amp; x.day() == y.day()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>x.year() &lt; y.year()</code>, returns <code>true</code>. Else
if <code>x.year() &gt; y.year()</code> returns <code>false</code>.
Else if <code>x.month() &lt; y.month()</code>, returns <code>true</code>.
Else if <code>x.month() &gt; y.month()</code>, returns <code>false</code>.
Else returns <code>x.day() &lt; y.day()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const year_month_day&amp; x, const year_month_day&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator+(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ymd.month().ok()</code> is <code>true</code>.
</p>
<p>
<i>Returns:</i> <code>(ymd.year() / ymd.month() + dm) / ymd.day()</code>.
</p>
<p>
<i>Remarks:</i> If <code>ymd.day()</code> is in the range <code>[1d, 28d]</code>,
the resultant <code>year_month_day</code> shall return <code>true</code> from
<code>ok()</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator+(const months&amp; dm, const year_month_day&amp; ymd) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymd + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator-(const year_month_day&amp; ymd, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymd + (-dm)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator+(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>(ymd.year() + dy) / ymd.month() / ymd.day()</code>.
</p>
<p>
<i>Remarks:</i> If <code>ymd.month()</code> is <code>feb</code> and <code>ymd.day()</code>
is not in the range <code>[1d, 28d]</code>, the resultant <code>year_month_day</code> may
return <code>false</code> from <code>ok()</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator+(const years&amp; dy, const year_month_day&amp; ymd) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymd + dy</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day operator-(const year_month_day&amp; ymd, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymd + (-dy)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day&amp; ymd);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts <code>yyyy-mm-dd</code> where the number of indicated digits
are prefixed with <code>'0'</code> if necessary.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt, const year_month_day&amp; ymd);
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>ymd</code> into <code>os</code> using the format specified by
the null-terminated array <code>fmt</code>. <code>fmt</code> encoding follows the rules
specified by [time.format].
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Alloc = allocator&lt;charT&gt;&gt;
basic_istream&lt;charT, traits&gt;&amp;
from_stream(basic_istream&lt;charT, traits&gt;&amp; is, const charT* fmt,
year_month_day&amp; ymd, basic_string&lt;charT, traits, Alloc&gt;* abbrev = nullptr,
minutes* offset = nullptr);
</pre>
<blockquote>
<p>
<i>Effects:</i> Attempts to parse the input stream <code>is</code> into the
<code>year_month_day ymd</code> using the format flags as specified in [time.parse].
</p>
<p>
If the parse fails to decode a valid <code>year_month_day</code>, <code>ios_base::failbit</code> will be set.
</p>
<p>
If <code>%Z</code> is used and successfully parsed, that value will be assigned to
<code>*abbrev</code> if <code>abbrev</code> is non-null.
</p>
<p>
If <code>%z</code> (or a modified variant) is used and successfully parsed, that value
will be assigned to <code>*offset</code> if <code>offset</code> is non-null.
</p>
<p>
<i>Returns:</i> <code>is</code>.
</p>
</blockquote>
<a name="time.calendar.year_month_day_last"></a><h3>23.17.10.14 Class <code>year_month_day_last</code> [time.calendar.year_month_day_last]</h3>
<p>
<code>year_month_day_last</code> represents a specific <code>year</code>,
<code>month</code>, and the last <code>day</code> of the <code>month</code>.
<code>year_month_day_last</code> is a field-based time point with a resolution of
<code>days</code>, except that it is restricted to pointing to the last day of a year and
month. One can observe each field. The <code>day</code> field is computed on demand.
<code>year_month_day_last</code> supports <code>years</code> and <code>months</code>
oriented arithmetic, but not <code>days</code> oriented arithmetic. For the latter, there
is a conversion to <code>sys_days</code> which efficiently supports <code>days</code>
oriented arithmetic. <code>year_month_day_last</code> is equality and less-than
comparable.
</p>
<pre>
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&amp; y,
const chrono::month_day_last&amp; mdl) noexcept;
constexpr year_month_day_last&amp; operator+=(const months&amp; m) noexcept;
constexpr year_month_day_last&amp; operator-=(const months&amp; m) noexcept;
constexpr year_month_day_last&amp; operator+=(const years&amp; y) noexcept;
constexpr year_month_day_last&amp; operator-=(const years&amp; 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&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator!=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&lt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&gt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&lt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr bool operator&gt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
constexpr year_month_day_last operator+(const months&amp; dm, const year_month_day_last&amp; ymdl) noexcept;
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
constexpr year_month_day_last operator+(const years&amp; dy, const year_month_day_last&amp; ymdl) noexcept;
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day_last&amp; ymdl);
</pre>
<p>
<code>year_month_day_last</code> is a trivially copyable class type.<br>
<code>year_month_day_last</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr year_month_day_last::year_month_day_last(const chrono::year&amp; y,
const chrono::month_day_last&amp; mdl) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_day_last</code> by
constructing <code>y_</code> with <code>y</code> and <code>mdl_</code> with <code>mdl</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last&amp; year_month_day_last::operator+=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last&amp; year_month_day_last::operator-=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last&amp; year_month_day_last::operator+=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last&amp; year_month_day_last::operator-=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year_month_day_last::year() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr month year_month_day_last::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>mdl_.month()</code>.
</p>
</blockquote>
<pre>
constexpr month_day_last year_month_day_last::month_day_last() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>mdl_</code>.
</p>
</blockquote>
<pre>
constexpr day year_month_day_last::day() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>day</code> representing the last day of the <code>year</code>,
<code>month</code> pair represented by <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last::operator sys_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ok() == true</code>.
</p>
<p>
<i>Effects:</i> Equivalent to: <code>return sys_days{year()/month()/day()};</code>
</p>
</blockquote>
<pre>
constexpr explicit year_month_day_last::operator local_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ok() == true</code>.
</p>
<p>
<i>Effects:</i> Equivalent to: <code>return local_days{sys_days{*this}.time_since_epoch()};</code>
</p>
</blockquote>
<pre>
constexpr bool year_month_day_last::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_.ok() &amp;&amp; mdl_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() == y.year() &amp;&amp; x.month_day_last() == y.month_day_last()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>x.year() &lt; y.year()</code>, returns <code>true</code>. Else
if <code>x.year() &gt; y.year()</code> returns <code>false</code>.
Else returns <code>x.month_day_last() &lt; y.month_day_last()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt; (const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&lt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
constexpr bool operator&gt;=(const year_month_day_last&amp; x, const year_month_day_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ymdl.ok()</code> is <code>true</code>.
</p>
<p>
<i>Returns:</i> <code>(ymdl.year() / ymdl.month() + dm) / last</code>.
</p>
<p>
<i>Postconditions:</i> The resultant <code>year_month_day_last</code> returns
<code>true</code> from <code>ok()</code>.
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator+(const months&amp; dm, const year_month_day_last&amp; ymdl) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymdl + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymdl + (-dm)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator+(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>{ymdl.year()+dy, ymdl.month_day_last()}</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator+(const years&amp; dy, const year_month_day_last&amp; ymdl) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymdl + dy</code>.
</p>
</blockquote>
<pre>
constexpr year_month_day_last operator-(const year_month_day_last&amp; ymdl, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymdl + (-dy)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_day_last&amp; ymdl);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; ymdl.year() &lt;&lt; '/' &lt;&lt; ymdl.month_day_last();
</pre></blockquote>
</blockquote>
<a name="time.calendar.year_month_weekday"></a><h3>23.17.10.15 Class <code>year_month_weekday</code> [time.calendar.year_month_weekday]</h3>
<p>
<code>year_month_weekday</code> represents a specific <code>year</code>,
<code>month</code>, and nth <code>weekday</code> of the <code>month</code>.
<code>year_month_weekday</code> is a field-based time point with a resolution of
<code>days</code>. One can observe each field. <code>year_month_weekday</code> supports
<code>years</code> and <code>months</code> oriented arithmetic, but not <code>days</code>
oriented arithmetic. For the latter, there is a conversion to <code>sys_days</code> which
efficiently supports <code>days</code> oriented arithmetic.
<code>year_month_weekday</code> is equality comparable.
</p>
<pre>
class year_month_weekday
{
chrono::year y_; // exposition only
chrono::month m_; // exposition only
chrono::weekday_indexed wdi_; // exposition only
public:
year_month_weekday() = default;
constexpr year_month_weekday(const chrono::year&amp; y, const chrono::month&amp; m,
const chrono::weekday_indexed&amp; wdi) noexcept;
constexpr year_month_weekday(const sys_days&amp; dp) noexcept;
constexpr explicit year_month_weekday(const local_days&amp; dp) noexcept;
constexpr year_month_weekday&amp; operator+=(const months&amp; m) noexcept;
constexpr year_month_weekday&amp; operator-=(const months&amp; m) noexcept;
constexpr year_month_weekday&amp; operator+=(const years&amp; y) noexcept;
constexpr year_month_weekday&amp; operator-=(const years&amp; 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&amp; x, const year_month_weekday&amp; y) noexcept;
constexpr bool operator!=(const year_month_weekday&amp; x, const year_month_weekday&amp; y) noexcept;
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
constexpr year_month_weekday operator+(const months&amp; dm, const year_month_weekday&amp; ymwd) noexcept;
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
constexpr year_month_weekday operator+(const years&amp; dy, const year_month_weekday&amp; ymwd) noexcept;
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday&amp; ymwdi);
</pre>
<p>
<code>year_month_weekday</code> is a trivially copyable class type.<br>
<code>year_month_weekday</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr year_month_weekday::year_month_weekday(const chrono::year&amp; y, const chrono::month&amp; m,
const chrono::weekday_indexed&amp; wdi) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_weekday</code> by
constructing <code>y_</code> with <code>y</code>, <code>m_</code> with <code>m</code>,
and <code>wdi_</code> with <code>wdi</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday(const sys_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_weekday</code> which
corresponds to the date represented by <code>dp</code>.
</p>
<p>
<i>Remarks:</i> For any value of <code>year_month_weekday</code>, <code>ymdl</code>, for
which <code>ymdl.ok()</code> is <code>true</code>, this equality will also be
<code>true</code>: <code>ymdl == year_month_weekday{sys_days{ymdl}}</code>.
</p>
</blockquote>
<pre>
constexpr explicit year_month_weekday(const local_days&amp; dp) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_weekday</code> which
corresponds to the date represented by <code>dp</code>.
</p>
<p>
<i>Remarks:</i> Equivalent to constructing with <code>sys_days{dp.time_since_epoch()}</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday&amp; year_month_weekday::operator+=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday&amp; year_month_weekday::operator-=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday&amp; year_month_weekday::operator+=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday&amp; year_month_weekday::operator-=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year_month_weekday::year() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr month year_month_weekday::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr weekday year_month_weekday::weekday() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdi_.weekday()</code>.
</p>
</blockquote>
<pre>
constexpr unsigned year_month_weekday::index() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdi_.index()</code>.
</p>
</blockquote>
<pre>
constexpr weekday_indexed year_month_weekday::weekday_indexed() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdi_</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday::operator sys_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>y_.ok() &amp;&amp; m_.ok() &amp;&amp; wdi_.weekday().ok() == true</code>.
</p>
<p>
<i>Returns:</i> A <code>sys_days</code> which represents the date
<code>(index() - 1)*7</code> days after the first
<code>weekday()</code> of <code>year()/month()</code>. If <code>index()</code> is
<code>0</code> the returned <code>sys_days</code> represents the date 7 days prior
to the first <code>weekday()</code> of <code>year()/month()</code>.
</p>
</blockquote>
<pre>
constexpr explicit year_month_weekday::operator local_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>y_.ok() &amp;&amp; m_.ok() &amp;&amp; wdi_.weekday().ok() == true</code>.
</p>
<p>
<i>Effects:</i> Equivalent to: <code>return local_days{sys_days{*this}.time_since_epoch()};</code>
</p>
</blockquote>
<pre>
constexpr bool year_month_weekday::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>y_.ok()</code> or <code>m_.ok()</code> or <code>wdi_.ok()</code>
returns <code>false</code>, returns <code>false</code>. Else if <code>*this</code>
represents a valid date, returns <code>true</code>, else returns <code>false</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year_month_weekday&amp; x, const year_month_weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() == y.year() &amp;&amp; x.month() == y.month() &amp;&amp; x.weekday_indexed() == y.weekday_indexed()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year_month_weekday&amp; x, const year_month_weekday&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ymwd.ok()</code> is <code>true</code>.
</p>
<p>
<i>Returns:</i> <code>(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()</code>.
</p>
<p>
<i>Postconditions:</i> The resultant <code>year_month_weekday</code> returns
<code>true</code> from <code>ok()</code>.
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator+(const months&amp; dm, const year_month_weekday&amp; ymwd) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwd + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwd + (-dm)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator+(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>{ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator+(const years&amp; dy, const year_month_weekday&amp; ymwd) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwd + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday operator-(const year_month_weekday&amp; ymwd, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwd + (-dm)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday&amp; ymwd);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; ymwdi.year() &lt;&lt; '/' &lt;&lt; ymwdi.month() &lt;&lt; '/' &lt;&lt; ymwdi.weekday_indexed();
</pre></blockquote>
</blockquote>
<a name="time.calendar.year_month_weekday_last"></a><h3>23.17.10.16 Class <code>year_month_weekday_last</code> [time.calendar.year_month_weekday_last]</h3>
<p>
<code>year_month_weekday_last</code> represents a specific <code>year</code>,
<code>month</code>, and last <code>weekday</code> of the <code>month</code>.
<code>year_month_weekday_last</code> is a field-based time point with a resolution of
<code>days</code>, except that it is restricted to pointing to the last weekday of a year
and month. One can observe each field. <code>year_month_weekday_last</code> supports
<code>years</code> and <code>months</code> oriented arithmetic, but not <code>days</code>
oriented arithmetic. For the latter, there is a conversion to <code>sys_days</code> which
efficiently supports <code>days</code> oriented arithmetic.
<code>year_month_weekday_last</code> is equality comparable.
</p>
<pre>
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&amp; y, const chrono::month&amp; m,
const chrono::weekday_last&amp; wdl) noexcept;
constexpr year_month_weekday_last&amp; operator+=(const months&amp; m) noexcept;
constexpr year_month_weekday_last&amp; operator-=(const months&amp; m) noexcept;
constexpr year_month_weekday_last&amp; operator+=(const years&amp; y) noexcept;
constexpr year_month_weekday_last&amp; operator-=(const years&amp; 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&amp; x, const year_month_weekday_last&amp; y) noexcept;
constexpr
bool
operator!=(const year_month_weekday_last&amp; x, const year_month_weekday_last&amp; y) noexcept;
constexpr
year_month_weekday_last
operator+(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
constexpr
year_month_weekday_last
operator+(const months&amp; dm, const year_month_weekday_last&amp; ymwdl) noexcept;
constexpr
year_month_weekday_last
operator+(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
constexpr
year_month_weekday_last
operator+(const years&amp; dy, const year_month_weekday_last&amp; ymwdl) noexcept;
constexpr
year_month_weekday_last
operator-(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
constexpr
year_month_weekday_last
operator-(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday_last&amp; ymwdl);
</pre>
<p>
<code>year_month_weekday_last</code> is a trivially copyable class type.<br>
<code>year_month_weekday_last</code> is a standard-layout class type.<br>
</p>
<pre>
constexpr year_month_weekday_last::year_month_weekday_last(const chrono::year&amp; y, const chrono::month&amp; m,
const chrono::weekday_last&amp; wdl) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>year_month_weekday_last</code> by
constructing <code>y_</code> with <code>y</code>, <code>m_</code> with <code>m</code>,
and <code>wdl_</code> with <code>wdl</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last&amp; year_month_weekday_last::operator+=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last&amp; year_month_weekday_last::operator-=(const months&amp; m) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - m;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last&amp; year_month_weekday_last::operator+=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this + y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last&amp; year_month_weekday_last::operator-=(const years&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> <code>*this = *this - y;</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr year year_month_weekday_last::year() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y_</code>.
</p>
</blockquote>
<pre>
constexpr month year_month_weekday_last::month() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>m_</code>.
</p>
</blockquote>
<pre>
constexpr weekday year_month_weekday_last::weekday() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdl_.weekday()</code>.
</p>
</blockquote>
<pre>
constexpr weekday_last year_month_weekday_last::weekday_last() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>wdl_</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last::operator sys_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ok() == true</code>.
</p>
<p>
<i>Returns:</i> A <code>sys_days</code> which represents the last
<code>weekday()</code> of <code>year()/month()</code>.
</p>
</blockquote>
<pre>
constexpr explicit year_month_weekday_last::operator local_days() const noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ok() == true</code>.
</p>
<p>
<i>Effects:</i> Equivalent to: <code>return local_days{sys_days{*this}.time_since_epoch()};</code>
</p>
</blockquote>
<pre>
constexpr bool year_month_weekday_last::ok() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> If <code>y_.ok() &amp;&amp; m_.ok() &amp;&amp; wdl_.ok()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator==(const year_month_weekday_last&amp; x, const year_month_weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.year() == y.year() &amp;&amp; x.month() == y.month() &amp;&amp; x.weekday_last() == y.weekday_last()</code>.
</p>
</blockquote>
<pre>
constexpr bool operator!=(const year_month_weekday_last&amp; x, const year_month_weekday_last&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator+(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>ymwdl.ok()</code> is <code>true</code>.
</p>
<p>
<i>Returns:</i> <code>(ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()</code>.
</p>
<p>
<i>Postconditions:</i> The resultant <code>year_month_weekday_last</code> returns
<code>true</code> from <code>ok()</code>.
</p>
<p>
<i>Complexity:</i> O(1) with respect to the value of <code>dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator+(const months&amp; dm, const year_month_weekday_last&amp; ymwdl) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwdl + dm</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator-(const year_month_weekday_last&amp; ymwdl, const months&amp; dm) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwdl + (-dm)</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator+(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>{ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator+(const years&amp; dy, const year_month_weekday_last&amp; ymwdl) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwdl + dy</code>.
</p>
</blockquote>
<pre>
constexpr year_month_weekday_last operator-(const year_month_weekday_last&amp; ymwdl, const years&amp; dy) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>ymwdl + (-dy)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const year_month_weekday_last&amp; ymwdl);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
return os &lt;&lt; ymwdl.year() &lt;&lt; '/' &lt;&lt; ymwdl.month() &lt;&lt; '/' &lt;&lt; ymwdl.weekday_last();
</pre></blockquote>
</blockquote>
<a name="time.calendar.operators"></a><h3>23.17.10.17 civil calendar conventional syntax operators [time.calendar.operators]</h3>
<p>
A set of overloaded <code>operator/()</code> 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:
</p>
<ol>
<li><code>y/m/d</code></li>
<li><code>m/d/y</code></li>
<li><code>d/m/y</code></li>
</ol>
<p>
Anywhere a "day" is required one can also specify one of:
</p>
<ul>
<li><code>last</code></li>
<li><code>weekday[i]</code></li>
<li><code>weekday[last]</code></li>
</ul>
<p>
Partial-date-types such as <code>year_month</code> and <code>month_day</code> can be created
by simply not applying the second division operator for any of the three orders. For
example:
</p>
<blockquote><pre>
year_month ym = 2015y/apr;
month_day md1 = apr/4;
month_day md2 = 4d/apr;
</pre></blockquote>
<p>
Everything not intended as above is ill-formed, with the notable
exception of an expression that consists of nothing but <code>int</code>, which
has type <code>int</code>.
</p>
<blockquote><pre>
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')
</pre></blockquote>
<p><b><code>year_month</code>:</b></p>
<pre>
constexpr year_month operator/(const year&amp; y, const month&amp; m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{y, m}</code>.
</blockquote>
<pre>
constexpr year_month operator/(const year&amp; y, int m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / month(m)</code>.
</blockquote>
<p><b><code>month_day</code>:</b></p>
<pre>
constexpr month_day operator/(const month&amp; m, const day&amp; d) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{m, d}</code>.
</blockquote>
<pre>
constexpr month_day operator/(const month&amp; m, int d) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>m / day(d)</code>.
</blockquote>
<pre>
constexpr month_day operator/(int m, const day&amp; d) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / d</code>.
</blockquote>
<pre>
constexpr month_day operator/(const day&amp; d, const month&amp; m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>m / d</code>.
</blockquote>
<pre>
constexpr month_day operator/(const day&amp; d, int m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / d</code>.
</blockquote>
<p><b><code>month_day_last</code>:</b></p>
<pre>
constexpr month_day_last operator/(const month&amp; m, last_spec) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month_day_last{m}</code>.
</blockquote>
<pre>
constexpr month_day_last operator/(int m, last_spec) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / last</code>.
</blockquote>
<pre>
constexpr month_day_last operator/(last_spec, const month&amp; m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>m / last</code>.
</blockquote>
<pre>
constexpr month_day_last operator/(last_spec, int m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / last</code>.
</blockquote>
<p><b><code>month_weekday</code>:</b></p>
<pre>
constexpr month_weekday operator/(const month&amp; m, const weekday_indexed&amp; wdi) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{m, wdi}</code>.
</blockquote>
<pre>
constexpr month_weekday operator/(int m, const weekday_indexed&amp; wdi) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / wdi</code>.
</blockquote>
<pre>
constexpr month_weekday operator/(const weekday_indexed&amp; wdi, const month&amp; m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>m / wdi</code>.
</blockquote>
<pre>
constexpr month_weekday operator/(const weekday_indexed&amp; wdi, int m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / wdi</code>.
</blockquote>
<p><b><code>month_weekday_last</code>:</b></p>
<pre>
constexpr month_weekday_last operator/(const month&amp; m, const weekday_last&amp; wdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{m, wdl}</code>.
</blockquote>
<pre>
constexpr month_weekday_last operator/(int m, const weekday_last&amp; wdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / wdl</code>.
</blockquote>
<pre>
constexpr month_weekday_last operator/(const weekday_last&amp; wdl, const month&amp; m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>m / wdl</code>.
</blockquote>
<pre>
constexpr month_weekday_last operator/(const weekday_last&amp; wdl, int m) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>month(m) / wdl</code>.
</blockquote>
<p><b><code>year_month_day</code>:</b></p>
<pre>
constexpr year_month_day operator/(const year_month&amp; ym, const day&amp; d) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{ym.year(), ym.month(), d}</code>.
</blockquote>
<pre>
constexpr year_month_day operator/(const year_month&amp; ym, int d) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>ym / day(d)</code>.
</blockquote>
<pre>
constexpr year_month_day operator/(const year&amp; y, const month_day&amp; md) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / md.month() / md.day()</code>.
</blockquote>
<pre>
constexpr year_month_day operator/(int y, const month_day&amp; md) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / md</code>.
</blockquote>
<pre>
constexpr year_month_day operator/(const month_day&amp; md, const year&amp; y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / md</code>.
</blockquote>
<pre>
constexpr year_month_day operator/(const month_day&amp; md, int y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / md</code>.
</blockquote>
<p><b><code>year_month_day_last</code>:</b></p>
<pre>
constexpr year_month_day_last operator/(const year_month&amp; ym, last_spec) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{ym.year(), month_day_last{ym.month()}}</code>.
</blockquote>
<pre>
constexpr year_month_day_last operator/(const year&amp; y, const month_day_last&amp; mdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{y, mdl}</code>.
</blockquote>
<pre>
constexpr year_month_day_last operator/(int y, const month_day_last&amp; mdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mdl</code>.
</blockquote>
<pre>
constexpr year_month_day_last operator/(const month_day_last&amp; mdl, const year&amp; y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / mdl</code>.
</blockquote>
<pre>
constexpr year_month_day_last operator/(const month_day_last&amp; mdl, int y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mdl</code>.
</blockquote>
<p><b><code>year_month_weekday</code>:</b></p>
<pre>
constexpr year_month_weekday operator/(const year_month&amp; ym, const weekday_indexed&amp; wdi) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{ym.year(), ym.month(), wdi}</code>.
</blockquote>
<pre>
constexpr year_month_weekday operator/(const year&amp; y, const month_weekday&amp; mwd) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{y, mwd.month(), mwd.weekday_indexed()}</code>.
</blockquote>
<pre>
constexpr year_month_weekday operator/(int y, const month_weekday&amp; mwd) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mwd</code>.
</blockquote>
<pre>
constexpr year_month_weekday operator/(const month_weekday&amp; mwd, const year&amp; y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / mwd</code>.
</blockquote>
<pre>
constexpr year_month_weekday operator/(const month_weekday&amp; mwd, int y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mwd</code>.
</blockquote>
<p><b><code>year_month_weekday_last</code>:</b></p>
<pre>
constexpr year_month_weekday_last operator/(const year_month&amp; ym, const weekday_last&amp; wdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{ym.year(), ym.month(), wdl}</code>.
</blockquote>
<pre>
constexpr year_month_weekday_last operator/(const year&amp; y, const month_weekday_last&amp; mwdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>{y, mwdl.month(), mwdl.weekday_last()}</code>.
</blockquote>
<pre>
constexpr year_month_weekday_last operator/(int y, const month_weekday_last&amp; mwdl) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mwdl</code>.
</blockquote>
<pre>
constexpr year_month_weekday_last operator/(const month_weekday_last&amp; mwdl, const year&amp; y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>y / mwdl</code>.
</blockquote>
<pre>
constexpr year_month_weekday_last operator/(const month_weekday_last&amp; mwdl, int y) noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>year(y) / mwdl</code>.
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.time_of_day"></a><p class = note>
Add new section [time.time_of_day] after 23.17.10 The civil calendar [time.calendar]:
</p>
<blockquote>
<h3>23.17.11 Class <code>time_of_day</code> [time.time_of_day]</h3>
<p>
The <code>time_of_day</code> class breaks a <code>duration</code> which
represents the time elapsed since midnight, into a "broken" down time such as
hours:minutes:seconds. The <code>Duration</code> 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. <code>time_of_day</code> is primarily
a formatting tool.
</p>
<pre>
template &lt;class Duration&gt; class time_of_day;
</pre>
<p>
There are 4 specializations of <code>time_of_day</code> to handle four precisions:
</p>
<ol>
<li>
<pre>
tempalte &lt;&gt; class time_of_day&lt;hours&gt;
</pre>
<blockquote><p>
This specialization handles hours since midnight.
</p></blockquote>
</li>
<li>
<pre>
tempalte &lt;&gt; class time_of_day&lt;minutes&gt;
</pre>
<blockquote><p>
This specialization handles hours:minutes since midnight.
</p></blockquote>
</li>
<li>
<pre>
tempalte &lt;&gt; class time_of_day&lt;seconds&gt;
</pre>
<blockquote><p>
This specialization handles hours:minutes:seconds since midnight.
</p></blockquote>
</li>
<li>
<pre>
tempalte &lt;class Rep, class Period&gt; class time_of_day&lt;duration&lt;Rep, Period&gt;&gt;
</pre>
<blockquote><p>
This specialization is restricted to <code>Rep</code> types that are integral, and
<code>Period</code>s that are not an integral number of seconds. Typical uses are with
milliseconds, microseconds and nanoseconds. This specialization handles
hours:minute:seconds.fractional_seconds since midnight.
</p></blockquote>
</li>
</ol>
<p>
Each specialization of <code>time_of_day</code> is a trivially copyable class type.<br>
Each specialization of <code>time_of_day</code> is a standard-layout class type.<br>
</p>
<pre>
tempalte &lt;&gt;
class time_of_day&lt;hours&gt;
{
public:
using precision = hours;
time_of_day() = default;
constexpr explicit time_of_day(hours since_midnight) noexcept;
constexpr hours hours() const noexcept;
constexpr explicit operator precision() const noexcept;
constexpr precision to_duration() const noexcept;
constexpr void make24() noexcept;
constexpr void make12() noexcept;
};
</pre>
<pre>
constexpr explicit time_of_day&lt;hours&gt;::time_of_day(hours since_midnight) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
corresponding to <code>since_midnight</code> hours after 00:00:00.
</p>
<p>
<i>Postconditions:</i> <code>hours()</code> returns the integral number of hours
<code>since_midnight</code> is after 00:00:00.
</p>
</blockquote>
<pre>
constexpr hours time_of_day&lt;hours&gt;::hours() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored hour of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit time_of_day&lt;hours&gt;::operator precision() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The number of hours since midnight.
</p>
</blockquote>
<pre>
constexpr precision to_duration() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>precision{*this}</code>.
</p>
</blockquote>
<pre>
constexpr void time_of_day&lt;hours&gt;::make24() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 12-hour time, converts to a 24-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
constexpr void time_of_day&lt;hours&gt;::make12() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 24-hour time, converts to a 12-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;hours&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>t</code> is a 24-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%H00". "%H" will emit a leading 0 for
hours less than 10.
Else <code>t</code> is a 12-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%I%p" according to the C locale, except
that no leading zero is output for hours less than 10.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
<i>Example:</i>
</p>
<blockquote><pre>
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
</pre></blockquote>
</blockquote>
<pre>
tempalte &lt;&gt;
class time_of_day&lt;minutes&gt;
{
public:
using precision = minutes;
time_of_day() = default;
constexpr explicit time_of_day(minutes since_midnight) noexcept;
constexpr hours hours() const noexcept;
constexpr minutes minutes() const noexcept;
constexpr explicit operator precision() const noexcept;
constexpr precision to_duration() const noexcept;
void make24() noexcept;
void make12() noexcept;
};
</pre>
<pre>
constexpr explicit time_of_day&lt;minutes&gt;::time_of_day(minutes since_midnight) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
corresponding to <code>since_midnight</code> minutes after 00:00:00.
</p>
<p>
<i>Postconditions:</i> <code>hours()</code> returns the integral number of hours
<code>since_midnight</code> is after 00:00:00. <code>minutes()</code> returns the
integral number of minutes <code>since_midnight</code> is after (00:00:00 +
<code>hours()</code>).
</p>
</blockquote>
<pre>
constexpr hours time_of_day&lt;minutes&gt;::hours() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored hour of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr minutes time_of_day&lt;minutes&gt;::minutes() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored minute of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit time_of_day&lt;minutes&gt;::operator precision() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The number of minutes since midnight.
</p>
</blockquote>
<pre>
constexpr precision to_duration() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>precision{*this}</code>.
</p>
</blockquote>
<pre>
void time_of_day&lt;minutes&gt;::make24() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 12-hour time, converts to a 24-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
void time_of_day&lt;minutes&gt;::make12() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 24-hour time, converts to a 12-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;minutes&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>t</code> is a 24-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%H:%M". "%H" will emit a leading 0 for
hours less than 10.
Else <code>t</code> is a 12-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%I:%M%p" according to the C locale, except
that no leading zero is output for hours less than 10.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
<i>Example:</i>
</p>
<blockquote><pre>
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
</pre></blockquote>
</blockquote>
<pre>
tempalte &lt;&gt;
class time_of_day&lt;seconds&gt;
{
public:
using precision = seconds;
time_of_day() = default;
constexpr explicit time_of_day(seconds since_midnight) noexcept;
constexpr hours hours() const noexcept;
constexpr minutes minutes() const noexcept;
constexpr seconds seconds() const noexcept;
constexpr explicit operator precision() const noexcept;
constexpr precision to_duration() const noexcept;
void make24() noexcept;
void make12() noexcept;
};
</pre>
<pre>
constexpr explicit time_of_day&lt;seconds&gt;::time_of_day(seconds since_midnight) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
corresponding to <code>since_midnight</code> seconds after 00:00:00.
</p>
<p>
<i>Postconditions:</i> <code>hours()</code> returns the integral number of hours
<code>since_midnight</code> is after 00:00:00. <code>minutes()</code> returns the
integral number of minutes <code>since_midnight</code> is after (00:00:00 +
<code>hours()</code>). <code>seconds()</code> returns the integral number of seconds
<code>since_midnight</code> is after (00:00:00 + <code>hours()</code> +
<code>minutes()</code>).
</p>
</blockquote>
<pre>
constexpr hours time_of_day&lt;seconds&gt;::hours() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored hour of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr minutes time_of_day&lt;seconds&gt;::minutes() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored minute of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr seconds time_of_day&lt;seconds&gt;::seconds() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored second of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit time_of_day&lt;seconds&gt;::operator precision() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The number of seconds since midnight.
</p>
</blockquote>
<pre>
constexpr precision to_duration() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>precision{*this}</code>.
</p>
</blockquote>
<pre>
void time_of_day&lt;seconds&gt;::make24() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 12-hour time, converts to a 24-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
void time_of_day&lt;seconds&gt;::make12() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 24-hour time, converts to a 12-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;seconds&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>t</code> is a 24-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%H:%M%S". "%H" will emit a leading 0 for
hours less than 10.
Else <code>t</code> is a 12-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%I:%M%S%p" according to the C locale, except
that no leading zero is output for hours less than 10.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
<i>Example:</i>
</p>
<blockquote><pre>
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
</pre></blockquote>
</blockquote>
<pre>
tempalte &lt;class Rep, class Period&gt;
class time_of_day&lt;duration&lt;Rep, Period&gt;&gt;
{
public:
using precision = duration&lt;Rep, Period&gt;;
time_of_day() = default;
constexpr explicit time_of_day(precision since_midnight) noexcept;
constexpr hours hours() const noexcept;
constexpr minutes minutes() const noexcept;
constexpr seconds seconds() const noexcept;
constexpr precision subseconds() const noexcept;
constexpr explicit operator precision() const noexcept;
constexpr precision to_duration() const noexcept;
void make24() noexcept;
void make12() noexcept;
};
</pre>
<p>
This specialization shall not exist unless
<code>treat_as_floating_point&lt;Rep&gt;::value</code> is <code>false</code> and
<code>duration&lt;Rep, Period&gt;</code> is not convertible to <code>seconds</code>.
</p>
<pre>
constexpr explicit time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::time_of_day(precision since_midnight) noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
corresponding to <code>since_midnight precision</code> fractional seconds after 00:00:00.
</p>
<p>
<i>Postconditions:</i> <code>hours()</code> returns the integral number of hours
<code>since_midnight</code> is after 00:00:00. <code>minutes()</code> returns the
integral number of minutes <code>since_midnight</code> is after (00:00:00 +
<code>hours()</code>). <code>seconds()</code> returns the integral number of seconds
<code>since_midnight</code> is after (00:00:00 + <code>hours()</code> +
<code>minutes()</code>). <code>subseconds()</code> returns the integral number of
fractional precision seconds <code>since_midnight</code> is after (00:00:00 +
<code>hours()</code> + <code>minutes()</code> + <code>seconds</code>).
</p>
</blockquote>
<pre>
constexpr hours time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::hours() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored hour of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr minutes time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::minutes() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored minute of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr seconds time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::seconds() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored second of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr
duration&lt;Rep, Period&gt;
time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::subseconds() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The stored subsecond of <code>*this</code>.
</p>
</blockquote>
<pre>
constexpr explicit time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::operator precision() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The number of subseconds since midnight.
</p>
</blockquote>
<pre>
constexpr precision to_duration() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>precision{*this}</code>.
</p>
</blockquote>
<pre>
void time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::make24() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 12-hour time, converts to a 24-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
void time_of_day&lt;duration&lt;Rep, Period&gt;&gt;::make12() noexcept;
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>*this</code> is a 24-hour time, converts to a 12-hour time.
Otherwise, no effects.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const time_of_day&lt;duration&lt;Rep, Period&gt;&gt;&amp; t);
</pre>
<blockquote>
<p>
<i>Effects:</i> If <code>t</code> is a 24-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%H:%M%S.%s". "%H" will emit a leading 0 for
hours less than 10. "%s" is not a <code>strftime</code> code and represents the fractional
seconds.
Else <code>t</code> is a 12-hour time, outputs to <code>os</code>
according to the <code>strftime</code> format: "%I:%M%S.%s%p" according to the C locale, except
that no leading zero is output for hours less than 10.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
<p>
<i>Example:</i>
</p>
<blockquote><pre>
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)
</pre></blockquote>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="time.timezone"></a><p class = note>
Add new section [time.timezone] after 23.17.11 Class <code>time_of_day</code> [time.time_of_day]:
</p>
<blockquote>
<h3>23.17.12 Time Zones [time.timezone]</h3>
<p>
This clause creates an API which exposes the IANA Time Zone database, and
interfaces with <code>sys_time</code> and <code>local_time</code>. 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
<code>sys_time</code> and <code>local_time</code>.
</p>
<a name="time.timezone.database"></a><h3>23.17.12.1 The time zone database [time.timezone.database]</h3>
<p>
The following data structure is the time zone database, and the following
functions access it.
</p>
<pre>
struct tzdb
{
string version;
vector&lt;time_zone&gt; zones;
vector&lt;link&gt; links;
vector&lt;leap&gt; leaps;
const time_zone* locate_zone(string_view tz_name) const;
const time_zone* current_zone() const;
};
class tzdb_list
{
std::atomic&lt;tzdb*&gt; head_{nullptr}; // exposition only
public:
class const_iterator;
const tzdb& front() const noexcept;
const_iterator erase_after(const_iterator p) noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
};
</pre>
<p>
The <code>tzdb_list</code> database is a singleton. Access is
granted to it via the <code>get_tzdb_list()</code> function which
returns a reference to it. However this access is only needed for
those applications which need to have long uptimes and have a need to
update the time zone database while running. Other applications can
implicitly access the <code>front()</code> of this list via the
<i>read-only</i> namespace scope functions <code>get_tzdb()</code>,
<code>locate_zone()</code> and <code>current_zone()</code>. Each
<code>vector</code> in <code>tzdb</code> is sorted to enable fast
lookup. One can iterate over and inspect this database. And
multiple versions of the database can be used at once, via the
<code>tzdb_list</code>.
</p>
<pre>
const time_zone* tzdb::locate_zone(string_view tz_name) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> If a <code>time_zone</code> is found for which
<code>name() == tz_name</code>, returns a pointer to that <code>time_zone</code>.
Otherwise if a <code>link</code> is found where <code>tz_name == link.name()</code>,
then a pointer is returned to the <code>time_zone</code> for which
<code>zone.name() == link.target()</code> [<i>Note:</i> A <code>link</code> is an
alternative name for a <code>time_zone</code>. <i>&mdash; end note</i>]
</p>
<p>
<i>Throws:</i> If a <code>const time_zone*</code> can not be found as
described in the <i>Returns</i> clause, throws a
<code>runtime_error</code>. [<i>Note:</i> On non-exceptional return,
the return value is <i>always</i> a pointer to a valid
<code>time_zone</code>. <i>&mdash; end note</i>]
</p>
</blockquote>
<pre>
const time_zone* tzdb::current_zone() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>const time_zone*</code> referring to the time zone which your
computer has set as its local time zone.
</p>
</blockquote>
<pre>
list&lt;tzdb&gt;&amp; get_tzdb_list();
</pre>
<blockquote>
<p>
<i>Effects:</i> If this is the first access to the database, will
initialize the database. If this call initializes the database, the
resulting database will be a <code>tzdb_list</code> which holds a
single initialized <code>tzdb</code>.
</p>
<p>
<i>Returns:</i> A reference to the database.
</p>
<p>
<i>Thread Safety:</i> It is safe to call this function from multiple threads at
one time.
</p>
<p>
<i>Throws:</i> <code>runtime_error</code> if for any reason a
reference can not be returned to a valid
<code>list&lt;tzdb&gt;&amp;</code> containing one or more valid
<code>tzdb</code>.
</p>
</blockquote>
<pre>
const tzdb&amp; get_tzdb();
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>get_tzdb_list().front()</code>.
</p>
</blockquote>
<pre>
const time_zone* locate_zone(string_view tz_name);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>get_tzdb().locate_zone(tz_name)</code> which
will initialize the timezone database if this is the first reference
to the database.
</p>
</blockquote>
<pre>
const time_zone* current_zone();
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>get_tzdb().current_zone()</code>.
</p>
</blockquote>
<code>tzdb_list::const_iterator</code> is a constant iterator which meets the
forward iterator requirements and has a value type of <code>tzdb</code>.
<pre>
const tzdb&amp; tzdb_list::front() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>*head_</code>.
</p>
<p>
<i>Remarks:</i> this operation is thread safe with respect to <code>reload_tzdb()</code>.
[<i>Note:</i> <code>reload_tzdb()</code> pushes a new <code>tzdb</code> onto the front
of this container. &mdash; <i>end note</i>]
</p>
</blockquote>
<pre>
tzdb::const_iterator tzdb::erase_after(const_iterator p) noexcept;
</pre>
<blockquote>
<p>
<i>Requires:</i> The iterator following <code>p</code> is dereferenceable.
</p>
<p>
<i>Effects:</i> Erases the <code>tzdb</code> referred to by the iterator following
<code>p</code>.
</p>
<p>
<i>Returns:</i> An iterator pointing to the element following the one that was erased,
or <code>end()</code> if no such element exists.
</p>
<p>
<i>Remarks:</i> No pointers, references or iterators are invalidated except those referring
to the erased <code>tzdb</code>.
</p>
<p>
<i>Note:</i> It is not possible to erase the <code>tzdb</code> referred to by
<code>begin()</code>.
</p>
</blockquote>
<pre>
tzdb::const_iterator tzdb::begin() const noexcept;
</pre>
<blockquote>
<i>Returns:</i> An iterator referring to the first <code>tzdb</code> in the container.
</blockquote>
<pre>
tzdb::const_iterator tzdb::end() const noexcept;
</pre>
<blockquote>
<i>Returns:</i> An iterator referring to the position one past the
last <code>tzdb</code> in the container.
</blockquote>
<pre>
tzdb::const_iterator tzdb::cbegin() const noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>begin()</code>.
</blockquote>
<pre>
tzdb::const_iterator tzdb::cend() const noexcept;
</pre>
<blockquote>
<i>Returns:</i> <code>end()</code>.
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
<a name="time.timezone.database.remote"></a><h3>23.17.12.1.1 Remote time zone database support [time.timezone.database.remote]</h3>
<p>
The <i>local</i> time zone database is that supplied by the implementation when the
application first accesses the database, for example via <code>current_zone()</code>.
While the application is running, the implementation may choose to update the time
zone database. This update shall not impact the application in any way unless the
application calls the functions in this section. This potentially updated time zone
database is referred to as the <i>remote</i> time zone database.
</p>
<pre>
const tzdb&amp; reload_tzdb();
</pre>
<blockquote>
<p>
<i>Effects:</i> This function first checks the version of the remote time zone database.
If the version of the local and remote databases are the same, there are no effects.
Otherwise the remote database is pushed to the front of
the <code>tzdb_list</code> accessed by <code>get_tzdb_list()</code>.
</p>
<p>
<i>Returns:</i> <code>get_tzdb_list().front()</code>.
</p>
<p>
<i>Remarks:</i> No pointers, references or iterators are invalidated.
</p>
<p>
<i>Thread Safety:</i> This function is thread safe with respect to
<code>get_tzdb_list().front()</code> and <code>get_tzdb_list().erase_after()</code>.
</p>
<p>
<i>Throws:</i> <code>runtime_error</code> if for any reason a reference can not
be returned to a valid <code>tzdb</code>.
</p>
</blockquote>
<pre>
string remote_version();
</pre>
<blockquote>
<p>
<i>Returns:</i> The latest remote database version. If the remote
version s not available, the empty string is returned.
</p>
<p>
<i>Note:</i> If non-empty, this can be compared with <code>get_tzdb().version</code> to
discover if the local and remote databases are equivalent.
</p>
</blockquote>
<a name="time.timezone.exception"></a><h3>23.17.12.2 Exception classes [time.timezone.exception]</h3>
<p>
<code>nonexistent_local_time</code> is thrown when one attempts to convert a
non-existent <code>local_time</code> to a <code>sys_time</code> without specifying
<code>choose::earliest</code> or <code>choose::latest</code>.
</p>
<pre>
class nonexistent_local_time
: public runtime_error
{
public:
// Construction is undocumented
};
</pre>
<p>
[<i>Example:</i>
</p>
<blockquote>
<pre>
#include "tz.h"
#include &lt;iostream&gt;
int
main()
{
using namespace std::chrono;
try
{
auto zt = zoned_time{"America/New_York", local_days{sun[2]/mar/2016} + 2h + 30min};
}
catch (const nonexistent_local_time&amp; e)
{
std::cout &lt;&lt; e.what() &lt;&lt; '\n';
}
}
</pre>
<p>
Which outputs:
</p>
<pre>
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
</pre>
</blockquote>
<p>
<i>&mdash; end example:</i>]
</p>
<p>
<code>ambiguous_local_time</code> is thrown when one attempts to convert an ambiguous
<code>local_time</code> to a <code>sys_time</code> without specifying
<code>choose::earliest</code> or <code>choose::latest</code>.
</p>
<pre>
class ambiguous_local_time
: public runtime_error
{
public:
// Construction is undocumented
};
</pre>
<p>
[<i>Example:</i>
</p>
<blockquote>
<pre>
#include "tz.h"
#include &lt;iostream&gt;
int
main()
{
using namespace std::chrono;
try
{
auto zt = zoned_time{"America/New_York", local_days{sun[1]/nov/2016} + 1h + 30min};
}
catch (const ambiguous_local_time&amp; e)
{
std::cout &lt;&lt; e.what() &lt;&lt; '\n';
}
}
</pre>
<p>
Which outputs:
</p>
<pre>
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
</pre>
</blockquote>
<p>
<i>&mdash; end example:</i>]
</p>
<a name="time.timezone.info"></a><h3>23.17.12.3 Information classes [time.timezone.info]</h3>
<p>
A <code>sys_info</code> structure can be obtained from the combination of a <code>time_zone</code> and
either a <code>sys_time</code>, or <code>local_time</code>. It can also be obtained
from a <code>zoned_time</code> which is effectively a <code>pair</code> of
a <code>time_zone</code> and <code>sys_time</code>.
</p>
<p>
This structure represents a lower-level API. Typical conversions from
<code>sys_time</code> to <code>local_time</code> will use this structure
<i>implicitly</i>, not <i>explicitly</i>.
</p>
<pre>
struct sys_info
{
sys_seconds begin;
sys_seconds end;
seconds offset;
minutes save;
string abbrev;
};
</pre>
<p>
The <code>begin</code> and <code>end</code> fields indicate that for the
associated <code>time_zone</code> and <code>time_point</code>, the
<code>offset</code> and <code>abbrev</code> are in effect in the range
<code>[begin, end)</code>. This information can be used to efficiently iterate the
transitions of a <code>time_zone</code>.
</p>
<p>
The <code>offset</code> field indicates the UTC offset in effect for the associated
<code>time_zone</code> and <code>time_point</code>. The relationship between
<code>local_time</code> and <code>sys_time</code> is:
</p>
<pre>
offset = local_time - sys_time
</pre>
<p>
The <code>save</code> field is "extra" information not normally needed for
conversion between <code>local_time</code> and <code>sys_time</code>. If
<code>save != 0min</code>, this <code>sys_info</code> is said to be on "daylight
saving" time, and <code>offset - save</code> suggests what this
<code>time_zone</code> <i>might</i> 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 <code>time_zone</code> with a
<code>time_point</code> that returns an <code>sys_info</code> where
<code>save == 0min</code>. There is no guarantee what <code>time_point</code> might return such
an <code>sys_info</code> except that it is guaranteed <i>not</i> to be in the range
<code>[begin, end)</code> (if <code>save != 0min</code> for this <code>sys_info</code>).
</p>
<p>
The <code>abbrev</code> field indicates the current abbreviation used for the
associated <code>time_zone</code> and <code>time_point</code>. Abbreviations
are not unique among the <code>time_zone</code>s, and so one can not reliably
map abbreviations back to a <code>time_zone</code> and UTC offset.
</p>
<p>
A <code>sys_info</code> can be streamed out in an unspecified format:
</p>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_info&amp; r);
</pre>
<p>
A <code>local_info</code> structure represents a lower-level API. Typical conversions from
<code>local_time</code> to <code>sys_time</code> will use this structure
<i>implicitly</i>, not <i>explicitly</i>.
</p>
<pre>
struct local_info
{
enum {unique, nonexistent, ambiguous} result;
sys_info first;
sys_info second;
};
</pre>
<p>
When a <code>local_time</code> to <code>sys_time</code> conversion is unique,
<code>result == unique</code>, <code>first</code> will be filled out with the
correct <code>sys_info</code> and <code>second</code> will be zero-initialized.
If the conversion stems from a nonexistent <code>local_time</code> then
<code>result == nonexistent</code>, <code>first</code> will be filled out with
the <code>sys_info</code> that ends just prior to the <code>local_time</code>
and <code>second</code> will be filled out with the <code>sys_info</code> that
begins just after the <code>local_time</code>. If the conversion stems from an
ambiguous <code>local_time</code> then <code>result == ambiguous</code>,
<code>first</code> will be filled out with the <code>sys_info</code> that ends
just after the <code>local_time</code> and <code>second</code> will be filled
out with the <code>sys_info</code> that starts just before the
<code>local_time</code>.
</p>
<p>
A <code>local_info</code> can be streamed out in an unspecified format:
</p>
<pre>
template &lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const local_info&amp; r);
</pre>
<a name="time.timezone.time_zone"></a><h3>23.17.12.4 Class <code>time_zone</code> [time.timezone.time_zone]</h3>
<p>
A <code>time_zone</code> represents all time zone transitions for a specific geographic
area. <code>time_zone</code> construction is undocumented, and done during
the database initialization. You can gain <code>const</code> access to a
<code>time_zone</code> via functions such as <code>locate_zone</code>.
</p>
<pre>
class time_zone
{
public:
time_zone(const time_zone&amp;) = delete;
time_zone&amp; operator=(const time_zone&amp;) = delete;
const string&amp; name() const noexcept;
template &lt;class Duration&gt; sys_info get_info(sys_time&lt;Duration&gt; st) const;
template &lt;class Duration&gt; local_info get_info(local_time&lt;Duration&gt; tp) const;
template &lt;class Duration&gt;
sys_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
to_sys(local_time&lt;Duration&gt; tp) const;
template &lt;class Duration&gt;
sys_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
to_sys(local_time&lt;Duration&gt; tp, choose z) const;
template &lt;class Duration&gt;
local_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
to_local(sys_time&lt;Duration&gt; tp) const;
};
bool operator==(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator!=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&lt; (const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&gt; (const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&lt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
bool operator&gt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<pre>
const string&amp; time_zone::name() const noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> The name of the <code>time_zone</code>.
</p>
<p>
<i>Example:</i> "America/New_York".
</p>
<p>
<i>Note:</i> Here is an unofficial list of <code>time_zone</code> names:
<a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">https://en.wikipedia.org/wiki/List_of_tz_database_time_zones</a>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; sys_info time_zone::get_info(sys_time&lt;Duration&gt; st) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>sys_info</code> <code>i</code> for which <code>st</code> is in the
range <code>[i.begin, i.end)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; local_info time_zone::get_info(local_time&lt;Duration&gt; tp) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>local_info</code> for <code>tp</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
time_zone::to_sys(local_time&lt;Duration&gt; tp) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>sys_time</code> that is at least as fine as <code>seconds</code>,
and will be finer if the argument <code>tp</code> has finer precision. This
<code>sys_time</code> is the UTC equivalent of <code>tp</code> according to the rules
of this <code>time_zone</code>.
</p>
<p>
<i>Throws:</i> If the conversion from <code>tp</code> to a <code>sys_time</code>
is ambiguous, throws <code>ambiguous_local_time</code>. If the conversion from
<code>tp</code> to a <code>sys_time</code> is nonexistent, throws
<code>nonexistent_local_time</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
sys_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
time_zone::to_sys(local_time&lt;Duration&gt; tp, choose z) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> A <code>sys_time</code> that is at least as fine as
<code>seconds</code>, and will be finer if the argument <code>tp</code> has
finer precision. This <code>sys_time</code> is the UTC equivalent of
<code>tp</code> according to the rules of this <code>time_zone</code>. If the
conversion from <code>tp</code> to a <code>sys_time</code> is ambiguous, returns
the earlier <code>sys_time</code> if <code>z == choose::earliest</code>, and
returns the later <code>sys_time</code> if <code>z == choose::latest</code>. If
the <code>tp</code> represents a non-existent time between two UTC
<code>time_point</code>s, then the two UTC <code>time_point</code>s will be the
same, and that UTC <code>time_point</code> will be returned.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt;
local_time&lt;typename common_type&lt;Duration, seconds&gt;::type&gt;
time_zone::to_local(sys_time&lt;Duration&gt; tp) const;
</pre>
<blockquote>
<p>
<i>Returns:</i> The <code>local_time</code> associated with <code>tp</code> and this
<code>time_zone</code>.
</p>
</blockquote>
<pre>
bool operator==(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.name() == y.name()</code>.
</p>
</blockquote>
<pre>
bool operator!=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
bool operator&lt;(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.name() &lt; y.name()</code>.
</p>
</blockquote>
<pre>
bool operator&gt;(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
bool operator&lt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
bool operator&gt;=(const time_zone&amp; x, const time_zone&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<a name="time.timezone.zoned_traits"></a><h3>23.17.12.5 Class <code>zoned_traits</code> [time.timezone.zoned_traits]</h3>
<p>
<code>zoned_traits</code> provides a means for customizing the behavior of
<code>zoned_time&lt;Duration, TimeZonePtr&gt;</code> for the
<code>zoned_time</code> default constructor, and constructors taking
<code>string_view</code>. A specialization for <code>const time_zone*</code>
is provided by the implementation.
</p>
<pre>
template &lt;class T&gt; struct zoned_traits {};
template &lt;&gt;
struct zoned_traits&lt;const time_zone*&gt;
{
static const time_zone* default_zone();
static const time_zone* locate_zone(string_view name);
};
</pre>
<pre>
static const time_zone* zoned_traits&lt;const time_zone*&gt;::default_zone();
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>std::chrono::locate_zone("UTC")</code>.
</p>
</blockquote>
<pre>
static const time_zone* zoned_traits&lt;const time_zone*&gt;::locate_zone(string_view name);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>std::chrono::locate_zone(name)</code>.
</p>
</blockquote>
<a name="time.timezone.zoned_time"></a><h3>23.17.12.6 Class <code>zoned_time</code> [time.timezone.zoned_time]</h3>
<p>
<code>zoned_time</code> represents a logical paring of <code>time_zone</code> and a
<code>time_point</code> with precision <code>Duration</code>.
</p>
<pre>
template &lt;class Duration, class TimeZonePtr = const time_zone*&gt;
class zoned_time
{
public:
using duration = common_type_t&lt;Duration, seconds&gt;;
private:
TimeZonePtr zone_; // exposition only
sys_time&lt;duration&gt; tp_; // exposition only
public:
zoned_time();
zoned_time(const zoned_time&amp;) = default;
zoned_time&amp; operator=(const zoned_time&amp;) = default;
zoned_time(const sys_time&lt;Duration&gt;&amp; st);
explicit zoned_time(TimeZonePtr z);
explicit zoned_time(string_view name);
template &lt;class Duration2&gt;
zoned_time(const zoned_time&lt;Duration2&gt;&amp; zt) noexcept;
zoned_time(TimeZonePtr z, const sys_time&lt;Duration&gt;&amp; st);
zoned_time(string_view name, const sys_time&lt;Duration&gt;&amp; st);
zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp);
zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp);
zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp, choose c);
zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp, choose c);
zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; zt);
zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; zt);
zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; zt, choose);
zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; zt, choose);
zoned_time&amp; operator=(const sys_time&lt;Duration&gt;&amp; st);
zoned_time&amp; operator=(const local_time&lt;Duration&gt;&amp; ut);
operator sys_time&lt;duration&gt;() const;
explicit operator local_time&lt;duration&gt;() const;
TimeZonePtr get_time_zone() const;
local_time&lt;duration&gt; get_local_time() const;
sys_time&lt;duration&gt; get_sys_time() const;
sys_info get_info() const;
};
template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool
operator==(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool
operator!=(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
const zoned_time&lt;Duration, TimeZonePtr&gt;& t);
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp);
zoned_time()
-&gt; zoned_time&lt;seconds&gt;;
template &lt;class Duration&gt;
zoned_time(sys_time&lt;Duration&gt;)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;;
template &lt;class TimeZonePtr, class Duration&gt;
zoned_time(TimeZonePtr, sys_time&lt;Duration&gt;)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;, TimeZonePtr&gt;;
template &lt;class TimeZonePtr, class Duration&gt;
zoned_time(TimeZonePtr, local_time&lt;Duration&gt;, choose = choose::earliest)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;, TimeZonePtr&gt;;
template &lt;class TimeZonePtr, class Duration&gt;
zoned_time(TimeZonePtr, zoned_time&lt;Duration&gt;, choose = choose::earliest)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;, TimeZonePtr&gt;;
zoned_time(string_view)
-&gt; zoned_time&lt;seconds&gt;;
template &lt;class Duration&gt;
zoned_time(string_view, sys_time&lt;Duration&gt;)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;;
template &lt;class Duration&gt;
zoned_time(string_view, local_time&lt;Duration&gt;, choose = choose::earliest)
-&gt; zoned_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;;
</pre>
<p>
An invariant of <code>zoned_time&lt;Duration&gt;</code> is that it always refers
to a valid <code>time_zone</code>, and represents a point in time that exists
and is not ambiguous.
</p>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time();
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
the expression <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> is well formed.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> and
default constructing <code>tp_</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(const zoned_time&amp;) = default;
zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration&gt;::operator=(const zoned_time&amp;) = default;
</pre>
<blockquote>
<p>
The copy members transfer the associated <code>time_zone</code> from the source
to the destination. After copying, source and destination compare equal. If
<code>Duration</code> has <code>noexcept</code> copy members, then
<code>zoned_time&lt;Duration&gt;</code> has <code>noexcept</code> copy
members.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
the expression <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> is well formed.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> and
<code>tp_</code> with <code>st</code>.
</p>
</blockquote>
<pre>
explicit zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> initializing <code>zone_</code>
with <code>std::move(z)</code>.
</p>
</blockquote>
<pre>
explicit zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
the expression <code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(string_view{})</code>
is well formed and <code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(string_view{})</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>
and default constructing <code>tp_</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration2, TimeZonePtr&gt;
zoned_time&lt;Duration&gt;::zoned_time(const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y) noexcept;
</pre>
<blockquote>
<p>
<i>Remarks:</i> Does not participate in overload resolution unless
<code>sys_time&lt;Duration2&gt;</code> is implicitly convertible to
<code>sys_time&lt;Duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>x</code> such that
<code>x == y</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>st</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code> and <code>st</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), st}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>declval&lt;TimeZonePtr&amp;&gt;()-&gt;to_sys(local_time&lt;Duration&gt;{})</code>
is convertible to <code>sys_time&lt;duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>zone_-&gt;to_sys(t)</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code> and <code>tp</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), tp}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp, choose c);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>decltype(declval&lt;TimeZonePtr&amp;&gt;()-&gt;to_sys(local_time&lt;Duration&gt;{}, choose::earliest))</code>
is convertible to <code>sys_time&lt;duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>zone_-&gt;to_sys(t, c)</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp, choose c);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>,
<code>local_time&lt;Duration&gt;</code> and <code>choose</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with
<code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), tp, c}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; y);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>z.tp_</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; y);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>
and <code>zoned_time</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with
<code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), y}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; y, choose);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{z, y}</code>.
</p>
<p>
<i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; y, choose c);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>, <code>zoned_time</code>,
and <code>choose</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), y, c}</code>.
</p>
<p>
<i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration, TimeZonePtr&gt;::operator=(const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Effects:</i> After assignment <code>get_sys_time() == st</code>. This assignment has
no effect on the return value of <code>get_time_zone()</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration, TimeZonePtr&gt;::operator=(const local_time&lt;Duration&gt;&amp; lt);
</pre>
<blockquote>
<p>
<i>Effects:</i> After assignment <code>get_local_time() == lt</code>. This assignment has
no effect on the return value of <code>get_time_zone()</code>.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::operator sys_time&lt;duration&gt;() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>get_sys_time()</code>.
</p>
</blockquote>
<pre>
explicit zoned_time&lt;Duration, TimeZonePtr&gt;::operator local_time&lt;duration&gt;() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>get_local_time()</code>.
</p>
</blockquote>
<pre>
TimeZonePtr zoned_time&lt;Duration, TimeZonePtr&gt;::get_time_zone() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>zone_</code>.
</p>
</blockquote>
<pre>
local_time&lt;typename zoned_time&lt;Duration, TimeZonePtr&gt;::duration&gt; zoned_time&lt;Duration, TimeZonePtr&gt;::get_local_time() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>zone_-&gt;to_local(tp_)</code>.
</p>
</blockquote>
<pre>
sys_time&lt;typename zoned_time&lt;Duration, TimeZonePtr&gt;::duration&gt; zoned_time&lt;Duration, TimeZonePtr&gt;::get_sys_time() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>tp_</code>.
</p>
</blockquote>
<pre>
sys_info zoned_time&lt;Duration, TimeZonePtr&gt;::get_info() const;
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>zone_-&gt;get_info(tp_)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool
operator==(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.zone_ == y.zone_ &amp;&amp; x.tp_ == y.tp_</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool
operator!=(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&
operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;& os,
const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; t)
</pre>
<blockquote>
<p>
<i>Effects:</i> Streams <code>t</code> to <code>os</code> using the format "%F %T %Z"
and the value returned from <code>t.get_local_time()</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<pre>
template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
basic_ostream&lt;charT, traits&gt;&amp;
to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp);
</pre>
<blockquote>
<p>
<i>Effects:</i> First obtains a <code>sys_info</code> via <code>tp.get_info()</code>
which for exposition purposes will be referred to as <code>info</code>. Then calls
<code>to_stream(os, fmt, tp.get_local_time(), &amp;info.abbrev, &amp;info.offset)</code>.
</p>
<p>
<i>Returns:</i> <code>os</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<p class = note>
Add a new section 23.17.12.7 leap [time.timezone.leap]:
</p>
<blockquote>
<a name="time.timezone.leap"></a><h3>23.17.12.7 class <code>leap</code> [time.timezone.leap]</h3>
<pre>
class leap
{
sys_seconds date_; // exposition only
public:
leap(const leap&amp;) = default;
leap&amp; operator=(const leap&amp;) = default;
// Undocumented constructors
sys_seconds date() const;
};
bool operator==(const leap&amp; x, const leap&amp; y);
bool operator!=(const leap&amp; x, const leap&amp; y);
bool operator&lt; (const leap&amp; x, const leap&amp; y);
bool operator&gt; (const leap&amp; x, const leap&amp; y);
bool operator&lt;=(const leap&amp; x, const leap&amp; y);
bool operator&gt;=(const leap&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator==(const const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator==(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator!=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator!=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&lt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&lt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&gt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&gt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&lt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&lt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
template &lt;class Duration&gt; bool operator&gt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y);
template &lt;class Duration&gt; bool operator&gt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y);
</pre>
<p>
<code>leap</code> is a copyable class that is constructed and stored in the time zone
database when initialized. You can explicitly convert it to a <code>sys_seconds</code>
with the member function <code>date()</code> and that will be the date of the leap second
insertion. <code>leap</code> is equality and less-than comparable, both with itself, and
with <code>sys_time&lt;Duration&gt;</code>.
</p>
<p>
[<i>Example:</i>
</p>
<blockquote>
<p>
Here is the date of all of the leap second insertions at the time of this writing:
</p>
<pre>
for (auto&amp; l : get_tzdb().leaps)
cout &lt;&lt; l.date() &lt;&lt; '\n';
</pre>
<p>
which outputs:
</p>
<pre>
1972-07-01 00:00:00
1973-01-01 00:00:00
1974-01-01 00:00:00
1975-01-01 00:00:00
1976-01-01 00:00:00
1977-01-01 00:00:00
1978-01-01 00:00:00
1979-01-01 00:00:00
1980-01-01 00:00:00
1981-07-01 00:00:00
1982-07-01 00:00:00
1983-07-01 00:00:00
1985-07-01 00:00:00
1988-01-01 00:00:00
1990-01-01 00:00:00
1991-01-01 00:00:00
1992-07-01 00:00:00
1993-07-01 00:00:00
1994-07-01 00:00:00
1996-01-01 00:00:00
1997-07-01 00:00:00
1999-01-01 00:00:00
2006-01-01 00:00:00
2009-01-01 00:00:00
2012-07-01 00:00:00
2015-07-01 00:00:00
2017-01-01 00:00:00
</pre>
</blockquote>
<p>
&mdash; <i>end example</i>]
</p>
<pre>
sys_seconds leap::date() const
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>date_</code>.
</p>
</blockquote>
<pre>
bool operator==(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.date() == y.date()</code>.
</p>
</blockquote>
<pre>
bool operator!=(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
bool operator&lt;(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.date() &lt; y.date()</code>.
</p>
</blockquote>
<pre>
bool operator&gt;(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
bool operator&lt;=(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
bool operator&gt;=(const leap&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator==(const const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.date() == y</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator==(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y == x</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator!=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator!=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&lt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.date() &lt; y</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&lt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x &lt; y.date()</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&gt; (const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&gt; (const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&lt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&lt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&gt;=(const leap&amp; x, const sys_time&lt;Duration&gt;&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<pre>
template &lt;class Duration&gt; bool operator&gt;=(const sys_time&lt;Duration&gt;&amp; x, const leap&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<p class = note>
Add a new section 23.17.12.8 link [time.timezone.link]:
</p>
<blockquote>
<a name="time.timezone.link"></a><h3>23.17.12.8 class <code>link</code> [time.timezone.link]</h3>
<pre>
class link
{
private:
std::string name_; // exposition only
std::string target_; // exposition only
public:
link(const link&amp;) = default;
link&amp; operator=(const link&amp;) = default;
// Undocumented constructors
const string&amp; name() const;
const string&amp; target() const;
};
bool operator==(const link&amp; x, const link&amp; y);
bool operator!=(const link&amp; x, const link&amp; y);
bool operator&lt; (const link&amp; x, const link&amp; y);
bool operator&gt; (const link&amp; x, const link&amp; y);
bool operator&lt;=(const link&amp; x, const link&amp; y);
bool operator&gt;=(const link&amp; x, const link&amp; y);
</pre>
<p>
A <code>link</code> is an alternative name for a <code>time_zone</code>. The alternative
name is <code>name()</code>. The name of the <code>time_zone</code> for which this is
an alternative name is <code>target()</code>. <code>link</code>s will be constructed
for you when the time zone database is initialized.
</p>
<pre>
const string&amp; link::name() const
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>name_</code>.
</p>
</blockquote>
<pre>
const string&amp; link::target() const
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>target_</code>.
</p>
</blockquote>
<pre>
bool operator==(const link&amp; x, const link&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.name() == y.name()</code>.
</p>
</blockquote>
<pre>
bool operator!=(const link&amp; x, const link&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x == y)</code>.
</p>
</blockquote>
<pre>
bool operator&lt; (const link&amp; x, const link&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>x.name() &lt; y.name()</code>.
</p>
</blockquote>
<pre>
bool operator&gt; (const link&amp; x, const link&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>y &lt; x</code>.
</p>
</blockquote>
<pre>
bool operator&lt;=(const link&amp; x, const link&amp; y)
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(y &lt; x)</code>.
</p>
</blockquote>
<pre>
bool operator&gt;=(const link&amp; x, const link&amp; y);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>!(x &lt; y)</code>.
</p>
</blockquote>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="fs.filesystem.syn"></a><p class = note>
Modify the synopsis in section [fs.filesystem.syn] 30.10.6 Header <code>&lt;filesystem&gt;</code> synopsis:
</p>
<blockquote>
<pre>
using file_time_type = chrono::time_point&lt;<del><i>trivial-clock</i></del> <ins>chrono::file_clock</ins>&gt;;
</pre>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="thread.req.paramname"></a><p class = note>
Add to [thread.req.paramname] 33.2.1 Template parameter names:
</p>
<blockquote>
<p>
1 Throughout this Clause, the names of template parameters are used to express type
requirements. If a template parameter is named <code>Predicate</code>,
<code>operator()</code> applied to the template argument shall return a value that is
convertible to <code>bool</code>. <ins>A program that instantiates a template with a
template parameter named <code>Clock</code> with a type for which
<code>chrono::is_clock_v&lt;Clock&gt;</code> is <code>false</code>, is ill-formed.</ins>
</p>
<p>
<a href="#Wording">Back to TOC</a>
</p>
</blockquote>
<a name="Acknowledgements"></a><h2>Acknowledgements</h2>
<p>
A database parser is nothing without its database. I would like to thank the founding
contributor of the <a href="http://www.iana.org/time-zones">IANA Time Zone Database</a>
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.
</p>
<p>
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. Thank you Daniel Kr&uuml;gler for the
incredibly thorough review. Thank you Tomasz Kami&nacute;ski for the very helpful
changes to the proposed wording.
</p>
<p>
And I would also especially like to thank the
<a href="https://github.com/HowardHinnant/date/graphs/contributors">growing list of
contributors to this library.</a>
</p>
<a name="References"></a><h2>References</h2>
<ol>
<li>
<a name="refcc"></a><p>
N. Dershowitz and E. Reingold, <i>Calendrical Calculations 3rd ed.</i>, Cambridge
University Press 2008.
</p>
</li>
</ol>
</body>
</html>