mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 16:41:04 +08:00
8427 lines
246 KiB
HTML
8427 lines
246 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>date</title>
|
|
|
|
<style>
|
|
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;
|
|
}
|
|
ins {color:#00A000}
|
|
del {color:#A00000}
|
|
code {white-space:pre;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<address align=right>
|
|
<br/>
|
|
<br/>
|
|
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/>
|
|
2018-03-03<br/>
|
|
</address>
|
|
<hr/>
|
|
<h1 align=center><code>date</code></h1>
|
|
|
|
<h2>Contents</h2>
|
|
|
|
<ul>
|
|
<li><a href="https://github.com/HowardHinnant/date">github link</a></li>
|
|
<li><a href="#Introduction">Introduction</a></li>
|
|
<li><a href="#Implementation">Implementation</a></li>
|
|
<li><a href="#Overview">Overview</a></li>
|
|
<li><a href="#range">Range of Validity</a></li>
|
|
<li><a href="#Reference">Reference</a></li>
|
|
<li><a href="#Installation">Installation</a></li>
|
|
</ul>
|
|
|
|
<a name="Introduction"></a><h2>Introduction</h2>
|
|
|
|
<p>
|
|
This paper fully documents a date and time library for use with C++11 and C++14.
|
|
</p>
|
|
|
|
<a name="Implementation"></a><h2>Implementation</h2>
|
|
|
|
<p>
|
|
This entire library is implemented in a single header:
|
|
<a href="https://github.com/HowardHinnant/date/blob/master/include/date/date.h">date.h</a> and is
|
|
open source.
|
|
</p>
|
|
|
|
<p>
|
|
It uses the algorithms from
|
|
<a href="http://howardhinnant.github.io/date_algorithms.html"><code>chrono</code>-Compatible Low-Level Date Algorithms</a>.
|
|
If you want detailed explanations of the algorithms, go there.
|
|
</p>
|
|
|
|
<p>
|
|
It performs best with C++14, which has vastly improved <code>constexpr</code> rules.
|
|
However, the library will auto-adopt to C++11, sacrificing several <code>constexpr</code>
|
|
declarations. In C++11, this will effectively transfer some computations that should be
|
|
done at compile-time to run-time. Porting to C++98/03 has not been attempted.
|
|
</p>
|
|
|
|
<a name="Overview"></a><h2>Overview</h2>
|
|
|
|
<p>
|
|
Here is an overview of all the types we are going to talk about at some point. They are
|
|
all fully covered in the reference section. This link is just there to give you a view
|
|
of everything on one quick page so that you don't get lost or overwhelmed. Many of these
|
|
types will never need to be explicitly named in typical use cases.
|
|
</p>
|
|
|
|
<blockquote>
|
|
<a href="date_types.jpeg">date_types.jpeg</a>
|
|
</blockquote>
|
|
|
|
<p>
|
|
This library builds date and date/time support on top of the <code><chrono></code>
|
|
library. However it does not support timezones nor leap seconds. A
|
|
<a href="tz.html">separate library is provided</a>, built on top of this one, for timezone
|
|
and leap second support. Thus you only pay for such support if you need it.
|
|
</p>
|
|
|
|
<h3>Major Concepts</h3>
|
|
|
|
<p>
|
|
A date on a calendar is a time point with a resolution of one day. This is not
|
|
conceptually different from <code>std::chrono::system_clock::time_point</code> which is a
|
|
time point with a resolution of <code>std::chrono::system_clock::period</code> (typically
|
|
on the order of a microsecond or nanosecond). Time points are divided into two basic
|
|
types:
|
|
</p>
|
|
|
|
<ol>
|
|
<li>serial-based</li>
|
|
<li>field-based</li>
|
|
</ol>
|
|
|
|
<p>
|
|
This terminology is gratefully borrowed from
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3344.pdf">N3344</a>. In
|
|
short, a <i>serial-based</i> time point stores a single count of time durations from some epoch.
|
|
<code>std::chrono::system_clock::time_point</code> is an example of a <i>serial-based</i>
|
|
time point. A count of days from some epoch is also a <i>serial-based</i> time point.
|
|
A <i>field-based</i> time point represents the same concept, but with several fields that
|
|
are typically used for human consumption. For example one might represent the time of day
|
|
with the number of seconds since midnight (<i>serial-based</i>), or with a structure such
|
|
as <code>{hours, minutes, seconds}</code> since midnight (<i>field-based</i>). Similarly
|
|
one can represent a date with a count of days, or with a <code>{year, month, day}</code>
|
|
structure. Both representations are useful, and each has its strengths and weaknesses.
|
|
</p>
|
|
|
|
<h3>Major Types</h3>
|
|
|
|
<p>
|
|
This library is composed of many types. But here are the most important ones:
|
|
</p>
|
|
|
|
<ol>
|
|
<li><code>sys_days</code>: A count of days since <code>system_clock</code>'s epoch. This
|
|
is a serial-based time point with a resolution of one day.</li>
|
|
<li><code>year_month_day</code>: A type that holds a year (e.g. 2015), a month
|
|
(encoded as 1 thru 12), and a day (encoded as 1 thru 31). This is a field-based time
|
|
point with a resolution of one day.</li>
|
|
<li><code>year_month_weekday</code>: A type that holds a year (e.g. 2015), a month
|
|
(encoded as 1 thru 12), a day of the week (encoded as 0 thru 6), and an index in the range
|
|
[1, 5] indicating if this is the first, second, etc. weekday of the indicated month. This
|
|
is a field-based time point with a resolution of one day.</li>
|
|
</ol>
|
|
|
|
<h3>Examples</h3>
|
|
|
|
<p>
|
|
The entire library is in namespace <code>date</code>. The examples in this
|
|
overview assume:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
using namespace date;
|
|
using namespace std::chrono;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
in order to cut down on the verbosity.
|
|
</p>
|
|
|
|
<h3>Example: Constructing dates</h3>
|
|
|
|
<b><code>year_month_day</code></b>
|
|
|
|
<p>
|
|
<code>constexpr</code> dates can be constructed from literals in any one of 3 orders:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x1 = 2015_y/mar/22;
|
|
constexpr auto x2 = mar/22/2015;
|
|
constexpr auto x3 = 22_d/mar/2015;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
<code>x1</code>, <code>x2</code> and <code>x3</code> all have the type:
|
|
<code>year_month_day</code>, and are all equal to one another. Any other order,
|
|
or any ambiguity is caught at compile time. These three orders were chosen
|
|
because these are the
|
|
<a href="http://en.wikipedia.org/wiki/Date_format_by_country">three orders that people actually use</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Integral types can be converted to <code>year</code>, <code>month</code>, or
|
|
<code>day</code> to create run time values:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
int y = 2015;
|
|
int m = 3;
|
|
int d = 22;
|
|
auto x1 = year{y}/m/d;
|
|
auto x2 = month{m}/d/y;
|
|
auto x3 = day{d}/m/y;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
As long as the type of the first date component is known, the following components become
|
|
unambiguous and can be formed either with the proper type, or with an <code>int</code>
|
|
expression. And since there is only one order with <code>day</code> in the middle, that
|
|
order need only properly type the <code>day</code> to remain unambiguous:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto x = m/day{d}/y;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
No matter the order of the <code>year</code>, <code>month</code> and
|
|
<code>day</code> specifiers, and no matter whether some of the fields implicitly
|
|
convert from <code>int</code>, the type of these expressions is
|
|
<code>year_month_day</code>. However because of <code>auto</code>, it is very
|
|
often unimportant how to spell the somewhat verbose type name
|
|
<code>year_month_day</code>. The compiler knows how to spell the type, and the
|
|
meaning is clear to the human reader without an explicit type.
|
|
</p>
|
|
|
|
<p>
|
|
If there is <i>any</i> ambiguity, the code <b>will not compile</b>. If the code
|
|
does compile, it will be unambiguous and quite readable.
|
|
</p>
|
|
|
|
<b><code>year_month_day_last</code></b>
|
|
|
|
<p>
|
|
Anywhere you can specify a <code>day</code> you can instead specify <code>last</code>
|
|
to indicate the last day of the month for that year:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x1 = 2015_y/feb/last;
|
|
constexpr auto x2 = feb/last/2015;
|
|
constexpr auto x3 = last/feb/2015;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Instead of constructing a <code>year_month_day</code>, these expressions construct a
|
|
<code>year_month_day_last</code>. This type always represents the last day of a
|
|
<code>year</code> and <code>month</code>. <code>year_month_day_last</code> will
|
|
implicitly convert to <code>year_month_day</code>. Note though that because of
|
|
<code>auto</code> both the reader and the writer of the code can very often remain
|
|
blissfully ignorant of the spelling of <code>year_month_day_last</code>. The API of
|
|
<code>year_month_day</code> and <code>year_month_day_last</code> are virtually identical
|
|
so that the learning curve is shallow, and generic code usually does not need to know
|
|
which type it is operating on.
|
|
</p>
|
|
|
|
<b><code>year_month_weekday</code></b>
|
|
|
|
<p>
|
|
Anywhere you can specify a <code>day</code> you can instead specify an <i>indexed</i>
|
|
<code>weekday</code> to indicate the nth weekday of the month for that year:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x1 = 2015_y/mar/sun[4];
|
|
constexpr auto x2 = mar/sun[4]/2015;
|
|
constexpr auto x3 = sun[4]/mar/2015;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The type constructed is <code>year_month_weekday</code> which will implicitly convert to
|
|
and from a <code>sys_days</code>. If you want to convert to a
|
|
<code>year_month_day</code> you can do so explicitly, which will implicitly convert to
|
|
<code>sys_days</code> and back:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x4 = year_month_day{x3};
|
|
</pre></blockquote>
|
|
|
|
<b><code>year_month_weekday_last</code></b>
|
|
|
|
<p>
|
|
<code>weekday</code>'s can be indexed with <code>last</code> and used as above:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x1 = 2015_y/mar/sun[last];
|
|
constexpr auto x2 = mar/sun[last]/2015;
|
|
constexpr auto x3 = sun[last]/mar/2015;
|
|
constexpr auto x4 = year_month_day{x3};
|
|
cout << x3 << '\n';
|
|
cout << x4 << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
This creates an object of type <code>year_month_weekday_last</code>. The above code
|
|
outputs:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015/Mar/Sun[last]
|
|
2015-03-29
|
|
</pre></blockquote>
|
|
|
|
<b>Escape hatch from the conventional syntax</b>
|
|
|
|
<p>
|
|
If you hate the conventional syntax, don't use it. Every type has a descriptive name,
|
|
and public type-safe constructors to do the same job. The "conventional syntax" is a
|
|
non-friended and <i>zero-abstraction-penalty</i> layer on top of a complete lower-level
|
|
API.
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
constexpr auto x1 = 2015_y/mar/sun[last];
|
|
constexpr auto x2 = year_month_weekday_last{year{2015}, month{3u}, weekday_last{weekday{0u}}};
|
|
static_assert(x1 == x2, "No matter the API, x1 and x2 have the same value ...");
|
|
static_assert(is_same<decltype(x1), decltype(x2)>::value, "... and are the same type");
|
|
cout << x1 << '\n';
|
|
cout << x2 << '\n';
|
|
|
|
2015/Mar/Sun[last]
|
|
2015/Mar/Sun[last]
|
|
</pre></blockquote>
|
|
|
|
<h3>Example: Today</h3>
|
|
|
|
<p>
|
|
To get today as a <code>sys_days</code>, use <code>system_clock::now()</code> and
|
|
<code>floor</code> to convert the <code>time_point</code> to a
|
|
<code>sys_days</code>:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto today = floor<days>(system_clock::now());
|
|
cout << today << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Currently this outputs for me:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015-03-22
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
To get today as a <code>year_month_day</code>, get a <code>sys_days</code> as above and
|
|
convert it to a <code>year_month_day</code>:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto today = year_month_day{floor<days>(system_clock::now())};
|
|
cout << today << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Which again currently outputs for me:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015-03-22
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
To get today as a <code>year_month_weekday</code>, get a <code>sys_days</code> as above and
|
|
convert it to a <code>year_month_weekday</code>:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto today = year_month_weekday{floor<days>(system_clock::now())};
|
|
cout << today << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Currently this outputs for me:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015/Mar/Sun[4]
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
This indicates that today (2015-03-22) is the fourth Sunday of Mar., 2015.
|
|
</p>
|
|
|
|
<h3>Example: Contrast with C</h3>
|
|
|
|
<p>
|
|
Just about everything C++ has for date handling, it inherits from C. I thought it
|
|
would be fun to contrast an example that comes from the C standard with this library.
|
|
</p>
|
|
|
|
<p>
|
|
From the C standard: 7.27.2.3 The <code>mktime</code> function, paragraph 4:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>
|
|
EXAMPLE What day of the week is July 4, 2001?
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
static const char *const wday[] =
|
|
{
|
|
"Sunday", "Monday", "Tuesday", "Wednesday",
|
|
"Thursday", "Friday", "Saturday", "-unknown-"
|
|
};
|
|
|
|
int
|
|
main()
|
|
{
|
|
struct tm time_str;
|
|
time_str.tm_year = 2001 - 1900;
|
|
time_str.tm_mon = 7 - 1;
|
|
time_str.tm_mday = 4;
|
|
time_str.tm_hour = 0;
|
|
time_str.tm_min = 0;
|
|
time_str.tm_sec = 0;
|
|
time_str.tm_isdst = -1;
|
|
if (mktime(&time_str) == (time_t)(-1))
|
|
time_str.tm_wday = 7;
|
|
printf("%s\n", wday[time_str.tm_wday]);
|
|
}
|
|
</pre></blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
This program outputs:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
Wednesday
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Coding the same problem up in this library looks like:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
#include "date.h"
|
|
#include <iostream>
|
|
|
|
int
|
|
main()
|
|
{
|
|
using namespace date;
|
|
std::cout << weekday{jul/4/2001} << '\n';
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
which outputs:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
Wed
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
And if we really want to show off, this can all be done at compile time:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
#include "date.h"
|
|
|
|
int
|
|
main()
|
|
{
|
|
using namespace date;
|
|
static_assert(weekday{2001_y/jul/4} == wed, "");
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
(Date ordering was switched simply to assure the gentle reader that we're not hung up on
|
|
m/d/y ordering.)
|
|
</p>
|
|
|
|
<h3>Errors</h3>
|
|
|
|
<p>
|
|
No exceptions are thrown in the entire library, except those that might be thrown from
|
|
<code>std::ostream</code> when streaming values to a <code>std::ostream</code>. Most of
|
|
the types have a <code>constexpr const</code> member function named <code>ok()</code>
|
|
which returns <code>true</code> if the object represents a valid date, or date component,
|
|
and otherwise returns <code>false</code>. However it is perfectly fine (and sometimes
|
|
actually useful) for these objects to contain invalid dates or date components. For
|
|
example, here is a very simple and remarkably efficient program to output the odd Fridays
|
|
of every month in 2015:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
int
|
|
main()
|
|
{
|
|
using namespace std;
|
|
using namespace date;
|
|
for (auto m = 1; m <= 12; ++m)
|
|
{
|
|
auto meet = year_month_day{m/fri[1]/2015};
|
|
cout << meet << '\n';
|
|
meet = meet.year()/meet.month()/(meet.day()+weeks{2});
|
|
cout << meet << '\n';
|
|
meet = meet.year()/meet.month()/(meet.day()+weeks{2});
|
|
if (meet.ok())
|
|
cout << meet << '\n';
|
|
}
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
There is a relatively expensive (expense is relative here — maybe as much as 100ns)
|
|
conversion from <code>year_month_weekday</code> to <code>year_month_day</code> at the top
|
|
of the loop to find the first Friday of the month. This computation can never fail. And
|
|
after that it is dirt cheap to find the 3rd Friday — you just have to add 2 weeks to
|
|
the day field. This computation also can never fail. And it is similarly cheap to find
|
|
the 5th Friday of each month. However, not every month has a fifth Friday. But
|
|
nevertheless it is ok to form such a <code>year_month_day</code>. The computation can
|
|
never fail, though it may render an invalid date. Afterwards one can simply ask: Did I
|
|
create a valid date? If so, print it out, otherwise just continue on.
|
|
</p>
|
|
|
|
<p>
|
|
This program is easy to read, easy to write, will fail to compile if any careless errors
|
|
are made, and extremely high performance. The date computations are dwarfed by the run
|
|
time costs of the I/O.
|
|
</p>
|
|
|
|
<p>
|
|
Because practically nothing throws exceptions, this entire library is liberally sprinkled
|
|
with <code>noexcept</code>.
|
|
</p>
|
|
|
|
<p>
|
|
A few of the operations have a precondition that <code>ok() == true</code>. These are
|
|
generally conversions to <code>sys_days</code>, and month-oriented and weekday-oriented
|
|
arithmetic. Anywhere there is a precondition, and those places are few, the precondition
|
|
is checkable with <code>ok()</code>.
|
|
</p>
|
|
|
|
<p>
|
|
This library catches many errors (especially ambiguity errors) at compile time. What's
|
|
left over is left up to <code>ok()</code>. Sometimes <code>!ok()</code> will represent an
|
|
error, and other times it will simply represent something innocuous that can be ignored
|
|
(such as in the example above). If <code>!ok()</code> actually represents an error that
|
|
must be dealt with, the choice of whether to assert or throw is made by the client of
|
|
this library.
|
|
</p>
|
|
|
|
<h3>Efficiency</h3>
|
|
|
|
<p>
|
|
In <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3344.pdf">N3344</a>
|
|
Pacifico, Meredith and Lakos present a thorough survey of date types and their performance.
|
|
This library has been strongly influenced by this excellent paper.
|
|
<code>year_month_day</code> is equivalent to what <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3344.pdf">N3344</a> terms <code>YMD_4</code>. And
|
|
<code>sys_days</code> is equivalent to what <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3344.pdf">N3344</a> terms <code>HH_SERIAL_RAW_4</code>.
|
|
</p>
|
|
|
|
<p>
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3344.pdf">N3344</a>
|
|
aptly demonstrates that field-based date structures are good at some operations and poor
|
|
at others. And serial-based implementations are generally good at what the field-based
|
|
data structures are poor at, and poor at what the field-based data structures are good at.
|
|
Indeed, this is the genesis of the design of this library: Provide both data structures
|
|
and let the conversions among the data structures be provided by algorithms as shown in
|
|
<a href="http://howardhinnant.github.io/date_algorithms.html"><code>chrono</code>-Compatible Low-Level Date Algorithms</a>.
|
|
And additionally, just provide the API for each data structure that it can do efficiently.
|
|
</p>
|
|
|
|
<ul>
|
|
<li><p>
|
|
Field types are good at returning the values of the fields. Serial types aren't (except
|
|
for weekdays). So <code>year_month_day</code> has accessors for <code>year</code>,
|
|
<code>month</code> and <code>day</code>. And <code>sys_days</code> does not.
|
|
</p></li>
|
|
<li><p>
|
|
Field types are good at month and year-oriented arithmetic. Serial types aren't.
|
|
So <code>year_month_day</code> has month and year-oriented arithmetic. And
|
|
<code>sys_days</code> does not.
|
|
</p></li>
|
|
<li><p>
|
|
Serial types are good at day-oriented arithmetic. Field types aren't.
|
|
So <code>sys_days</code> has day-oriented arithmetic. And <code>year_month_day</code>
|
|
does not. Though one can perform day-oriented arithmetic on the day field of a
|
|
<code>year_month_day</code>, with no impact on the other fields.
|
|
</p></li>
|
|
<li><p>
|
|
To efficiently compute a day of the week, one first needs to compute a serial date. So
|
|
<code>weekday</code> is constructible from <code>sys_days</code>.
|
|
</p></li>
|
|
</ul>
|
|
|
|
<p>
|
|
To demonstrate the efficiency of constructing a <code>year_month_day</code>, a hypothetical
|
|
factory function has been created in the table below. And this is compared with a
|
|
simplistic <code>struct YMD_4</code> and an obvious factory function for that. Each is
|
|
compiled using clang at an optimization of -O2 or higher.
|
|
</p>
|
|
|
|
<blockquote>
|
|
<table border="1" cellpadding="10">
|
|
<caption><code>year_month_day</code> constructor assembly</caption>
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
date::year_month_day
|
|
make_year_month_day(int y, int m, int d)
|
|
{
|
|
using namespace date;
|
|
return year{y}/m/d;
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
struct YMD_4
|
|
{
|
|
std::int16_t year;
|
|
std::uint8_t month;
|
|
std::uint8_t day;
|
|
};
|
|
|
|
YMD_4
|
|
make_YMD_4(int y, int m, int d)
|
|
{
|
|
return {static_cast<std::int16_t>(y),
|
|
static_cast<std::uint8_t>(m),
|
|
static_cast<std::uint8_t>(d)};
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z19make_year_month_dayiii
|
|
.align 4, 0x90
|
|
__Z19make_year_month_dayiii:
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp3:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp4:
|
|
.cfi_def_cfa_register %rbp
|
|
shll $24, %edx
|
|
shll $16, %esi
|
|
andl $16711680, %esi
|
|
movzwl %di, %eax
|
|
orl %edx, %eax
|
|
orl %esi, %eax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z10make_YMD_4iii
|
|
.align 4, 0x90
|
|
__Z10make_YMD_4iii:
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp3:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp4:
|
|
.cfi_def_cfa_register %rbp
|
|
shll $24, %edx
|
|
shll $16, %esi
|
|
andl $16711680, %esi
|
|
movzwl %di, %eax
|
|
orl %esi, %eax
|
|
orl %edx, %eax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
</table>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
One can see that the generated assembler is virtually identical for these two factory
|
|
functions. I.e. the code size and run time overhead of the "cute syntax" for constructing
|
|
a <code>year_month_day</code> is zero, at least in optimized builds.
|
|
</p>
|
|
|
|
<p>
|
|
A similar experiment is made for constructing a <code>sys_days</code> from a count of
|
|
days held in an <code>int</code>. To do this one must first create a <code>days</code>
|
|
duration, and then construct the <code>sys_days</code> from the <code>days</code>
|
|
duration. This is contrasted with the very simplistic <code>struct SERIAL_4</code>.
|
|
</p>
|
|
|
|
<blockquote>
|
|
<table border="1" cellpadding="10">
|
|
<caption><code>sys_days</code> constructor assembly</caption>
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
date::sys_days
|
|
make_day_point(int z)
|
|
{
|
|
using namespace date;
|
|
return sys_days{days{z}};
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
struct SERIAL_4
|
|
{
|
|
std::int32_t count;
|
|
};
|
|
|
|
SERIAL_4
|
|
make_SERIAL_4(int z)
|
|
{
|
|
return {z};
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z14make_day_pointi
|
|
.align 4, 0x90
|
|
__Z14make_day_pointi:
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp3:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp4:
|
|
.cfi_def_cfa_register %rbp
|
|
movl %edi, %eax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z13make_SERIAL_4i
|
|
.align 4, 0x90
|
|
__Z13make_SERIAL_4i:
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp3:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp4:
|
|
.cfi_def_cfa_register %rbp
|
|
movl %edi, %eax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
</table>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
It is easy to see that the generated code is identical, and thus there is no overhead
|
|
associated with the <code>sys_days</code> type. It is also noteworthy that the code for
|
|
this construction does not actually come from this <code>date</code> library, but instead
|
|
comes from your std::lib header <code><chrono></code>. <code>days</code> is nothing
|
|
but a <i>type-alias</i> for a <code>std::chrono::duration</code>, and
|
|
<code>sys_days</code> is nothing but a <i>type-alias</i> for a
|
|
<code>std::chrono::time_point</code> (thus the inspiration for the name
|
|
<code>sys_days</code>). So this is also evidence that there is zero overhead for the
|
|
type-safe system of the <code><chrono></code> library.
|
|
</p>
|
|
|
|
<a name="shift_epoch"></a>
|
|
<p>
|
|
One final example taken from real-world code. Below are two ways of implementing a system
|
|
which counts seconds since Jan. 1, 2000: One that uses this library and another that
|
|
simply stores the count of seconds in a <code>long</code>. A utility is needed to convert
|
|
that count to <a href="http://en.wikipedia.org/wiki/Unix_time">Unix Time</a>, which simply
|
|
involves shifting the epoch to Jan. 1, 1970.
|
|
</p>
|
|
|
|
<blockquote>
|
|
<table border="1" cellpadding="10">
|
|
<caption>Shift epoch from <code>jan/1/2000</code> to <code>jan/1/1970</code></caption>
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
using time_point = std::chrono::time_point<std::chrono::system_clock,
|
|
std::chrono::seconds>;
|
|
|
|
time_point
|
|
shift_epoch(time_point t)
|
|
{
|
|
using namespace date;
|
|
return t + (sys_days(jan/1/2000) - sys_days(jan/1/1970));
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
long
|
|
shift_epoch(long t)
|
|
{
|
|
return t + 946684800;
|
|
}
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z11shift_epochNSt3__16chrono10time_pointINS0...
|
|
.align 4, 0x90
|
|
__Z11shift_epochNSt3__16chrono10time_pointINS0...
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp0:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp1:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_register %rbp
|
|
leaq 946684800(%rdi), %rax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
<td>
|
|
<pre>
|
|
.globl __Z11shift_epochl
|
|
.align 4, 0x90
|
|
__Z11shift_epochl:
|
|
.cfi_startproc
|
|
## BB#0:
|
|
pushq %rbp
|
|
Ltmp0:
|
|
.cfi_def_cfa_offset 16
|
|
Ltmp1:
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
Ltmp2:
|
|
.cfi_def_cfa_register %rbp
|
|
leaq 946684800(%rdi), %rax
|
|
popq %rbp
|
|
retq
|
|
.cfi_endproc
|
|
</pre>
|
|
</td>
|
|
|
|
</tr>
|
|
</table>
|
|
|
|
</blockquote>
|
|
|
|
<p>
|
|
On the left we have a strongly typed solution which makes it explicit that the code is
|
|
adding a time duration equal to the difference between the two epochs. Though verbose,
|
|
the code is easy to read. On the right we have the maximally efficient, and yet relatively
|
|
cryptic implementation with <code>long</code>. As it turns out, there are 946,684,800
|
|
seconds between these two epochs ... who knew?
|
|
</p>
|
|
|
|
<p>
|
|
clang generates <i>identical</i> assembly for these two functions at -O2 and higher. That
|
|
is, the sub-expression <code>(sys_days(jan/1/2000) - sys_days(jan/1/1970))</code> is
|
|
reduced down to a number of days (10,957) <i>at compile time</i>, and then this
|
|
sub-expression, which has type <code>days</code> is added to a <code>time_point</code>
|
|
with a resolution of <code>seconds</code>, which causes the compiler to convert
|
|
<code>days{10957}</code> to <code>seconds{946684800}</code>, again <i>at compile time</i>.
|
|
</p>
|
|
|
|
<p>
|
|
And in the strongly typed case, if in the future one decides that one wants to count
|
|
milliseconds instead of seconds, that can be changed in <b>one</b> place:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
using time_point = std::chrono::time_point<std::chrono::system_clock,
|
|
std::chrono::<ins>milli</ins>seconds>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
Upon recompile the compiler automatically updates the compile-time constant in
|
|
<code>shift_epoch</code> from 946684800 to 946684800000 (and everywhere else such as
|
|
where you perform the epoch shift in the reverse direction).
|
|
</p>
|
|
|
|
<h3>What about a date-time type?</h3>
|
|
|
|
<p>
|
|
You already have a good one. It is called
|
|
<code>std::chrono::system_clock::time_point</code>. And it is completely interoperable
|
|
with this library. <code>std::chrono::system_clock::time_point</code> is a pointer to
|
|
a particular instant of time, with high precision (that precision is specified differently
|
|
on each platform). As we saw earlier, one can get a high-precision <code>time_point</code>
|
|
representing <i>now</i> with:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto tp = system_clock::now();
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
This library provides a stream insertion operator for
|
|
<code>system_clock::time_point</code> (in <code>namespace date</code>).
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
std::cout << tp << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
This currently outputs for me:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015-04-19 18:24:42.770911
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
One can turn that into a <code>time_point</code> with the precision of a day (which
|
|
has a type alias called <code>sys_days</code>) with:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto dp = floor<days>(tp);
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
And one can convert that day-oriented <code>time_point</code> into a
|
|
<code>{year, month, day}</code> field type with:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto ymd = year_month_day{dp};
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
This section explains how to extract the <i>time of day</i> from the above information.
|
|
<code>dp</code> can also be though of as a <code>time_point</code> to the beginning of the
|
|
current day (in the UTC timezone). And so one can get the time <code>duration</code>
|
|
since midnight by subtracting the day-precision <code>time_point</code> from the high
|
|
precision <code>time_point</code>: <code>tp-dp</code>. This results in a high precision
|
|
<code>std::chrono::duration</code> representing the time since midnight.
|
|
</p>
|
|
|
|
<p>
|
|
This high precision <code>duration</code> can be broken down into hours, minutes, seconds,
|
|
and fractions of a second with a <code>time_of_day</code> object, which is most easily
|
|
created by using the <code>make_time</code> factory function:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto time = make_time(tp-dp);
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Now both <code>ymd</code> and <code>time</code> can simply be printed out:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
std::cout << ymd << ' ' << time << '\n';
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Which will result in something like:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015-04-19 18:24:42.770911
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Indeed, this is exactly what the stream insertion operator for
|
|
<code>system_clock::time_point</code> does. So if you don't like the default format,
|
|
this is how you pick apart a <code>system_clock::time_point</code> so you can output it
|
|
in whatever format you prefer.
|
|
</p>
|
|
|
|
<p>
|
|
The above is the current date and time in the UTC timezone with microsecond precision.
|
|
On the platform I'm writing this, <code>system_clock::time_point</code> counts
|
|
microseconds. When you run this code on your platform, the library will automatically
|
|
adapt to the precision supported by your platform's implementation of
|
|
<code>system_clock::time_point</code>.
|
|
</p>
|
|
|
|
<p>
|
|
If you prefer output in a local time zone, you will need to discover your current UTC
|
|
offset and add that to <code>tp</code> prior to applying <code>floor</code>.
|
|
Your current UTC offset is a function of both your UTC time point <code>tp</code>, and
|
|
your location. This functionality is not offered by this library, but can be built on top
|
|
of it. For example <a href="tz.html">here is such a library</a>. But as a simplistic
|
|
example, here is code that assumes an Eastern US location and daylight savings rules
|
|
currently in effect:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
std::chrono::hours
|
|
utc_offset_Eastern_US(std::chrono::system_clock::time_point tp)
|
|
{
|
|
using namespace date;
|
|
using namespace std::chrono;
|
|
constexpr auto EST = -5h;
|
|
constexpr auto EDT = -4h;
|
|
const auto y = year_month_day{floor<days>(tp)}.year();
|
|
const auto begin = sys_days{sun[2]/mar/y} + 2h - EST; // EDT begins at this UTC time
|
|
const auto end = sys_days{sun[1]/nov/y} + 2h - EDT; // EST begins at this UTC time
|
|
if (tp < begin || end <= tp)
|
|
return EST;
|
|
return EDT;
|
|
}
|
|
...
|
|
auto tp = system_clock::now();
|
|
tp += utc_offset_Eastern_US(tp); // tp now in Eastern US timezone
|
|
std::cout << tp << '\n';
|
|
|
|
2015-04-19 14:24:42.770911
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
And if you prefer your output in a 12-hour format with a precision of only minutes, that
|
|
is also easily accomplished:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto tp = system_clock::now();
|
|
tp += utc_offset_Eastern_US(tp);
|
|
const auto tpm = floor<minutes>(tp); // truncate to minutes precision
|
|
const auto dp = floor<days>(tpm);
|
|
const auto ymd = year_month_day{dp};
|
|
auto time = make_time(tpm-dp); // minutes since midnight
|
|
time.make12(); // change to 12-hour format
|
|
std::cout << ymd << ' ' << time << '\n';
|
|
|
|
2015-04-19 2:24pm
|
|
</pre></blockquote>
|
|
|
|
<h3>Extensibility</h3>
|
|
|
|
<p>
|
|
The hub of this library is <code>sys_days</code>. This is a <i>serial-based</i> time
|
|
point which simply counts the days since (or before) <code>jan/1/1970</code>. And
|
|
ironically this all important hub is nothing but a type alias to a std-defined type. That
|
|
is, the central theme this library is built around is nothing more than this:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
using sys_days = std::chrono::time_point<std::chrono::system_clock, days>;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Types such as <code>year_month_day</code> and <code>year_month_weekday</code> provide
|
|
implicit conversions to and from <code>sys_days</code>, and because of this, the C++
|
|
language provides explicit conversions between <code>year_month_day</code> and
|
|
<code>year_month_weekday</code>.
|
|
</p>
|
|
|
|
<p>
|
|
You can easily build your own types that implicitly convert to and from
|
|
<code>sys_days</code>, and when you do, you automatically gain explicit convertibility to
|
|
and from every other type which ties into <code>sys_days</code>. For example, here is
|
|
how you could create a custom type that models the ISO week-based calendar:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
class iso_week
|
|
{
|
|
date::year y_;
|
|
date::weeks w_;
|
|
date::weekday wd_;
|
|
|
|
public:
|
|
constexpr iso_week(date::sys_days dp) noexcept
|
|
: iso_week(iso_week_from_day_point(dp))
|
|
{}
|
|
|
|
constexpr iso_week(date::year y, date::weeks w, date::weekday wd) noexcept
|
|
: y_(y)
|
|
, w_(w)
|
|
, wd_(wd)
|
|
{}
|
|
|
|
constexpr operator date::sys_days() const noexcept
|
|
{
|
|
using namespace date;
|
|
return iso_week_start(y_) + w_ - weeks{1} + (wd_ - mon);
|
|
}
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, const iso_week& x)
|
|
{
|
|
return os << x.y_ << "-W(" << x.w_.count() << ")-" << x.wd_;
|
|
}
|
|
|
|
private:
|
|
static
|
|
constexpr
|
|
date::sys_days
|
|
iso_week_start(date::year y) noexcept
|
|
{
|
|
using namespace date;
|
|
return sys_days{thu[1]/jan/y} - (thu-mon);
|
|
}
|
|
|
|
static
|
|
constexpr
|
|
iso_week
|
|
iso_week_from_day_point(date::sys_days dp) noexcept
|
|
{
|
|
using namespace date;
|
|
using namespace std::chrono;
|
|
auto y = year_month_day{dp}.year();
|
|
auto start = iso_week_start(y);
|
|
if (dp < start)
|
|
{
|
|
--y;
|
|
start = iso_week_start(y);
|
|
}
|
|
else
|
|
{
|
|
auto const next_start = iso_week_start(y+years{1});
|
|
if (dp >= next_start)
|
|
{
|
|
++y;
|
|
start = next_start;
|
|
}
|
|
}
|
|
return {y, duration_cast<weeks>(dp - start) + weeks{1}, weekday{dp}};
|
|
}
|
|
};
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The rules for the ISO week-based calendar are fairly simple:
|
|
</p>
|
|
|
|
<ol>
|
|
<li>Weeks begin with Monday and end on Sunday.</li>
|
|
<li>The year begins on the Monday prior to the first Thursday in January.</li>
|
|
<li>A date is specified by the week number [1 - 53], day of the week [Mon - Sun], and year
|
|
number.</li>
|
|
<li>The year number is the same as the civil year number for the Thursday that follows the
|
|
start of the week-based year.</li>
|
|
</ol>
|
|
|
|
<p>
|
|
With that in mind, one can easily create a <i>field-based</i> data structure that holds
|
|
a <code>year</code>, a week number, and a day of the week, and then provides conversions
|
|
to and from <code>sys_days</code>.
|
|
</p>
|
|
|
|
<p>
|
|
The key points of this class (for interoperability) are the constructor
|
|
<code>iso_week(date::sys_days dp)</code> and the <code>operator date::sys_days()</code>.
|
|
</p>
|
|
|
|
<p>
|
|
To aid in these computations a private helper function is created to compute the
|
|
<code>sys_days</code> corresponding to the first day of the week-based year. And according
|
|
to rule 2, this can be elegantly coded as:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
return sys_days{thu[1]/jan/y} - (thu-mon);
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
That is, first find the first Thursday in January for year <code>y</code>, and then subtract
|
|
the number of days required to find the Monday before this day. This could have been done
|
|
with <code>days{3}</code>. But I chose to code this as <code>(thu-mon)</code>.
|
|
Computationally and performance wise, these two choices are identical: they both subtract
|
|
the literal 3. I chose the latter because I believe it to be more readable.
|
|
"<code>3</code>" is just a magic constant. But "<code>(thu-mon)</code>" is the number of
|
|
days Thursday is past Monday.
|
|
</p>
|
|
|
|
<p>
|
|
The constructor <code>iso_week(date::sys_days dp)</code> has to first discover which
|
|
ISO week-based year the <code>sys_days dp</code> falls into. Most often this is the
|
|
same as the civil (<code>year_month_day</code>) year number associated <code>dp</code>.
|
|
But because the week-based year may start a few days earlier or later than
|
|
<code>jan/1</code>, the week-based year number may be one less or one greater than the
|
|
civil year number associated <code>dp</code>. Once the proper start of the week-based year
|
|
is nailed down (in <code>start</code>), the translation to the field-based
|
|
<code>iso_week</code> is trivial:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
return {y, duration_cast<weeks>(dp - start) + weeks{1}, weekday{dp}};
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The conversion from <code>iso_week</code> to <code>sys_days</code> is even easier:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
return iso_week_start(y_) + w_ - weeks{1} + (wd_ - mon);
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
It is the the start of the week-based year, plus the number of weeks (minus one since this
|
|
count is 1-based), plus the number of days the <code>weekday</code> is past Monday. Note
|
|
that because <code>weekday</code> subtraction is treated as a circular range (always
|
|
results in a number of days in the range [0, 6]), the logic at this level is simplified.
|
|
That is, Sunday is 6 days past Monday, not one day before it (and Monday is still one day
|
|
past Sunday). So the encoding used for <code>weekday</code> is irrelevant; safely
|
|
encapsulated within <code>weekday</code>. Said differently, <code>weekday</code>
|
|
arithmetic is unsigned, modulo 7.
|
|
</p>
|
|
|
|
<p>
|
|
With the above code, one can now write programs such as the one below which demonstrates
|
|
easy convertibility among the <code>date</code> <i>field-types</i> and your custom
|
|
<i>field-type</i>.
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
int
|
|
main()
|
|
{
|
|
using namespace date;
|
|
using namespace std;
|
|
using namespace std::chrono;
|
|
auto dp = floor<days>(system_clock::now());
|
|
auto ymd = year_month_day{dp};
|
|
cout << ymd << '\n';
|
|
<b>auto iso = iso_week{ymd};</b>
|
|
cout << iso << '\n';
|
|
<b>auto ymwd = year_month_weekday{iso};</b>
|
|
cout << ymwd << '\n';
|
|
<b>assert(year_month_day{iso} == ymd);</b>
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Which will output something like:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
2015-05-20
|
|
2015-W(21)-Wed
|
|
2015/May/Wed[3]
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
As long as you can relate your custom <i>field-based</i> structure (be it the Julian
|
|
calendar, the Hindu calendar, or the Maya calendar) to the number of days before and after
|
|
civil 1970-01-01, you can achieve interoperability with every other <i>field-based</i>
|
|
structure that does so. And obviously you can then also convert your custom calendar to
|
|
UTC (<code>std::chrono::system_clock::time_point</code>). <i>This is the Rosetta Stone of
|
|
time keeping.</i>
|
|
</p>
|
|
|
|
<p>
|
|
For an example of a fully developed
|
|
<a href="https://en.wikipedia.org/wiki/ISO_week_date">ISO week date calendar</a>
|
|
which is fully interoperable with this library via the technique described above see
|
|
<a href="iso_week.html"><code>iso_week</code></a>.
|
|
</p>
|
|
|
|
<a name="range"></a><h2>Range of Validity</h2>
|
|
|
|
<p>
|
|
As with all numerical representations with a fixed storage size, <code>duration</code>s,
|
|
<code>time_point</code>s, and <code>year_month_day</code>s have a fixed range, outside
|
|
of which they overflow. With this library, and with <code><chrono></code>, the
|
|
range varies with precision.
|
|
</p>
|
|
|
|
<p>
|
|
On one side <code>nanoseconds</code> is represented by a <code>int64_t</code>
|
|
which has a range of about +/- 292 years. And on the other side <code>year</code>
|
|
is represented by a <code>int16_t</code> which has a range of about +/- 32 thousand
|
|
years. It is informative and educational to write software which explores the
|
|
intersection of these two constraints for various precisions, and outputs the result
|
|
in terms of a <code>sys_time</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Here is a function which will discover the limits for a single durration <code>D</code>:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
#include "date.h"
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <cstdint>
|
|
|
|
template <class D>
|
|
void
|
|
limit(const std::string& msg)
|
|
{
|
|
using namespace date;
|
|
using namespace std;
|
|
using namespace std::chrono;
|
|
using dsecs = sys_time<duration<double>>;
|
|
constexpr auto ymin = sys_days{year::min()}/jan/1};
|
|
constexpr auto ymax = sys_days{year::max()}/12/last};
|
|
constexpr auto dmin = sys_time<D>::min();
|
|
constexpr auto dmax = sys_time<D>::max();
|
|
cout << left << setw(24) << msg << " : [";
|
|
if (ymin > dsecs{dmin})
|
|
cout << ymin;
|
|
else
|
|
cout << dmin;
|
|
cout << ", ";
|
|
if (ymax < dsecs{dmax})
|
|
cout << ymax;
|
|
else
|
|
cout << dmax;
|
|
cout << "]\n";
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The best way to explore limits without risking overflow during the comparison operation
|
|
itself is to use <code>double</code>-based <code>seconds</code> for the comparison. By
|
|
using <code>seconds</code> you guarantee that the conversion to the comparison type
|
|
won't overflow the compile-time machinery of finding the <code>common_type</code> of the
|
|
<code>duration</code>s, and by using <code>double</code> you make overflow or underflow
|
|
nearly impossible. The use of <code>double</code> sacrifices precision, but this is
|
|
rarely needed for limits comparisons as the two operands of the comparison are typically
|
|
orders of magnitude apart.
|
|
</p>
|
|
|
|
<p>
|
|
So the code above creates a <code>sys_time<double></code> <code>time_point</code>
|
|
with which to perform the comparisons. Then it finds the min and max of both the
|
|
<code>year_month_day</code> object, and the duration <code>D</code>. It then prints
|
|
out the intersection of these two ranges.
|
|
</p>
|
|
|
|
<p>
|
|
This code can be exercised like so:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
void
|
|
limits()
|
|
{
|
|
using namespace std::chrono;
|
|
using namespace std;
|
|
using picoseconds = duration<int64_t, pico>;
|
|
using fs = duration<int64_t, ratio_multiply<ratio<100>, nano>>;
|
|
limit<picoseconds>("picoseconds range is");
|
|
limit<nanoseconds>("nanoseconds range is");
|
|
limit<fs>("VS system_clock range is");
|
|
limit<microseconds>("microseconds range is");
|
|
limit<milliseconds>("milliseconds range is");
|
|
limit<seconds>("seconds range is");
|
|
limit<minutes>("minutes range is");
|
|
limit<hours>("hours range is");
|
|
}
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
I've included two extra units: <code>picoseconds</code>, and the units used by Visual
|
|
Studio's <code>system_clock::time_point</code>. Units finer than <code>picoseconds</code>
|
|
do not work with this date library because the conversion factors needed to convert to
|
|
units such as <code>days</code> overflow the compile-time machinery. As a practical
|
|
matter this is not important as the range of a 64 bit femtosecond is only about +/- 2.5
|
|
hours. On the other side, units coarser than <code>hours</code>, if represented by at
|
|
least 32 bits, will always have a range far greater than a 16 bit <code>year</code>.
|
|
</p>
|
|
|
|
<p>
|
|
The output of this function on Visual Studio, and on clang using libc++ with
|
|
<code>-arch i386</code> is:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
picoseconds range is : [1969-09-16 05:57:07.963145224192, 1970-04-17 18:02:52.036854775807]
|
|
nanoseconds range is : [1677-09-21 00:12:43.145224192, 2262-04-11 23:47:16.854775807]
|
|
VS system_clock range is : [-27258-04-19 21:11:54.5224192, 31197-09-14 02:48:05.4775807]
|
|
microseconds range is : [-32768-01-01, 32767-12-31]
|
|
milliseconds range is : [-32768-01-01, 32767-12-31]
|
|
seconds range is : [-32768-01-01, 32767-12-31]
|
|
minutes range is : [-2114-12-08 21:52, 6053-01-23 02:07]
|
|
hours range is : [-32768-01-01, 32767-12-31]
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Using gcc or clang/libc++ with <code>-arch x86_64</code> the output is:
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
picoseconds range is : [1969-09-16 05:57:07.963145224192, 1970-04-17 18:02:52.036854775807]
|
|
nanoseconds range is : [1677-09-21 00:12:43.145224192, 2262-04-11 23:47:16.854775807]
|
|
VS system_clock range is : [-27258-04-19 21:11:54.5224192, 31197-09-14 02:48:05.4775807]
|
|
microseconds range is : [-32768-01-01, 32767-12-31]
|
|
milliseconds range is : [-32768-01-01, 32767-12-31]
|
|
seconds range is : [-32768-01-01, 32767-12-31]
|
|
minutes range is : [-32768-01-01, 32767-12-31]
|
|
hours range is : [-32768-01-01, 32767-12-31]
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The only difference between these two outputs is that associated with
|
|
<code>minutes</code>. When <code>minutes</code> is represented with 32 bits the range is
|
|
only about +/- 4000 years from 1970. When <code>minutes</code> is represented with 64
|
|
bits, the limits of the 16 bit year takes precedence.
|
|
</p>
|
|
|
|
<p>
|
|
The take-away point here is two-fold:
|
|
</p>
|
|
|
|
<ol>
|
|
<li><p>
|
|
If you need to check range, do the check using <code>duration<double></code> to
|
|
ensure your comparison is not itself vulnerable to overflow.
|
|
</p></li>
|
|
<li><p>
|
|
If you are dealing units finer than <code>microseconds</code>, you may well
|
|
accidentally experience overflow in surprisingly mundane-looking code. When
|
|
dealing with dates that may be hundreds of years away from 1970, keep an eye on
|
|
the precision. And in a surprise move, 32 bit <code>minutes</code> can bite if
|
|
you are several thousand years away from 1970.
|
|
</p></li>
|
|
</ol>
|
|
|
|
<p>
|
|
Finally note that the civil calendar itself models the rotation and orbit of the
|
|
earth with an accuracy of only one day in several thousand years. So dates more
|
|
than several thousand years in the past or future (with a precision of a single
|
|
day) are of limited practical use with or without numerical overflow. The chief
|
|
motivation for having large ranges of date computation before overflow happens
|
|
is to make range checking superflous for most reasonable computations. If you
|
|
need to handle ranges dealing with geological or astrophysical phenomenon,
|
|
<code><chrono></code> can handle it (<code>attoseconds</code> to
|
|
<code>exaseconds</code>), but <code>year_month_day</code> is the wrong tool for
|
|
such extremes.
|
|
</p>
|
|
|
|
<a name="Reference"></a><h2>Reference</h2>
|
|
|
|
<p>
|
|
Here is a detailed specification of the entire library. This specification is detailed
|
|
enough that you could write your own implementation from it if desired. But feel free
|
|
to use <a href="https://github.com/HowardHinnant/date/blob/master/include/date/date.h">this one</a>
|
|
instead. Each type, and each operation is simple
|
|
and predictable.
|
|
</p>
|
|
|
|
<table>
|
|
<tr><td>durations</td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#days"><code>days</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#weeks"><code>weeks</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#months"><code>months</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#years"><code>years</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#duration_io"><code>Formatting and parsing durations</code></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td>time_points</td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#sys_time"><code>sys_time</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#sys_days"><code>sys_days</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#sys_seconds"><code>sys_seconds</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#local_time"><code>local_time</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#local_days"><code>local_days</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#local_seconds"><code>local_seconds</code></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td>types</td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#last_spec"><code>last_spec</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#day"><code>day</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#month"><code>month</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#year"><code>year</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#weekday"><code>weekday</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#weekday_indexed"><code>weekday_indexed</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#weekday_last"><code>weekday_last</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#month_day"><code>month_day</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#month_day_last"><code>month_day_last</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#month_weekday"><code>month_weekday</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#month_weekday_last"><code>month_weekday_last</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#year_month"><code>year_month</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#year_month_day"><code>year_month_day</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#year_month_day_last"><code>year_month_day_last</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#year_month_weekday"><code>year_month_weekday</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#year_month_weekday_last"><code>year_month_weekday_last</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#time_of_day"><code>time_of_day</code></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td>conventional syntax<br/>operators</td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_1"><code>constexpr year_month operator/(const year& y, const month& m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_2"><code>constexpr year_month operator/(const year& y, int m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_3"><code>constexpr month_day operator/(const month& m, const day& d) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_4"><code>constexpr month_day operator/(const month& m, int d) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_5"><code>constexpr month_day operator/(int m, const day& d) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_6"><code>constexpr month_day operator/(const day& d, const month& m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_7"><code>constexpr month_day operator/(const day& d, int m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_8"><code>constexpr month_day_last operator/(const month& m, last_spec) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_9"><code>constexpr month_day_last operator/(int m, last_spec) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_10"><code>constexpr month_day_last operator/(last_spec, const month& m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_11"><code>constexpr month_day_last operator/(last_spec, int m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_12"><code>constexpr month_weekday operator/(const month& m, const weekday_indexed& wdi) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_13"><code>constexpr month_weekday operator/(int m, const weekday_indexed& wdi) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_14"><code>constexpr month_weekday operator/(const weekday_indexed& wdi, const month& m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_15"><code>constexpr month_weekday operator/(const weekday_indexed& wdi, int m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_16"><code>constexpr month_weekday_last operator/(const month& m, const weekday_last& wdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_17"><code>constexpr month_weekday_last operator/(int m, const weekday_last& wdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_18"><code>constexpr month_weekday_last operator/(const weekday_last& wdl, const month& m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_19"><code>constexpr month_weekday_last operator/(const weekday_last& wdl, int m) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_20"><code>constexpr year_month_day operator/(const year_month& ym, const day& d) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_21"><code>constexpr year_month_day operator/(const year_month& ym, int d) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_22"><code>constexpr year_month_day operator/(const year& y, const month_day& md) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_23"><code>constexpr year_month_day operator/(int y, const month_day& md) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_24"><code>constexpr year_month_day operator/(const month_day& md, const year& y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_25"><code>constexpr year_month_day operator/(const month_day& md, int y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_26"><code>constexpr year_month_day_last operator/(const year_month& ym, last_spec) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_27"><code>constexpr year_month_day_last operator/(const year& y, const month_day_last& mdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_28"><code>constexpr year_month_day_last operator/(int y, const month_day_last& mdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_29"><code>constexpr year_month_day_last operator/(const month_day_last& mdl, const year& y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_30"><code>constexpr year_month_day_last operator/(const month_day_last& mdl, int y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_31"><code>constexpr year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_32"><code>constexpr year_month_weekday operator/(const year& y, const month_weekday& mwd) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_33"><code>constexpr year_month_weekday operator/(int y, const month_weekday& mwd) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_34"><code>constexpr year_month_weekday operator/(const month_weekday& mwd, const year& y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_35"><code>constexpr year_month_weekday operator/(const month_weekday& mwd, int y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_36"><code>constexpr year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_37"><code>constexpr year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_38"><code>constexpr year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_39"><code>constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept;</code></a></td></tr>
|
|
<tr><td> </td><td><a href="#_40"><code>constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept;</code></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td><code>time_of_day</code><br/> factory function</td><td> </td></tr>
|
|
<tr><td> </td><td><a href="#_41">
|
|
<pre>
|
|
template <class Rep, class Period>
|
|
constexpr
|
|
time_of_day<std::chrono::duration<Rep, Period>>
|
|
make_time(std::chrono::duration<Rep, Period> d) noexcept;
|
|
</pre></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td>convenience<br/>streaming operators</td><td> </td></tr>
|
|
|
|
<tr><td> </td><td><a href="#_46">
|
|
<pre>
|
|
template <class CharT, class Traits, class Duration>
|
|
std::basic_ostream<CharT, Traits>&
|
|
operator<<(std::basic_ostream<CharT, Traits>& os, const sys_time<Duration>& tp);
|
|
</pre></a></td></tr>
|
|
|
|
<tr><td> </td><td><a href="#_47">
|
|
<pre>
|
|
template <class CharT, class Traits, class Duration>
|
|
std::basic_ostream<CharT, Traits>&
|
|
operator<<(std::basic_ostream<CharT, Traits>& os, const local_time<Duration>& tp);
|
|
</pre></a></td></tr>
|
|
|
|
<tr><td> </td><td> </td></tr>
|
|
<tr><td><a href="#to_stream_formatting"><code>to_stream</code> formatting</a></td><td> </td></tr>
|
|
<tr><td><a href="#format"><code>format</code></a></td><td> </td></tr>
|
|
<tr><td><a href="#from_stream_formatting"><code>from_stream</code> formatting</a></td><td> </td></tr>
|
|
<tr><td><a href="#parse"><code>parse</code></a></td><td> </td></tr>
|
|
|
|
</table>
|
|
|
|
<p>
|
|
Everything here is contained in the namespace <code>date</code>. The literal operators,
|
|
and the constexpr field literals (e.g. <code>sun</code>, <code>jan</code>, etc.) are
|
|
in namespace <code>date::literals</code> and imported into namespace <code>date</code>.
|
|
</p>
|
|
|
|
<a name="days"></a><h3><code>days</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>days</code> is a <code>std::chrono::duration</code> with a tick period of 24 hours.
|
|
This definition is not an SI unit but <a
|
|
href="http://www.bipm.org/en/publications/si-brochure/table6.html">is accepted for use
|
|
with SI</a>. <code>days</code> is the resultant type when subtracting two
|
|
<code>sys_days</code>s.
|
|
</p>
|
|
<pre>
|
|
using days = std::chrono::duration
|
|
<int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
|
|
</pre></blockquote>
|
|
|
|
<a name="weeks"></a><h3><code>weeks</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>weeks</code> is a <code>std::chrono::duration</code> with a tick period of 7 days.
|
|
This definition is widely recognized and predates the Gregorian calendar. It is
|
|
consistent with <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>.
|
|
<code>weeks</code> will implicitly convert to <code>days</code> but not vice-versa.
|
|
</p>
|
|
<pre>
|
|
using weeks = std::chrono::duration
|
|
<int, std::ratio_multiply<std::ratio<7>, days::period>>;
|
|
</pre></blockquote>
|
|
|
|
<a name="years"></a><h3><code>years</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>years</code> is a <code>std::chrono::duration</code> with a tick period of 365.2425
|
|
days. This definition accurately describes the length of the average year in the
|
|
Gregorian calendar. <code>years</code> is the resultant type when subtracting two
|
|
<code>year</code> field-based time points. <code>years</code> is not implicitly
|
|
convertible to <code>days</code> or <code>weeks</code> nor vice-versa. However
|
|
<code>years</code> will implicitly convert to <code>months</code>.
|
|
</p>
|
|
<pre>
|
|
using years = std::chrono::duration
|
|
<int, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;
|
|
</pre></blockquote>
|
|
|
|
<a name="months"></a><h3><code>months</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>months</code> is a <code>std::chrono::duration</code> with a tick period of
|
|
<sup>1</sup>/<sub>12</sub> of a year. This definition accurately describes the length of
|
|
the average month in the Gregorian calendar. <code>months</code> is the resultant type
|
|
when subtracting two <code>month</code> field-based time points. <code>months</code> is
|
|
not implicitly convertible to <code>days</code> or <code>weeks</code> nor vice-versa.
|
|
<code>months</code> will not implicitly convert to <code>years</code>.
|
|
</p>
|
|
<pre>
|
|
using months = std::chrono::duration
|
|
<int, std::ratio_divide<years::period, std::ratio<12>>>;
|
|
</pre></blockquote>
|
|
|
|
<a name="duration_io"></a><h3>Formatting and parsing durations</h3>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Rep, class Period>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
const std::chrono::duration<Rep, Period>& d);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>d</code>, converted to the
|
|
<code>common_type<duration, seconds></code> into <code>os</code> using the format
|
|
string <code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%H</code>, <code>%I</code>, <code>%M</code>, <code>%p</code>, <code>%r</code>,
|
|
<code>%R</code>, <code>%S</code>, <code>%T</code>, <code>%X</code>, <code>%n</code>,
|
|
<code>%t</code> or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Rep, class Period, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
std::chrono::duration<Rep, Period>& d,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>d</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%H</code>, <code>%I</code>, <code>%M</code>, <code>%p</code>,
|
|
<code>%r</code>, <code>%R</code>, <code>%S</code>, <code>%T</code>, <code>%X</code>,
|
|
<code>%n</code>, <code>%t</code>, <code>%z</code>, <code>%Z</code> or <code>%%</code>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Rep, class Period>
|
|
std::basic_ostream<CharT, Traits>&
|
|
operator<<(std::basic_ostream<CharT, Traits>& os,
|
|
const std::chrono::duration<Rep, Period>& d);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Equivalent to:
|
|
</p>
|
|
<blockquote><pre>
|
|
os << to_string<CharT, Traits>(d.count()) + detail::get_units<CharT>(duration<Rep, typename Period::type>{});
|
|
</pre>
|
|
<p>
|
|
Where <code>to_string</code> is pseudo code that returns a
|
|
<code>std::basic_string<CharT, Traits></code> representation of <code>d.count()</code>,
|
|
and <code>detail::get_units<CharT>()</code> returns a null-terminated string of
|
|
<code>CharT</code> which depends only 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>std::atto</code>, <code>as</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::femto</code>, <code>fs</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::pico</code>, <code>ps</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::nano</code>, <code>ns</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::micro</code>, <code>µs</code> (U+00B5), else</li>
|
|
<li>if <code>period</code> is type <code>std::milli</code>, <code>ms</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::centi</code>, <code>cs</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::deci</code>, <code>ds</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::ratio<1></code>, <code>s</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::deca</code>, <code>das</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::hecto</code>, <code>hs</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::kilo</code>, <code>ks</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::mega</code>, <code>Ms</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::giga</code>, <code>Gs</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::tera</code>, <code>Ts</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::peta</code>, <code>Ps</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::exa</code>, <code>Es</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::ratio<60></code>, <code>min</code>, else</li>
|
|
<li>if <code>period</code> is type <code>std::ratio<3600></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>
|
|
|
|
</blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="sys_time"></a><h3><code>sys_time</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>sys_time</code> is a convenience template alias for creating a
|
|
<code>system_clock::time_point</code> but of arbitrary precision. This family of types
|
|
represents "system time", which closely models UTC. See <code>utc_time</code> in
|
|
<a href="tz.html">tz.h</a> for a variation of <code>sys_time</code> that accurately takes
|
|
leap seconds into account when subtracting <code>time_point</code>s.
|
|
</p>
|
|
<pre>
|
|
template <class Duration>
|
|
using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sys_days"></a><h3><code>sys_days</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>sys_days</code> is a <code>std::chrono::time_point</code> using
|
|
<code>std::chrono::system_clock</code> and <code>days</code>. This makes
|
|
<code>sys_days</code> interoperable with
|
|
<code>std::chrono::system_clock::time_point</code>. It is simply a count of days since
|
|
the epoch of <code>std::chrono::system_clock</code> which in every implementation is
|
|
Jan. 1, 1970. <code>sys_days</code> is a serial-based time point with a resolution of
|
|
<code>days</code>.
|
|
</p>
|
|
<pre>
|
|
using sys_days = sys_time<days>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sys_seconds"></a><h3><code>sys_seconds</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>sys_seconds</code> is a <code>std::chrono::time_point</code> using
|
|
<code>std::chrono::system_clock</code> and <code>std::chrono::seconds</code>.
|
|
This makes <code>sys_seconds</code> interoperable with
|
|
<code>std::chrono::system_clock::time_point</code>. It is simply a count of
|
|
<i>non-leap</i> seconds since the epoch of
|
|
<code>std::chrono::system_clock</code> which in every implementation is Jan. 1,
|
|
1970 00:00:00 UTC. <code>sys_seconds</code> is a serial-based time point with a
|
|
resolution of <code>seconds</code>. <code>sys_seconds</code> is also widely known
|
|
as <a href="href="http://en.wikipedia.org/wiki/Unix_time"">Unix Time</a>.
|
|
</p>
|
|
<pre>
|
|
using sys_seconds = sys_time<std::chrono::seconds>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Duration>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
const sys_time<Duration>& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>tp</code>, converted to the
|
|
<code>common_type<Duration, seconds></code> into <code>os</code> using the format
|
|
string <code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. If
|
|
<code>%Z</code> is in the formatting string <code>"UTC"</code> will be used. If
|
|
<code>%z</code> is in the formatting string <code>"+0000"</code> will be used.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
sys_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>tp</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>.
|
|
If <code>%z</code> is present, the parsed offset will be subtracted from the parsed time.
|
|
If <code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>. If an invalid date
|
|
is parsed, or a time of day which is outside of the conventional bounds, <code>failbit</code>
|
|
will be set and <code>tp</code> will not be altered.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="local_time"></a><h3><code>local_time</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>local_time</code> is a convenience template alias for creating a
|
|
<code>time_point</code> of arbitrary precision which is not based on any clock at all.
|
|
This family of types represents a time not associated with any time zone. It is handy
|
|
in disambiguating calendar timestamps referring to an unspecified timezone, and those
|
|
referring to UTC.
|
|
</p>
|
|
<p>
|
|
For example, we can say that the upcoming 2017 New Years will be commonly
|
|
celebrated at <code>local_time<days>{2017_y/jan/1} + 0s</code>. For those
|
|
in a time zone with a zero offset from UTC, it will be celebrated at the
|
|
concrete time of <code>sys_days{2017_y/jan/1} + 0s</code>. These two timestamps
|
|
have different types, though both have the exact same representation (a count of
|
|
seconds), because they mean two <i>subtly</i> different things, and are both
|
|
<i>quite</i> useful.
|
|
</p>
|
|
|
|
<pre>
|
|
struct local_t {};
|
|
|
|
template <class Duration>
|
|
using local_time = std::chrono::time_point<local_t, Duration>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="local_days"></a><h3><code>local_days</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>local_days</code> is a convient way to write <code>local_time<days></code>.
|
|
The upcoming 2017 New Years will be commonly celebrated at
|
|
<code>local_days{2017_y/jan/1} + 0s</code>.
|
|
</p>
|
|
|
|
<pre>
|
|
using local_days = local_time<days>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="local_seconds"></a><h3><code>local_seconds</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>local_seconds</code> is a convient way to write <code>local_time<seconds></code>.
|
|
</p>
|
|
|
|
<pre>
|
|
using local_seconds = local_time<std::chrono::seconds>;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Duration>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
const local_time<Duration>& tp, const std::string* abbrev = nullptr,
|
|
const std::chrono::seconds* offset_sec = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>tp</code>, converted to the
|
|
<code>common_type<Duration, seconds></code> into <code>os</code> using the format
|
|
string <code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. If
|
|
<code>%Z</code> is in the formatting string <code>*abbrev</code> will be used. If
|
|
<code>%z</code> is in the formatting string <code>*offset_sec</code> will be used.
|
|
</p>
|
|
|
|
<p>
|
|
If <code>%Z</code> is in the formatting string and <code>abbrev == nullptr</code>, or if
|
|
<code>%z</code> is in the formatting string and <code>offset_sec == nullptr</code>,
|
|
<code>failbit</code> will be set for <code>os</code>.
|
|
</p>
|
|
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
local_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>tp</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>.
|
|
If <code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>. If an invalid date
|
|
is parsed, or a time of day which is outside of the conventional bounds, <code>failbit</code>
|
|
will be set and <code>tp</code> will not be altered.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="last_spec"></a><h3><code>last_spec</code></h3>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<code>last_spec</code> is a <code>struct</code> that is <code>CopyConstructible</code>.
|
|
There exists a <code>constexpr</code> instance of <code>last_spec</code> named
|
|
<code>last</code>. This is simply a tag type. It is used to indicate the last day of
|
|
a month, or the last weekday of a month.
|
|
</p>
|
|
<pre>
|
|
struct last_spec
|
|
{
|
|
explicit last_spec() = default;
|
|
};
|
|
inline namespace literals
|
|
{
|
|
constexpr last_spec last{};
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="day"></a><h3><code>day</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class day
|
|
{
|
|
unsigned char d_; // exposition only
|
|
public:
|
|
day() = default;
|
|
explicit constexpr day(unsigned d) noexcept;
|
|
|
|
constexpr day& operator++() noexcept;
|
|
constexpr day operator++(int) noexcept;
|
|
constexpr day& operator--() noexcept;
|
|
constexpr day operator--(int) noexcept;
|
|
|
|
constexpr day& operator+=(const days& d) noexcept;
|
|
constexpr day& operator-=(const days& d) noexcept;
|
|
|
|
constexpr explicit operator unsigned() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const day& x, const day& y) noexcept;
|
|
constexpr bool operator!=(const day& x, const day& y) noexcept;
|
|
constexpr bool operator< (const day& x, const day& y) noexcept;
|
|
constexpr bool operator> (const day& x, const day& y) noexcept;
|
|
constexpr bool operator<=(const day& x, const day& y) noexcept;
|
|
constexpr bool operator>=(const day& x, const day& y) noexcept;
|
|
|
|
constexpr day operator+(const day& x, const days& y) noexcept;
|
|
constexpr day operator+(const days& x, const day& y) noexcept;
|
|
constexpr day operator-(const day& x, const days& y) noexcept;
|
|
constexpr days operator-(const day& x, const day& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const day& d);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const day& d);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, day& d,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
|
|
inline namespace literals {
|
|
constexpr day operator "" _d(unsigned long long d) noexcept;
|
|
}
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<p>
|
|
<code>day</code> represents a day of a month. It should only be representing values in
|
|
the range 1 to 31. However it may hold 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 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> for debugging purposes.
|
|
<code>day</code> has explicit conversions to and from <code>unsigned</code>.
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>day</code> is a trivially copyable class type.<br/>
|
|
<code>day</code> is a standard-layout class type.<br/>
|
|
<code>day</code> is a literal 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>. The value held is unspecified if <code>d</code>
|
|
is not in the range <code>[0, 255]</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr day& 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& 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& day::operator+=(const days& 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& day::operator-=(const days& 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& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>unsigned{x} < unsigned{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr day operator+(const day& x, const days& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>day{unsigned{x} + y.count()}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr day operator+(const days& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y + x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr day operator-(const day& x, const days& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x + -y</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr days operator-(const day& x, const day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>days{static_cast<days::rep>(unsigned{x} - unsigned{y})}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr day operator "" _d(unsigned long long d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>day{static_cast<unsigned>(d)}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const day& 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<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const day& d);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>d</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%d</code>, <code>%e</code>, <code>%n</code>, <code>%t</code>
|
|
or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, day& d,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>d</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%e</code>, <code>%e</code>, <code>%n</code>,
|
|
<code>%t</code>, <code>%z</code>, <code>%Z</code> or <code>%%</code>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="month"></a><h3><code>month</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class month
|
|
{
|
|
unsigned char m_; // exposition only
|
|
public:
|
|
month() = default;
|
|
explicit constexpr month(unsigned m) noexcept;
|
|
|
|
constexpr month& operator++() noexcept;
|
|
constexpr month operator++(int) noexcept;
|
|
constexpr month& operator--() noexcept;
|
|
constexpr month operator--(int) noexcept;
|
|
|
|
constexpr month& operator+=(const months& m) noexcept;
|
|
constexpr month& operator-=(const months& m) noexcept;
|
|
|
|
constexpr explicit operator unsigned() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const month& x, const month& y) noexcept;
|
|
constexpr bool operator!=(const month& x, const month& y) noexcept;
|
|
constexpr bool operator< (const month& x, const month& y) noexcept;
|
|
constexpr bool operator> (const month& x, const month& y) noexcept;
|
|
constexpr bool operator<=(const month& x, const month& y) noexcept;
|
|
constexpr bool operator>=(const month& x, const month& y) noexcept;
|
|
|
|
constexpr month operator+(const month& x, const months& y) noexcept;
|
|
constexpr month operator+(const months& x, const month& y) noexcept;
|
|
constexpr month operator-(const month& x, const months& y) noexcept;
|
|
constexpr months operator-(const month& x, const month& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month& m);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const month& m);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month& m,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
|
|
inline namespace literals {
|
|
constexpr month jan{1};
|
|
constexpr month feb{2};
|
|
constexpr month mar{3};
|
|
constexpr month apr{4};
|
|
constexpr month may{5};
|
|
constexpr month jun{6};
|
|
constexpr month jul{7};
|
|
constexpr month aug{8};
|
|
constexpr month sep{9};
|
|
constexpr month oct{10};
|
|
constexpr month nov{11};
|
|
constexpr month dec{12};
|
|
}
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<p>
|
|
<code>month</code> represents a month of a year. It should only be representing values in
|
|
the range 1 to 12. However it may hold 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 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>
|
|
for debugging purposes. <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.
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>month</code> is a trivially copyable class type.<br/>
|
|
<code>month</code> is a standard-layout class type.<br/>
|
|
<code>month</code> is a literal 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>. The value held is unspecified if <code>m</code>
|
|
is not in the range <code>[0, 255]</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr month& month::operator++() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> If <code>m_ != 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& month::operator--() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> If <code>m_ != 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& month::operator+=(const months& 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& month::operator-=(const months& 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& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>unsigned{x} < unsigned{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr month operator+(const month& x, const months& 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 < 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>. — <i>end note</i>]
|
|
</p>
|
|
<p>
|
|
<i>Complexity:</i> O(1) with respect to the value of <code>y</code>. That is, repeated
|
|
increments or decrements is not a valid implementation.
|
|
</p>
|
|
<p>
|
|
<i>Example:</i> <code>feb + months{11} == jan</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr month operator+(const months& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y + x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr month operator-(const month& x, const months& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x + -y</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr months operator-(const month& x, const month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.ok() == true</code> and <code>y.ok() == true</code>,
|
|
returns a value of <code>months</code> in the range of <code>months{0}</code> to
|
|
<code>months{11}</code> inclusive. Otherwise the value returned is unspecified.
|
|
</p>
|
|
<p>
|
|
<i>Remarks:</i> If <code>x.ok() == true</code> and <code>y.ok() == true</code>,
|
|
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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month& 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} << " is not a valid month"</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const month& m);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>m</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%b</code>, <code>%B</code>, <code>%h</code>, <code>%m</code>, <code>%n</code>,
|
|
<code>%t</code> or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month& m,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>m</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%b</code>, <code>%B</code>, <code>%h</code>, <code>%m</code>,
|
|
<code>%n</code>, <code>%t</code>, <code>%z</code>, <code>%Z</code> or <code>%%</code>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year"></a><h3><code>year</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year
|
|
{
|
|
short y_; // exposition only
|
|
public:
|
|
year() = default;
|
|
explicit constexpr year(int y) noexcept;
|
|
|
|
constexpr year& operator++() noexcept;
|
|
constexpr year operator++(int) noexcept;
|
|
constexpr year& operator--() noexcept;
|
|
constexpr year operator--(int) noexcept;
|
|
|
|
constexpr year& operator+=(const years& y) noexcept;
|
|
constexpr year& operator-=(const years& y) noexcept;
|
|
|
|
constexpr 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& x, const year& y) noexcept;
|
|
constexpr bool operator!=(const year& x, const year& y) noexcept;
|
|
constexpr bool operator< (const year& x, const year& y) noexcept;
|
|
constexpr bool operator> (const year& x, const year& y) noexcept;
|
|
constexpr bool operator<=(const year& x, const year& y) noexcept;
|
|
constexpr bool operator>=(const year& x, const year& y) noexcept;
|
|
|
|
constexpr year operator+(const year& x, const years& y) noexcept;
|
|
constexpr year operator+(const years& x, const year& y) noexcept;
|
|
constexpr year operator-(const year& x, const years& y) noexcept;
|
|
constexpr years operator-(const year& x, const year& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year& y);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year& y);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year& y,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
|
|
inline namespace literals {
|
|
constexpr year operator "" _y(unsigned long long y) noexcept;
|
|
}
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<p>
|
|
<code>year</code> represents a year in the Gregorian 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 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> for debugging purposes.
|
|
<code>year</code> has explicit conversions to and from <code>int</code>.
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>year</code> is a trivially copyable class type.<br/>
|
|
<code>year</code> is a standard-layout class type.<br/>
|
|
<code>year</code> is a literal 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>. The value held is unspecified if <code>y</code>
|
|
is not in the range <code>[-32767, 32767]</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year& 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& 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& year::operator+=(const years& 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::operator-=(const years& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> <code>*this = *this - y</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constepxr year year::operator-() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>year{-y_}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constepxr year year::operator+() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool year::is_leap() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>true</code> if <code>*this</code> represents a leap year, else
|
|
returns <code>false</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>true</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
static constexpr year year::min() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>year{-32767}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
static constexpr year year::max() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>year{32767}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>int{x} == int{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>int{x} < int{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year operator+(const year& x, const years& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>year{int{x} + y.count()}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year operator+(const years& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y + x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year operator-(const year& x, const years& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x + -y</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr years operator-(const year& x, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>years{int{x} - int{y}}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year operator "" _y(unsigned long long y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>year{static_cast<int>(y)}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year& 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 less than four decimal digits, pads 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<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year& y);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>y</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%C</code>, <code>%y</code>, <code>%Y</code>, <code>%n</code>, <code>%t</code>
|
|
or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year& y,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>y</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%C</code>, <code>%y</code>, <code>%Y</code>, <code>%n</code>,
|
|
<code>%t</code>, <code>%z</code>, <code>%Z</code> or <code>%%</code>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="weekday"></a><h3><code>weekday</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class weekday
|
|
{
|
|
unsigned char wd_; // exposition only
|
|
public:
|
|
weekday() = default;
|
|
explicit constexpr weekday(unsigned wd) noexcept;
|
|
constexpr weekday(const sys_days& dp) noexcept;
|
|
constexpr explicit weekday(const local_days& dp) noexcept;
|
|
|
|
constexpr weekday& operator++() noexcept;
|
|
constexpr weekday operator++(int) noexcept;
|
|
constexpr weekday& operator--() noexcept;
|
|
constexpr weekday operator--(int) noexcept;
|
|
|
|
constexpr weekday& operator+=(const days& d) noexcept;
|
|
constexpr weekday& operator-=(const days& d) noexcept;
|
|
|
|
constexpr explicit operator unsigned() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
constexpr weekday_indexed operator[](unsigned index) const noexcept;
|
|
constexpr weekday_last operator[](last_spec) const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
|
|
constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
|
|
|
|
constexpr weekday operator+(const weekday& x, const days& y) noexcept;
|
|
constexpr weekday operator+(const days& x, const weekday& y) noexcept;
|
|
constexpr weekday operator-(const weekday& x, const days& y) noexcept;
|
|
constexpr days operator-(const weekday& x, const weekday& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday& wd);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const weekday& wd);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, weekday& wd,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
|
|
inline namespace literals {
|
|
constexpr weekday sun{0};
|
|
constexpr weekday mon{1};
|
|
constexpr weekday tue{2};
|
|
constexpr weekday wed{3};
|
|
constexpr weekday thu{4};
|
|
constexpr weekday fri{5};
|
|
constexpr weekday sat{6};
|
|
}
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<p>
|
|
<code>weekday</code> represents a day of the week in the Gregorian calendar. It should
|
|
only be representing values in the range 0 to 6, corresponding to Sunday thru Saturday.
|
|
However it may hold 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 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 thru 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> for debugging purposes. <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.
|
|
</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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>weekday</code> is a trivially copyable class type.<br/>
|
|
<code>weekday</code> is a standard-layout class type.<br/>
|
|
<code>weekday</code> is a literal 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>. The value held is unspecified if <code>wd</code>
|
|
is not in the range <code>[0, 255]</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr weekday(const sys_days& 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> shall represent Thursday by storing 4 in <code>wd_</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit weekday(const local_days& 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& 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& 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& weekday::operator+=(const days& 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& weekday::operator-=(const days& 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& x, const weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>unsigned{x} == unsigned{y}</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const weekday& x, const weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr weekday operator+(const weekday& x, const days& 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 < 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>. — <i>end note</i>]
|
|
</p>
|
|
<p>
|
|
<i>Complexity:</i> O(1) with respect to the value of <code>y</code>. That is, repeated
|
|
increments or decrements is not a valid implementation.
|
|
</p>
|
|
<p>
|
|
<i>Example:</i> <code>mon + days{6} == sun</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr weekday operator+(const days& x, const weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y + x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr weekday operator-(const weekday& x, const days& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x + -y</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr days operator-(const weekday& x, const weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.ok() == true</code> and <code>y.ok() == true</code>,
|
|
returns a value of <code>days</code> in the range of <code>days{0}</code> to
|
|
<code>days{6}</code> inclusive. Otherwise the value returned is unspecified.
|
|
</p>
|
|
<p>
|
|
<i>Remarks:</i> If <code>x.ok() == true</code> and <code>y.ok() == true</code>,
|
|
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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday& 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} << " is not a valid weekday"</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const weekday& wd);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>wd</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%a</code>, <code>%A</code>, <code>%u</code>, <code>%w</code>, <code>%n</code>,
|
|
<code>%t</code> or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, weekday& wd,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>wd</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%a</code>, <code>%A</code>, <code>%u</code>, <code>%w</code>, <code>%n</code>,
|
|
<code>%t</code>, <code>%z</code>, <code>%Z</code> or <code>%%</code>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="weekday_indexed"></a><h3><code>weekday_indexed</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class weekday_indexed
|
|
{
|
|
date::weekday wd_; // exposition only
|
|
unsigned char index_; // exposition only
|
|
|
|
public:
|
|
constexpr weekday_indexed(const date::weekday& wd, unsigned index) noexcept;
|
|
|
|
constexpr date::weekday weekday() const noexcept;
|
|
constexpr unsigned index() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
|
|
constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday_indexed& wdi);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
— <i>end example:</i>]
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>weekday_indexed</code> is a trivially copyable class type.<br/>
|
|
<code>weekday_indexed</code> is a standard-layout class type.<br/>
|
|
<code>weekday_indexed</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr weekday_indexed::weekday_indexed(const date::weekday& 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>.
|
|
The values held are unspecified if <code>!wd.ok()</code> or <code>index</code> is not
|
|
in the range <code>[1, 5]</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() && 1 <= index_ && index_ <= 5</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& 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& x, const weekday_indexed& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday_indexed& wdi);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << wdi.weekday() << '[' << wdi.index() << ']'</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="weekday_last"></a><h3><code>weekday_last</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class weekday_last
|
|
{
|
|
date::weekday wd_; // exposition only
|
|
|
|
public:
|
|
explicit constexpr weekday_last(const date::weekday& wd) noexcept;
|
|
|
|
constexpr date::weekday weekday() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
|
|
constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday_last& wdl);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
— <i>end example:</i>]
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>weekday_last</code> is a trivially copyable class type.<br/>
|
|
<code>weekday_last</code> is a standard-layout class type.<br/>
|
|
<code>weekday_last</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
explicit constexpr weekday_last::weekday_last(const date::weekday& 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& x, const weekday_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.weekday() == y.weekday()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const weekday_last& wdl);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << wdi.weekday() << "[last]"</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="month_day"></a><h3><code>month_day</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class month_day
|
|
{
|
|
date::month m_; // exposition only
|
|
date::day d_; // exposition only
|
|
|
|
public:
|
|
month_day() = default;
|
|
constexpr month_day(const date::month& m, const date::day& d) noexcept;
|
|
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::day day() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
|
|
constexpr bool operator!=(const month_day& x, const month_day& y) noexcept;
|
|
constexpr bool operator< (const month_day& x, const month_day& y) noexcept;
|
|
constexpr bool operator> (const month_day& x, const month_day& y) noexcept;
|
|
constexpr bool operator<=(const month_day& x, const month_day& y) noexcept;
|
|
constexpr bool operator>=(const month_day& x, const month_day& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_day& md);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const month_day& md);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month_day& md,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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> for
|
|
debugging purposes.
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>month_day</code> is a trivially copyable class type.<br/>
|
|
<code>month_day</code> is a standard-layout class type.<br/>
|
|
<code>month_day</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr month_day::month_day(const date::month& m, const date::day& 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>1_d <= d_</code>, and if <code>d_ <=</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& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.month() == y.month() && x.day() == y.day()</code>
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const month_day& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const month_day& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.month() < y.month()</code> returns <code>true</code>. Else
|
|
if <code>x.month() > y.month()</code> returns <code>false</code>. Else returns
|
|
<code>x.day() < y.day()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const month_day& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const month_day& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const month_day& x, const month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_day& md);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << md.month() << '/' << md.day()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const month_day& md);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>md</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%b</code>, <code>%B</code>, <code>%d</code>, <code>%e</code>, <code>%h</code>,
|
|
<code>%m</code>, <code>%n</code>, <code>%t</code> or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, month_day& md,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>md</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%b</code>, <code>%B</code>, <code>%d</code>, <code>%e</code>,
|
|
<code>%h</code>, <code>%m</code>, <code>%n</code>, <code>%t</code>, <code>%z</code>,
|
|
<code>%Z</code> or <code>%%</code>. If <code>abbrev</code> is not equal to
|
|
<code>nullptr</code>, the information parsed by <code>%Z</code> (if present) will be
|
|
placed in <code>*abbrev</code>. If <code>offset</code> is not equal to
|
|
<code>nullptr</code>, the information parsed by <code>%z</code> (if present) will be
|
|
placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="month_day_last"></a><h3><code>month_day_last</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class month_day_last
|
|
{
|
|
date::month m_; // exposition only
|
|
|
|
public:
|
|
constexpr explicit month_day_last(const date::month& m) noexcept;
|
|
|
|
constexpr date::month month() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
|
|
constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept;
|
|
constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept;
|
|
constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_day_last& mdl);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
— <i>end example:</i>]
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>month_day_last</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr explicit month_day_last::month_day_last(const date::month& 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& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.month() == y.month()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.month() < y.month()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_day_last& mdl);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << mdl.month() << "/last"</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="month_weekday"></a><h3><code>month_weekday</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class month_weekday
|
|
{
|
|
date::month m_; // exposition only
|
|
date::weekday_indexed wdi_; // exposition only
|
|
public:
|
|
constexpr month_weekday(const date::month& m, const date::weekday_indexed& wdi) noexcept;
|
|
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::weekday_indexed weekday_indexed() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
|
|
constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_weekday& mwd);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>month_weekday</code> is a trivially copyable class type.<br/>
|
|
<code>month_weekday</code> is a standard-layout class type.<br/>
|
|
<code>month_weekday</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr month_weekday::month_weekday(const date::month& m, const date::weekday_indexed& 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() && wdi_.ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_weekday& mwd);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << mwd.month() << '/' << mwd.weekday_indexed()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="month_weekday_last"></a><h3><code>month_weekday_last</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class month_weekday_last
|
|
{
|
|
date::month m_; // exposition only
|
|
date::weekday_last wdl_; // exposition only
|
|
public:
|
|
constexpr month_weekday_last(const date::month& m,
|
|
const date::weekday_last& wdl) noexcept;
|
|
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::weekday_last weekday_last() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
|
|
constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_weekday_last& mwdl);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>month_weekday_last</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr month_weekday_last::month_weekday_last(const date::month& m,
|
|
const date::weekday_last& 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() && wdl_.ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.month() == y.month() && x.weekday_last() == y.weekday_last()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const month_weekday_last& mwdl);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << mwdl.month() << '/' << mwdl.weekday_last()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year_month"></a><h3><code>year_month</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year_month
|
|
{
|
|
date::year y_; // exposition only
|
|
date::month m_; // exposition only
|
|
|
|
public:
|
|
year_month() = default;
|
|
constexpr year_month(const date::year& y, const date::month& m) noexcept;
|
|
|
|
constexpr date::year year() const noexcept;
|
|
constexpr date::month month() const noexcept;
|
|
|
|
constexpr year_month& operator+=(const months& dm) noexcept;
|
|
constexpr year_month& operator-=(const months& dm) noexcept;
|
|
constexpr year_month& operator+=(const years& dy) noexcept;
|
|
constexpr year_month& operator-=(const years& dy) noexcept;
|
|
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
|
|
constexpr bool operator!=(const year_month& x, const year_month& y) noexcept;
|
|
constexpr bool operator< (const year_month& x, const year_month& y) noexcept;
|
|
constexpr bool operator> (const year_month& x, const year_month& y) noexcept;
|
|
constexpr bool operator<=(const year_month& x, const year_month& y) noexcept;
|
|
constexpr bool operator>=(const year_month& x, const year_month& y) noexcept;
|
|
|
|
constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
|
|
constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
|
|
constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
|
|
constexpr months operator-(const year_month& x, const year_month& y) noexcept;
|
|
constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
|
|
constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
|
|
constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month& ym);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year_month& ym);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month& ym,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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> for
|
|
debugging purposes.
|
|
</p>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<p>
|
|
<code>year_month</code> is a trivially copyable class type.<br/>
|
|
<code>year_month</code> is a standard-layout class type.<br/>
|
|
<code>year_month</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr year_month::year_month(const date::year& y, const date::month& 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& operator+=(const months& 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& operator-=(const months& 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& operator+=(const years& 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& operator-=(const years& 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() && m_.ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.year() == y.year() && x.month() == y.month()</code>
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.year() < y.year()</code> returns <code>true</code>. Else
|
|
if <code>x.year() > y.year()</code> returns <code>false</code>. Else returns
|
|
<code>x.month() < y.month()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const year_month& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < 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& x, const year_month& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The number of <code>months</code> one must add to <code>y</code> to get
|
|
<code>x</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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month& ym);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << ym.year() << '/' << ym.month()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year_month& ym);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>ym</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>. The behavior
|
|
is undefined except for the following flags (or modified versions of these flags):
|
|
<code>%b</code>, <code>%B</code>, <code>%C</code>, <code>%h</code>, <code>%m</code>,
|
|
<code>%y</code>, <code>%Y</code>, <code>%n</code>, <code>%t</code> or <code>%%</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month& ym,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>ym</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. The
|
|
behavior is undefined except for the following flags (or modified versions of these
|
|
flags): <code>%b</code>, <code>%B</code>, <code>%C</code>, <code>%h</code>,
|
|
<code>%m</code>, <code>%y</code>, <code>%Y</code>, <code>%n</code>, <code>%t</code>,
|
|
<code>%z</code>, <code>%Z</code> or <code>%%</code>. If <code>abbrev</code> is not equal
|
|
to <code>nullptr</code>, the information parsed by <code>%Z</code> (if present) will be
|
|
placed in <code>*abbrev</code>. If <code>offset</code> is not equal to
|
|
<code>nullptr</code>, the information parsed by <code>%z</code> (if present) will be
|
|
placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year_month_day"></a><h3><code>year_month_day</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year_month_day
|
|
{
|
|
date::year y_; // exposition only
|
|
date::month m_; // exposition only
|
|
date::day d_; // exposition only
|
|
|
|
public:
|
|
year_month_day() = default;
|
|
constexpr year_month_day(const date::year& y, const date::month& m, const date::day& d) noexcept;
|
|
constexpr year_month_day(const year_month_day_last& ymdl) noexcept;
|
|
constexpr year_month_day(const sys_days& dp) noexcept;
|
|
constexpr explicit year_month_day(const local_days& dp) noexcept;
|
|
|
|
constexpr year_month_day& operator+=(const months& m) noexcept;
|
|
constexpr year_month_day& operator-=(const months& m) noexcept;
|
|
constexpr year_month_day& operator+=(const years& y) noexcept;
|
|
constexpr year_month_day& operator-=(const years& y) noexcept;
|
|
|
|
constexpr date::year year() const noexcept;
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::day day() const noexcept;
|
|
|
|
constexpr operator sys_days() const noexcept;
|
|
constexpr explicit operator local_days() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
|
|
constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
|
|
constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept;
|
|
constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
|
|
constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
|
|
constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
|
|
constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
|
|
constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
|
|
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
|
|
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_day& ymd);
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year_month_day& ymd);
|
|
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month_day& ymd,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>year_month_day</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr year_month_day::year_month_day(const date::year& y, const date::month& m, const date::day& 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& 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& 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& 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& year_month_day::operator+=(const months& 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& year_month_day::operator-=(const months& 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& year_month_day::operator+=(const years& 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& year_month_day::operator-=(const years& 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>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 if <code>y_.ok() && m_.ok() == true</code> 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>.
|
|
Otherwise the value returned is unspecified.
|
|
</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>
|
|
—<i>end example</i>]
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit year_month_day::operator local_days() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<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>[1_d, (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& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.year() == y.year() && x.month() == y.month() && x.day() == y.day()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.year() < y.year()</code>, returns <code>true</code>. Else
|
|
if <code>x.year() > y.year()</code> returns <code>false</code>.
|
|
Else if <code>x.month() < y.month()</code>, returns <code>true</code>.
|
|
Else if <code>x.month() > y.month()</code>, returns <code>false</code>.
|
|
Else returns <code>x.day() < y.day()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<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>[1_d, 28_d]</code>,
|
|
the resultant <code>year_month_day</code> is guaranteed to return <code>true</code> from
|
|
<code>ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymd + dm</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymd + (-dm)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator+(const year_month_day& ymd, const years& 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>[1_d, 28_d]</code>, the resultant <code>year_month_day</code> is
|
|
not guaranteed to return <code>true</code> from <code>ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymd + dy</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymd + (-dy)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_day& 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<class CharT, class Traits>
|
|
std::basic_ostream<CharT, Traits>&
|
|
to_stream(std::basic_ostream<class CharT, class Traits>& os, const CharT* fmt,
|
|
const year_month_day& ymd);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts <code>ymd</code> into <code>os</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#to_stream_formatting"><code>to_stream</code> formatting flags</a>.
|
|
</p>
|
|
<p>
|
|
If <code>%z</code> or <code>%Z</code> is used in the <code>fmt</code> string
|
|
<code>failbit</code> will be set for <code>os</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
std::basic_istream<CharT, Traits>&
|
|
from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt, year_month_day& ymd,
|
|
std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
std::chrono::minutes* offset = nullptr);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Extracts <code>ymd</code> from <code>is</code> using the format string
|
|
<code>fmt</code> as specified by the
|
|
<a href="#from_stream_formatting"><code>from_stream</code> formatting flags</a>. If
|
|
<code>abbrev</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%Z</code> (if present) will be placed in <code>*abbrev</code>. If
|
|
<code>offset</code> is not equal to <code>nullptr</code>, the information parsed by
|
|
<code>%z</code> (if present) will be placed in <code>*offset</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>is</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year_month_day_last"></a><h3><code>year_month_day_last</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year_month_day_last
|
|
{
|
|
date::year y_; // exposition only
|
|
date::month_day_last mdl_; // exposition only
|
|
|
|
public:
|
|
constexpr year_month_day_last(const date::year& y,
|
|
const date::month_day_last& mdl) noexcept;
|
|
|
|
constexpr year_month_day_last& operator+=(const months& m) noexcept;
|
|
constexpr year_month_day_last& operator-=(const months& m) noexcept;
|
|
constexpr year_month_day_last& operator+=(const years& y) noexcept;
|
|
constexpr year_month_day_last& operator-=(const years& y) noexcept;
|
|
|
|
constexpr date::year year() const noexcept;
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::month_day_last month_day_last() const noexcept;
|
|
constexpr date::day day() const noexcept;
|
|
|
|
constexpr operator sys_days() const noexcept;
|
|
constexpr explicit operator local_days() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
constexpr bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
constexpr bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
constexpr bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
constexpr bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
|
|
constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
|
|
constexpr year_month_day_last operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
|
|
constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
|
|
constexpr year_month_day_last operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
|
|
constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
|
|
constexpr year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_day_last& ymdl);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>year_month_day_last</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr year_month_day_last::year_month_day_last(const date::year& y,
|
|
const date::month_day_last& 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& year_month_day_last::operator+=(const months& 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& year_month_day_last::operator-=(const months& 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& year_month_day_last::operator+=(const years& 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& year_month_day_last::operator-=(const years& 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>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>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() && mdl_.ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.year() == y.year() && x.month_day_last() == y.month_day_last()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> If <code>x.year() < y.year()</code>, returns <code>true</code>. Else
|
|
if <code>x.year() > y.year()</code> returns <code>false</code>.
|
|
Else returns <code>x.month_day_last() < y.month_day_last()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>y < x</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(y < x)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x < y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day_last operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Equivalent to: <code>return (ymdl.year() / ymdl.month() + dm) / last</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_day_last operator+(const months& dm, const year_month_day_last& 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& ymdl, const months& 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& ymdl, const years& 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& dy, const year_month_day_last& 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& ymdl, const years& dy) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymdl + (-dy)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_day_last& ymdl);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << ymdl.year() << '/' << ymdl.month_day_last()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year_month_weekday"></a><h3><code>year_month_weekday</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year_month_weekday
|
|
{
|
|
date::year y_; // exposition only
|
|
date::month m_; // exposition only
|
|
date::weekday_indexed wdi_; // exposition only
|
|
|
|
public:
|
|
year_month_weekday() = default;
|
|
constexpr year_month_weekday(const date::year& y, const date::month& m,
|
|
const date::weekday_indexed& wdi) noexcept;
|
|
constexpr year_month_weekday(const sys_days& dp) noexcept;
|
|
constexpr explicit year_month_weekday(const local_days& dp) noexcept;
|
|
|
|
constexpr year_month_weekday& operator+=(const months& m) noexcept;
|
|
constexpr year_month_weekday& operator-=(const months& m) noexcept;
|
|
constexpr year_month_weekday& operator+=(const years& y) noexcept;
|
|
constexpr year_month_weekday& operator-=(const years& y) noexcept;
|
|
|
|
constexpr date::year year() const noexcept;
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::weekday weekday() const noexcept;
|
|
constexpr unsigned index() const noexcept;
|
|
constexpr date::weekday_indexed weekday_indexed() const noexcept;
|
|
|
|
constexpr operator sys_days() const noexcept;
|
|
constexpr explicit operator local_days() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept;
|
|
constexpr bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept;
|
|
|
|
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
|
|
constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
|
|
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
|
|
constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
|
|
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
|
|
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_weekday& ymwdi);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>year_month_weekday</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday::year_month_weekday(const date::year& y, const date::month& m,
|
|
const date::weekday_indexed& 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& 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& 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& year_month_weekday::operator+=(const months& 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& year_month_weekday::operator-=(const months& 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& year_month_weekday::operator+=(const years& 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& year_month_weekday::operator-=(const years& 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>Returns:</i> If <code>y_.ok() && m_.ok() && wdi_.weekday().ok()</code>,
|
|
returns 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>.
|
|
Otherwise, <code>!y_.ok() || !m_.ok() || !wdi_.weekday().ok()</code> and the returned
|
|
value is unspecified.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit year_month_weekday::operator local_days() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<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& x, const year_month_weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>!(x == y)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymwd + dm</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymwd + (-dm)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& 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& dy, const year_month_weekday& ymwd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymwd + dm</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymwd + (-dm)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_weekday& ymwd);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="year_month_weekday_last"></a><h3><code>year_month_weekday_last</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Synopsis</b></p>
|
|
|
|
<pre>
|
|
class year_month_weekday_last
|
|
{
|
|
date::year y_; // exposition only
|
|
date::month m_; // exposition only
|
|
date::weekday_last wdl_; // exposition only
|
|
|
|
public:
|
|
constexpr year_month_weekday_last(const date::year& y, const date::month& m,
|
|
const date::weekday_last& wdl) noexcept;
|
|
|
|
constexpr year_month_weekday_last& operator+=(const months& m) noexcept;
|
|
constexpr year_month_weekday_last& operator-=(const months& m) noexcept;
|
|
constexpr year_month_weekday_last& operator+=(const years& y) noexcept;
|
|
constexpr year_month_weekday_last& operator-=(const years& y) noexcept;
|
|
|
|
constexpr date::year year() const noexcept;
|
|
constexpr date::month month() const noexcept;
|
|
constexpr date::weekday weekday() const noexcept;
|
|
constexpr date::weekday_last weekday_last() const noexcept;
|
|
|
|
constexpr operator sys_days() const noexcept;
|
|
constexpr explicit operator local_days() const noexcept;
|
|
constexpr bool ok() const noexcept;
|
|
};
|
|
|
|
constexpr
|
|
bool
|
|
operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
|
|
|
|
constexpr
|
|
bool
|
|
operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
|
|
|
|
constexpr
|
|
year_month_weekday_last
|
|
operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
|
|
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_weekday_last& ymwdl);
|
|
</pre>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<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>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<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/>
|
|
<code>year_month_weekday_last</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday_last::year_month_weekday_last(const date::year& y, const date::month& m,
|
|
const date::weekday_last& 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& year_month_weekday_last::operator+=(const months& 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& year_month_weekday_last::operator-=(const months& 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& year_month_weekday_last::operator+=(const years& 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& year_month_weekday_last::operator-=(const years& 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>Returns:</i> If <code>ok() == true</code>, returns a <code>sys_days</code> which
|
|
represents the last <code>weekday()</code> of <code>year()/month()</code>. Otherwise
|
|
the returned value is unspecified.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit year_month_weekday_last::operator local_days() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<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() && m_.ok() && wdl_.ok()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& 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& ymwdl, const months& dm) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Equivalent to: <code>return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr year_month_weekday_last operator+(const months& dm, const year_month_weekday_last& 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& ymwdl, const months& 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& ymwdl, const years& 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& dy, const year_month_weekday_last& 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& ymwdl, const years& dy) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>ymwdl + (-dy)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const year_month_weekday_last& ymwdl);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Inserts
|
|
<code>os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last()</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<h3>date composition operators</h3>
|
|
|
|
<blockquote>
|
|
|
|
<p>
|
|
To understand this API it is not necessary for you to memorize each of these operators.
|
|
Indeed, that would be detrimental to understanding this API. Instead it is sufficient
|
|
to known that this collection of operators implement constructions in 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>
|
|
The first component in each order must be properly typed, the following components may
|
|
be specified with the proper type or an <code>int</code>.
|
|
</p>
|
|
|
|
<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>
|
|
Sub-field-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 = 2015_y/apr;
|
|
month_day md1 = apr/4;
|
|
month_day md2 = 4_d/apr;
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
Everything not intended as above is caught as a compile-time error, with the notable
|
|
exception of an expression that consists of nothing but <code>int</code>, which of course
|
|
has type <code>int</code>.
|
|
</p>
|
|
|
|
<blockquote><pre>
|
|
auto a = 2015/4/4; // a == int(125)
|
|
auto b = 2015_y/4/4; // b == year_month_day{year(2015), month(4), day(4)}
|
|
auto c = 2015_y/4_d/apr; // error: invalid operands to binary expression ('date::year' and 'date::day')
|
|
auto d = 2015/apr/4; // error: invalid operands to binary expression ('int' and 'const date::month')
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
The last example may be clear to a human reader. But the compiler doesn't know if
|
|
<code>2015</code> refers to a <code>year</code> or a <code>day</code>. Instead of
|
|
guessing, the compiler flags it as an error.
|
|
</p>
|
|
|
|
<p>
|
|
In short, you will either write unambiguous and readable code, or you will get a
|
|
compile-time error.
|
|
</p>
|
|
|
|
<hr>
|
|
|
|
<p><b><code>year_month</code>:</b></p>
|
|
|
|
<a name="_1"></a><pre>
|
|
constexpr year_month operator/(const year& y, const month& m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{y, m}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_2"></a><pre>
|
|
constexpr year_month operator/(const year& y, int m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / month(m)</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>month_day</code>:</b></p>
|
|
|
|
<a name="_3"></a><pre>
|
|
constexpr month_day operator/(const month& m, const day& d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{m, d}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_4"></a><pre>
|
|
constexpr month_day operator/(const month& m, int d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>m / day(d)</code>.
|
|
</blockquote>
|
|
|
|
<a name="_5"></a><pre>
|
|
constexpr month_day operator/(int m, const day& d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / d</code>.
|
|
</blockquote>
|
|
|
|
<a name="_6"></a><pre>
|
|
constexpr month_day operator/(const day& d, const month& m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>m / d</code>.
|
|
</blockquote>
|
|
|
|
<a name="_7"></a><pre>
|
|
constexpr month_day operator/(const day& d, int m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / d</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>month_day_last</code>:</b></p>
|
|
|
|
<a name="_8"></a><pre>
|
|
constexpr month_day_last operator/(const month& m, last_spec) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month_day_last{m}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_9"></a><pre>
|
|
constexpr month_day_last operator/(int m, last_spec) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / last</code>.
|
|
</blockquote>
|
|
|
|
<a name="_10"></a><pre>
|
|
constexpr month_day_last operator/(last_spec, const month& m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>m / last</code>.
|
|
</blockquote>
|
|
|
|
<a name="_11"></a><pre>
|
|
constexpr month_day_last operator/(last_spec, int m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / last</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>month_weekday</code>:</b></p>
|
|
|
|
<a name="_12"></a><pre>
|
|
constexpr month_weekday operator/(const month& m, const weekday_indexed& wdi) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{m, wdi}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_13"></a><pre>
|
|
constexpr month_weekday operator/(int m, const weekday_indexed& wdi) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / wdi</code>.
|
|
</blockquote>
|
|
|
|
<a name="_14"></a><pre>
|
|
constexpr month_weekday operator/(const weekday_indexed& wdi, const month& m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>m / wdi</code>.
|
|
</blockquote>
|
|
|
|
<a name="_15"></a><pre>
|
|
constexpr month_weekday operator/(const weekday_indexed& wdi, int m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / wdi</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>month_weekday_last</code>:</b></p>
|
|
|
|
<a name="_16"></a><pre>
|
|
constexpr month_weekday_last operator/(const month& m, const weekday_last& wdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{m, wdl}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_17"></a><pre>
|
|
constexpr month_weekday_last operator/(int m, const weekday_last& wdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / wdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_18"></a><pre>
|
|
constexpr month_weekday_last operator/(const weekday_last& wdl, const month& m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>m / wdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_19"></a><pre>
|
|
constexpr month_weekday_last operator/(const weekday_last& wdl, int m) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>month(m) / wdl</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>year_month_day</code>:</b></p>
|
|
|
|
<a name="_20"></a><pre>
|
|
constexpr year_month_day operator/(const year_month& ym, const day& d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{ym.year(), ym.month(), d}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_21"></a><pre>
|
|
constexpr year_month_day operator/(const year_month& ym, int d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>ym / day(d)</code>.
|
|
</blockquote>
|
|
|
|
<a name="_22"></a><pre>
|
|
constexpr year_month_day operator/(const year& y, const month_day& md) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / md.month() / md.day()</code>.
|
|
</blockquote>
|
|
|
|
<a name="_23"></a><pre>
|
|
constexpr year_month_day operator/(int y, const month_day& md) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / md</code>.
|
|
</blockquote>
|
|
|
|
<a name="_24"></a><pre>
|
|
constexpr year_month_day operator/(const month_day& md, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / md</code>.
|
|
</blockquote>
|
|
|
|
<a name="_25"></a><pre>
|
|
constexpr year_month_day operator/(const month_day& md, int y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / md</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>year_month_day_last</code>:</b></p>
|
|
|
|
<a name="_26"></a><pre>
|
|
constexpr year_month_day_last operator/(const year_month& ym, last_spec) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{ym.year(), month_day_last{ym.month()}}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_27"></a><pre>
|
|
constexpr year_month_day_last operator/(const year& y, const month_day_last& mdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{y, mdl}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_28"></a><pre>
|
|
constexpr year_month_day_last operator/(int y, const month_day_last& mdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_29"></a><pre>
|
|
constexpr year_month_day_last operator/(const month_day_last& mdl, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / mdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_30"></a><pre>
|
|
constexpr year_month_day_last operator/(const month_day_last& mdl, int y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mdl</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>year_month_weekday</code>:</b></p>
|
|
|
|
<a name="_31"></a><pre>
|
|
constexpr year_month_weekday operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{ym.year(), ym.month(), wdi}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_32"></a><pre>
|
|
constexpr year_month_weekday operator/(const year& y, const month_weekday& mwd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{y, mwd.month(), mwd.weekday_indexed()}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_33"></a><pre>
|
|
constexpr year_month_weekday operator/(int y, const month_weekday& mwd) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mwd</code>.
|
|
</blockquote>
|
|
|
|
<a name="_34"></a><pre>
|
|
constexpr year_month_weekday operator/(const month_weekday& mwd, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / mwd</code>.
|
|
</blockquote>
|
|
|
|
<a name="_35"></a><pre>
|
|
constexpr year_month_weekday operator/(const month_weekday& mwd, int y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mwd</code>.
|
|
</blockquote>
|
|
|
|
<p> </p>
|
|
|
|
<p><b><code>year_month_weekday_last</code>:</b></p>
|
|
|
|
<a name="_36"></a><pre>
|
|
constexpr year_month_weekday_last operator/(const year_month& ym, const weekday_last& wdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{ym.year(), ym.month(), wdl}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_37"></a><pre>
|
|
constexpr year_month_weekday_last operator/(const year& y, const month_weekday_last& mwdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>{y, mwdl.month(), mwdl.weekday_last()}</code>.
|
|
</blockquote>
|
|
|
|
<a name="_38"></a><pre>
|
|
constexpr year_month_weekday_last operator/(int y, const month_weekday_last& mwdl) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mwdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_39"></a><pre>
|
|
constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>y / mwdl</code>.
|
|
</blockquote>
|
|
|
|
<a name="_40"></a><pre>
|
|
constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<i>Returns:</i> <code>year(y) / mwdl</code>.
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="time_of_day"></a><h3><code>time_of_day</code></h3>
|
|
|
|
<blockquote>
|
|
<p><b>Overview</b></p>
|
|
|
|
<pre>
|
|
template <class Duration> class time_of_day;
|
|
</pre>
|
|
|
|
<p>
|
|
The <code>time_of_day</code> class breaks a <code>std::chrono::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.
|
|
</p>
|
|
|
|
<p>
|
|
There are 4 specializations of <code>time_of_day</code> to handle four precisions:
|
|
</p>
|
|
|
|
<ol>
|
|
|
|
<li>
|
|
<pre>
|
|
time_of_day<std::chrono::hours>
|
|
</pre>
|
|
<blockquote><p>
|
|
This specialization handles hours since midnight.
|
|
</p></blockquote>
|
|
</li>
|
|
|
|
<li>
|
|
<pre>
|
|
time_of_day<std::chrono::minutes>
|
|
</pre>
|
|
<blockquote><p>
|
|
This specialization handles hours:minutes since midnight.
|
|
</p></blockquote>
|
|
</li>
|
|
|
|
<li>
|
|
<pre>
|
|
time_of_day<std::chrono::seconds>
|
|
</pre>
|
|
<blockquote><p>
|
|
This specialization handles hours:minutes:seconds since midnight.
|
|
</p></blockquote>
|
|
</li>
|
|
|
|
<li>
|
|
<pre>
|
|
time_of_day<std::chrono::duration<Rep, Period>>
|
|
</pre>
|
|
<blockquote><p>
|
|
This specialization is restricted to <code>Period</code>s that fractions of a second
|
|
to represent. Typical uses are with milliseconds, microseconds and nanoseconds. This
|
|
specialization handles hours:minute:seconds.fractional_seconds since midnight.
|
|
</p></blockquote>
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
<p><b>Specification</b></p>
|
|
|
|
<pre>
|
|
enum {am = 1, pm};
|
|
</pre>
|
|
|
|
<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/>
|
|
Each specialization of <code>time_of_day</code> is a literal class type.<br/>
|
|
</p>
|
|
|
|
<pre>
|
|
time_of_day<std::chrono::hours>
|
|
{
|
|
public:
|
|
using precision = std::chrono::hours;
|
|
|
|
constexpr time_of_day() noexcept;
|
|
constexpr explicit time_of_day(std::chrono::hours since_midnight) noexcept;
|
|
|
|
constexpr std::chrono::hours hours() const noexcept;
|
|
constexpr unsigned mode() const noexcept;
|
|
|
|
constexpr explicit operator precision() const noexcept;
|
|
constexpr precision to_duration() const noexcept;
|
|
|
|
void make24() noexcept;
|
|
void make12() noexcept;
|
|
};
|
|
</pre>
|
|
|
|
<pre>
|
|
constexpr time_of_day<std::chrono::hours>::time_of_day() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
|
|
corresponding to 00:00:00 hours after 00:00:00.
|
|
</p>
|
|
<p>
|
|
<i>Postconditions:</i> <code>hours()</code> returns <code>0h</code>.
|
|
<code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::hours>::time_of_day(std::chrono::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. <code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::hours time_of_day<std::chrono::hours>::hours() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored hour of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr unsigned time_of_day<std::chrono::hours>::mode() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> 0 if <code>*this</code> is in 24-hour format. Otherwise returns
|
|
<code>am</code> or <code>pm</code> corresponding to whether this represents a before-noon
|
|
time or afternoon time.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::hours>::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>
|
|
void time_of_day<std::chrono::hours>::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<std::chrono::hours>::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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const time_of_day<std::chrono::hours>& 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>
|
|
time_of_day<std::chrono::minutes>
|
|
{
|
|
public:
|
|
using precision = std::chrono::minutes;
|
|
|
|
constexpr time_of_day() noexcept;
|
|
constexpr explicit time_of_day(std::chrono::minutes since_midnight) noexcept;
|
|
|
|
constexpr std::chrono::hours hours() const noexcept;
|
|
constexpr std::chrono::minutes minutes() const noexcept;
|
|
constexpr unsigned mode() const noexcept;
|
|
|
|
constexpr explicit operator precision() const noexcept;
|
|
constexpr precision to_duration() const noexcept;
|
|
|
|
void make24() noexcept;
|
|
void make12() noexcept;
|
|
};
|
|
</pre>
|
|
|
|
<pre>
|
|
constexpr time_of_day<std::chrono::minutes>::time_of_day() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
|
|
corresponding to 0 minutes after 00:00:00.
|
|
</p>
|
|
<p>
|
|
<i>Postconditions:</i> <code>hours()</code> returns <code>0h</code>.
|
|
<code>minutes()</code> returns <code>0min</code>. <code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::minutes>::time_of_day(std::chrono::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>). <code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::hours time_of_day<std::chrono::minutes>::hours() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored hour of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::minutes time_of_day<std::chrono::minutes>::minutes() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored minute of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr unsigned time_of_day<std::chrono::minutes>::mode() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> 0 if <code>*this</code> is in 24-hour format. Otherwise returns
|
|
<code>am</code> or <code>pm</code> corresponding to whether this represents a before-noon
|
|
time or afternoon time.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::minutes>::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<std::chrono::minutes>::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<std::chrono::minutes>::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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const time_of_day<std::chrono::minutes>& 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>
|
|
time_of_day<std::chrono::seconds>
|
|
{
|
|
public:
|
|
using precision = std::chrono::seconds;
|
|
|
|
constexpr time_of_day() noexcept;
|
|
constexpr explicit time_of_day(std::chrono::seconds since_midnight) noexcept;
|
|
|
|
constexpr std::chrono::hours hours() const noexcept;
|
|
constexpr std::chrono::minutes minutes() const noexcept;
|
|
constexpr std::chrono::seconds seconds() const noexcept;
|
|
constexpr unsigned mode() const noexcept;
|
|
|
|
constexpr explicit operator precision() const noexcept;
|
|
constexpr precision to_duration() const noexcept;
|
|
|
|
void make24() noexcept;
|
|
void make12() noexcept;
|
|
};
|
|
</pre>
|
|
|
|
<pre>
|
|
constexpr time_of_day<std::chrono::seconds>::time_of_day() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
|
|
corresponding to 0 seconds after 00:00:00.
|
|
</p>
|
|
<p>
|
|
<i>Postconditions:</i> <code>hours()</code> returns <code>0h</code>.
|
|
<code>minutes()</code> returns <code>0min</code>. <code>seconds()</code> returns
|
|
<code>0s</code>. <code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::seconds>::time_of_day(std::chrono::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>). <code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::hours time_of_day<std::chrono::seconds>::hours() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored hour of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::minutes time_of_day<std::chrono::seconds>::minutes() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored minute of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::seconds time_of_day<std::chrono::seconds>::seconds() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored second of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr unsigned time_of_day<std::chrono::seconds>::mode() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> 0 if <code>*this</code> is in 24-hour format. Otherwise returns
|
|
<code>am</code> or <code>pm</code> corresponding to whether this represents a before-noon
|
|
time or afternoon time.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::seconds>::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<std::chrono::seconds>::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<std::chrono::seconds>::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<class CharT, class Traits>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const time_of_day<std::chrono::seconds>& 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>
|
|
time_of_day<std::chrono::duration<Rep, Period>>
|
|
{
|
|
public:
|
|
using precision = <i>The decimal-based duration used to format</i>
|
|
|
|
constexpr time_of_day() noexcept;
|
|
constexpr explicit time_of_day(std::chrono::duration<Rep, Period> since_midnight) noexcept;
|
|
|
|
constexpr std::chrono::hours hours() const noexcept;
|
|
constexpr std::chrono::minutes minutes() const noexcept;
|
|
constexpr std::chrono::seconds seconds() const noexcept;
|
|
constexpr precision subseconds() const noexcept;
|
|
constexpr unsigned mode() const noexcept;
|
|
|
|
constexpr explicit operator precision() const noexcept;
|
|
constexpr precision to_duration() const noexcept;
|
|
|
|
void make24() noexcept;
|
|
void make12() noexcept;
|
|
};
|
|
</pre>
|
|
|
|
<p>
|
|
This specialization shall not exist unless <code>Period < 1s</code>.
|
|
</p>
|
|
|
|
<pre>
|
|
constexpr
|
|
time_of_day<std::chrono::duration<Rep, Period>>::time_of_day() noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> Constructs an object of type <code>time_of_day</code> in 24-hour format
|
|
corresponding to 0 fractional seconds after 00:00:00.
|
|
</p>
|
|
<p>
|
|
<i>Postconditions:</i> <code>hours()</code> returns <code>0h</code>.
|
|
<code>minutes()</code> returns <code>0min</code>.
|
|
<code>seconds()</code> returns <code>0s</code>.
|
|
<code>subseconds()</code> returns 0 fractional precision seconds.
|
|
<code>mode()</code> returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit
|
|
time_of_day<std::chrono::duration<Rep, Period>>::time_of_day(std::chrono::duration<Rep, Period> 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>). <code>mode()</code>
|
|
returns <code>0</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::hours time_of_day<std::chrono::duration<Rep, Period>>::hours() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored hour of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::minutes time_of_day<std::chrono::duration<Rep, Period>>::minutes() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored minute of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr std::chrono::seconds time_of_day<std::chrono::duration<Rep, Period>>::seconds() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored second of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr
|
|
std::chrono::duration<Rep, Period>
|
|
time_of_day<std::chrono::duration<Rep, Period>>::subseconds() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> The stored subsecond of <code>*this</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr unsigned time_of_day<std::chrono::duration<Rep, Period>>::mode() const noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> 0 if <code>*this</code> is in 24-hour format. Otherwise returns
|
|
<code>am</code> or <code>pm</code> corresponding to whether this represents a before-noon
|
|
time or afternoon time.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
constexpr explicit time_of_day<std::chrono::duration<Rep, Period>>::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<std::chrono::duration<Rep, Period>>::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<std::chrono::duration<Rep, Period>>::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<class CharT, class Traits, class Rep, class Period>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os, const time_of_day<std::chrono::duration<Rep, Period>>& 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>
|
|
|
|
</blockquote>
|
|
|
|
<h3><code>make_time</code></h3>
|
|
|
|
<blockquote>
|
|
|
|
<a name="_41"></a><pre>
|
|
template <class Rep, class Period>
|
|
constexpr
|
|
time_of_day<std::chrono::duration<Rep, Period>>
|
|
make_time(std::chrono::duration<Rep, Period> d) noexcept;
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>time_of_day<std::chrono::duration<Rep, Period>>(d)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
</blockquote>
|
|
|
|
<a name="_46"></a><pre>
|
|
template <class CharT, class Traits, class Duration>
|
|
std::basic_ostream<class CharT, class Traits>&
|
|
operator<<(std::basic_ostream<class CharT, class Traits>& os,
|
|
const std::chrono::time_point<std::chrono::system_clock, Duration>& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This operator shall not participate in overload resolution if
|
|
<code>std::chrono::treat_as_floating_point<typename Duration::rep>::value</code> is
|
|
true.
|
|
</p>
|
|
<p>
|
|
<i>Effects:</i> If <code>Duration{1} < days{1}</code>:
|
|
</p>
|
|
<blockquote><pre>
|
|
auto const dp = floor<days>(tp);
|
|
os << year_month_day(dp) << ' ' << make_time(tp-dp);
|
|
</pre></blockquote>
|
|
<p>
|
|
Otherwise:
|
|
</p>
|
|
<blockquote><pre>
|
|
os << year_month_day(floor<days>(tp));
|
|
</pre></blockquote>
|
|
|
|
<p>
|
|
<i>Returns:</i> <code>os</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="to_stream_formatting"></a><h3><code>to_stream</code> formatting</h3>
|
|
|
|
<p>
|
|
Each flag begins with a <code>%</code>. Some flags can be modified by <code>E</code> or
|
|
<code>O</code>. During streaming each flag is replaced according to the table below. All
|
|
characters in the format string which are not represented in the table below are inserted
|
|
unchanged into the stream.
|
|
</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>std::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>std::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>std::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>std::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>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>failbit</code> will be set. <code>UTC</code> is used for
|
|
<code>sys_time</code>.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>%%</code></td>
|
|
<td>A <code>%</code> character.</td>
|
|
</tr>
|
|
|
|
</table>
|
|
</blockquote>
|
|
|
|
<a name="format"></a><h3><code>format</code></h3>
|
|
|
|
<pre>
|
|
template <class CharT, class Streamable>
|
|
std::basic_string<CharT>
|
|
format(const std::locale& loc, const CharT* fmt, const Streamable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp)</code>
|
|
is valid.
|
|
</p>
|
|
<p>
|
|
<i>Effects:</i> Constructs a <code>std::basic_ostringstream<CharT> os</code> and
|
|
imbues it with <code>loc</code>.
|
|
Executes <code>os.exceptions(std::ios::failbit | std::ios::badbit)</code>.
|
|
Calls <code>to_stream(os, fmt, tp)</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os.str()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Streamable>
|
|
std::basic_string<CharT>
|
|
format(const CharT* fmt, const Streamable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp)</code>
|
|
is valid.
|
|
</p>
|
|
<p>
|
|
<i>Effects:</i> Constructs a <code>std::basic_ostringstream<CharT> os</code>.
|
|
Executes <code>os.exceptions(std::ios::failbit | std::ios::badbit)</code>.
|
|
Calls <code>to_stream(os, fmt, tp)</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os.str()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Streamable>
|
|
std::basic_string<CharT>
|
|
format(const std::locale& loc, const std::basic_string<CharT, Traits>& fmt, const Streamable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt.c_str(), tp)</code>
|
|
is valid.
|
|
</p>
|
|
<p>
|
|
<i>Effects:</i> Constructs a <code>std::basic_ostringstream<CharT> os</code> and
|
|
imbues it with <code>loc</code>.
|
|
Executes <code>os.exceptions(std::ios::failbit | std::ios::badbit)</code>.
|
|
Calls <code>to_stream(os, fmt.c_str(), tp)</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os.str()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class CharT, class Traits, class Streamable>
|
|
std::basic_string<CharT>
|
|
format(const std::basic_string<CharT, Traits>& fmt, const Streamable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt.c_str(), tp)</code>
|
|
is valid.
|
|
</p>
|
|
<p>
|
|
<i>Effects:</i> Constructs a <code>std::basic_ostringstream<CharT> os</code>.
|
|
Executes <code>os.exceptions(std::ios::failbit | std::ios::badbit)</code>.
|
|
Calls <code>to_stream(os, fmt.c_str(), tp)</code>.
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> <code>os.str()</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="from_stream_formatting"></a><h3><code>from_stream</code> formatting</h3>
|
|
|
|
<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. The C++ specification
|
|
says that the parsing of month and weekday names is both locale sensitive <i>and</i> case
|
|
insensitive. If you find this not to be the case, file a bug with your std::lib vendor.
|
|
</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 charcters, and <code>"%n%t%t"</code> matches one to three white
|
|
space characters. — <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>%Ou</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 format <code>[+|-]hh[mm]</code>. For example
|
|
<code>-0430</code> refers to 4 hours 30 minutes behind UTC. And <code>04</code> refers to
|
|
4 hours ahead of UTC. The modified commands <code>%Ez</code> and <code>%Oz</code> parse a
|
|
<code>:</code> between the hours and minutes and leading zeroes on the hour field are
|
|
optional: <code>[+|-]h[h][:mm]</code>. For example <code>-04:30</code> refers to 4 hours
|
|
30 minutes behind UTC. And <code>4</code> refers to 4 hours ahead of UTC.</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>
|
|
|
|
<a name="parse"></a><h3><code>parse</code></h3>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits, class Alloc>
|
|
<i>unspecified</i>
|
|
parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format.c_str(), tp)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format.c_str(), tp)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits, class Alloc>
|
|
<i>unspecified</i>
|
|
parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
|
|
std::basic_string<CharT, Traits, Alloc>& abbrev);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format.c_str(), tp, &abbrev)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format.c_str(), tp, &abbrev)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits, class Alloc>
|
|
<i>unspecified</i>
|
|
parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
|
|
std::chrono::minutes& offset);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format.c_str(), tp, nullptr, &offset)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format.c_str(), tp, nullptr, &offset)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits>
|
|
<i>unspecified</i>
|
|
parse(const std::basic_string<CharT, Traits>& format, Parsable& tp,
|
|
std::basic_string<CharT, Traits>& abbrev, std::chrono::minutes& offset);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format.c_str(), tp, &abbrev, &offset)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format.c_str(), tp, &abbrev, &offset)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
// const CharT* formats
|
|
|
|
template <class Parsable, class CharT>
|
|
<i>unspecified</i>
|
|
parse(const CharT* format, Parsable& tp);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, tp)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format, tp)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits, class Alloc>
|
|
<i>unspecified</i>
|
|
parse(const CharT* format, Parsable& tp, std::basic_string<CharT, Traits, Alloc>& abbrev);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, tp, &abbrev)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format, tp, &abbrev)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT>
|
|
<i>unspecified</i>
|
|
parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, tp, nullptr, &offset)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format, tp, nullptr, &offset)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<pre>
|
|
template <class Parsable, class CharT, class Traits, class Alloc>
|
|
<i>unspecified</i>
|
|
parse(const CharT* format, Parsable& tp,
|
|
std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset);
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>
|
|
<i>Remarks:</i> This function does not participate in overload resolution unless
|
|
<code>from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format, tp, &abbrev, &offset)</code>
|
|
is valid
|
|
</p>
|
|
<p>
|
|
<i>Returns:</i> A <code>basic_istream<CharT, Traits></code> manipulator that on
|
|
extraction from a <code>basic_istream<CharT, Traits> is</code> calls
|
|
<code>from_stream(is, format, tp, &abbrev, &offset)</code>.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<a name="Installation"></a><h2>Installation</h2>
|
|
|
|
<p>
|
|
Some of the parsing and formatting flags require help from your std::lib's
|
|
<code>time_get</code> and <code>time_put</code> facets for localization help. If you are
|
|
happy with being restricted to the <code>"C"</code> locale, and/or need to port this to an
|
|
older platform that doesn't support the <code>time_get</code> and <code>time_put</code>
|
|
facets, compile with <code>-DONLY_C_LOCALE=1</code>. This enables all of the streaming
|
|
and parsing flags, but makes all of them assume the <code>"C"</code> locale, and removes
|
|
the dependency on the <code>time_get</code> and <code>time_put</code> facets.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|