Document custom time zone capabilities

This commit is contained in:
Howard Hinnant
2017-09-16 14:12:30 -04:00
parent 2f8d22b5a0
commit cb7e2e3ced

651
tz.html
View File

@@ -26,7 +26,7 @@
<br/> <br/>
<br/> <br/>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/> <a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/>
2017-07-03<br/> 2017-09-16<br/>
</address> </address>
<hr/> <hr/>
<h1 align=center>Time Zone Database Parser</h1> <h1 align=center>Time Zone Database Parser</h1>
@@ -55,6 +55,7 @@
<li><a href="#sys_info"><code>sys_info</code></a></li> <li><a href="#sys_info"><code>sys_info</code></a></li>
<li><a href="#local_info"><code>local_info</code></a></li> <li><a href="#local_info"><code>local_info</code></a></li>
<li><a href="#time_zone"><code>time_zone</code></a></li> <li><a href="#time_zone"><code>time_zone</code></a></li>
<li><a href="#zoned_traits"><code>zoned_traits</code></a></li>
<li><a href="#zoned_time"><code>zoned_time</code></a></li> <li><a href="#zoned_time"><code>zoned_time</code></a></li>
<li><a href="#make_zoned"><code>make_zoned</code></a></li> <li><a href="#make_zoned"><code>make_zoned</code></a></li>
<li><a href="#utc_clock"><code>utc_clock</code></a></li> <li><a href="#utc_clock"><code>utc_clock</code></a></li>
@@ -558,6 +559,8 @@ formatting strings.
<a name="Examples"><h3>Examples</h3> <a name="Examples"><h3>Examples</h3>
<h4>Flight time</h4>
<p> <p>
Interesting things can happen to the apparent time when you travel across the globe Interesting things can happen to the apparent time when you travel across the globe
at high speeds. So departure and arrival times of airplane flights make for good at high speeds. So departure and arrival times of airplane flights make for good
@@ -674,6 +677,8 @@ flight time is 14:44
arrival Tehran time: 1979-01-01 11:<b>14:59</b> IRST arrival Tehran time: 1979-01-01 11:<b>14:59</b> IRST
</pre></blockquote> </pre></blockquote>
<h4>Format conversion</h4>
<p> <p>
A common task in dealing with dates and times is converting from one string format A common task in dealing with dates and times is converting from one string format
to another. This library is extremely flexible in handling this task. As an to another. This library is extremely flexible in handling this task. As an
@@ -755,6 +760,247 @@ for extension formatting flags to indicate fractional seconds. <code>%S</code>
and <code>%T</code> just work. and <code>%T</code> just work.
</p> </p>
<h4>Custom time zone</h4>
<p>
Occasionally the IANA time zone database doesn't quite do <i>everything</i> you want.
This library allows you to use <code>zoned_time</code> with a time zone and/or pointer
to time zone of your own making. One common example is the need to have a time zone
that has a fixed offset from UTC, but for which that offset isn't known until run time.
Below is an example which supplies a custom time zone called <code>OffsetZone</code>
which can hold a UTC offset with minutes precision.
</p>
<blockquote><pre>
#include "tz.h"
#include &lt;iostream&gt;
#include &lt;type_traits&gt;
class OffsetZone
{
std::chrono::minutes offset_;
public:
explicit OffsetZone(std::chrono::minutes offset)
: offset_{offset}
{}
template &lt;class Duration&gt;
auto
to_local(date::sys_time&lt;Duration&gt; tp) const
{
using namespace date;
using namespace std;
using namespace std::chrono;
using LT = local_time&lt;common_type_t&lt;Duration, minutes&gt;&gt;;
return LT{(tp + offset_).time_since_epoch()};
}
template &lt;class Duration&gt;
auto
to_sys(date::local_time&lt;Duration&gt; tp) const
{
using namespace date;
using namespace std;
using namespace std::chrono;
using ST = sys_time&lt;common_type_t&lt;Duration, minutes&gt;&gt;;
return ST{(tp - offset_).time_since_epoch()};
}
};
int
main()
{
using namespace date;
using namespace std::chrono;
OffsetZone p3_45{3h + 45min};
zoned_time&lt;milliseconds, OffsetZone*&gt; zt{&amp;p3_45, floor&lt;milliseconds&gt;(system_clock::now())};
std::cout &lt;&lt; zt.get_sys_time() &lt;&lt; '\n';
std::cout &lt;&lt; zt.get_local_time() &lt;&lt; '\n';
}
</pre></blockquote>
<p>
This just output for me:
</p>
<blockquote><pre>
2017-09-16 17:34:47.560
2017-09-16 21:19:47.560
</pre></blockquote>
<p>
The second template parameter to <code>zoned_time</code> is a pointer to a time zone.
This example simply creates a <code>OffsetZone</code> with a UTC offset of 3:45, and
constructs a <code>OffsetZone</code> which points to that custom time zone and
supplies the current time to the desired precision (whatever that may be).
</p>
<p>
You don't have to use a built-in pointer to your time zone. You could just as easily use
<code>unique_ptr</code>, <code>shared_ptr</code>, or whatever smart pointer is right for
your application. And in C++17, you won't need to supply the template parameters for
<code>zoned_time</code> (though you still can if you want to). That is, the construction
of <code>zt</code> above could be simplified down to just this:
</p>
<blockquote><pre>
zoned_time zt{&amp;p3_45, floor&lt;milliseconds&gt;(system_clock::now())};
</pre></blockquote>
<p>
One can <i>even</i> have <code>OffsetZone</code> serve as its <i>own</i> smart pointer by
giving it a member <code>operator-&gt;()</code> that returns itself:
</p>
<blockquote><pre>
const OffsetZone* operator-&gt;() const {return this;}
</pre></blockquote>
<p>
This allows you to embed the <code>OffsetZone</code> <i>directly</i> into the
<code>zoned_time</code> instead of pointing to an externally held <code>OffsetZone</code>:
</p>
<blockquote><pre>
zoned_time&lt;milliseconds, OffsetZone&gt; zt{OffsetZone{3h + 45min}, floor&lt;milliseconds&gt;(system_clock::now())};
</pre></blockquote>
<p>
As it stands, <code>zoned&lt;Duration, OffsetZone&gt;</code> can't be streamed with
<code>operator&lt;&lt;</code> or formatted with <code>format</code>. But that can be
fixed too: Just give <code>OffsetZone</code> a member <code>get_info</code> which
takes a <code>sys_time</code> and returns a
<a href="#sys_info"><code>sys_info</code></a>:
</p>
<blockquote><pre>
template &lt;class Duration&gt;
date::sys_info
get_info(date::sys_time&lt;Duration&gt;) const
{
using namespace date;
using namespace std::chrono;
return {sys_seconds::min(), sys_seconds::max(), offset_,
minutes{0}, offset_ &gt;= minutes{0}
? "+" + date::format("%H%M", offset_)
: "-" + date::format("%H%M", -offset_)};
}
</pre></blockquote>
<p>
Above I've chosen to make the abbreviation for <code>OffsetZone</code> equivalent to
<code>%z</code>, but I could have installed any <code>std::string</code> I wanted to.
This allows me to say:
</p>
<blockquote><pre>
std::cout &lt;&lt; zt &lt;&lt; '\n';
</pre></blockquote>
<p>
which just output for me:
</p>
<blockquote><pre>
2017-09-16 21:36:10.913 +0345
</pre></blockquote>
<p>
If I want to make <code>zoned_time&lt;Duration, OffsetZone&gt;</code> default constructible,
then I need to specialize <code>zoned_traits&lt;OffsetZone&gt;</code> with
<code>default_zone()</code>:
</p>
<blockquote><pre>
namespace date
{
template &lt;&gt;
struct zoned_traits&lt;OffsetZone&gt;
{
static
OffsetZone
default_zone()
{
using namespace std::chrono;
return OffsetZone{minutes{0}};
}
};
} // namespace date
</pre></blockquote>
<p>
Now this:
</p>
<blockquote><pre>
zoned_time&lt;milliseconds, OffsetZone&gt; zt;
std::cout &lt;&lt; zt &lt;&lt; '\n';
</pre></blockquote>
<p>
outputs:
</p>
<blockquote><pre>
1970-01-01 00:00:00.000 +0000
</pre></blockquote>
<p>
And if I wanted to construct a <code>zoned_time&lt;Duration, OffsetZone&gt;</code> from
a <code>string</code>, I need to add
<code>static OffsetZone locate_zone(string name)</code> to my <code>zoned_traits</code>
specialization.
</p>
<blockquote><pre>
namespace date
{
template &lt;&gt;
struct zoned_traits&lt;OffsetZone&gt;
{
static
OffsetZone
default_zone()
{
using namespace std::chrono;
return OffsetZone{minutes{0}};
}
static
OffsetZone
locate_zone(const std::string&amp; name)
{
using namespace std::chrono;
if (name == "UTC")
return OffsetZone{minutes{0}};
throw std::runtime_error{"OffsetZone can't handle anything but " + name};
}
};
} // namespace date
</pre></blockquote>
<p>
Now this:
</p>
<blockquote><pre>
zoned_time&lt;seconds, OffsetZone&gt; zt{"UTC", floor&lt;seconds&gt;(system_clock::now())};
std::cout &lt;&lt; zt &lt;&lt; '\n';
</pre></blockquote>
<p>
outputs:
</p>
<blockquote><pre>
2017-09-16 18:09:22 +0000
</pre></blockquote>
<a name="Reference"></a><h2>Reference</h2> <a name="Reference"></a><h2>Reference</h2>
<p> <p>
@@ -1543,84 +1789,125 @@ useful for debugging this library.
</blockquote> </blockquote>
<a name="zoned_traits"></a><h3><code>zoned_traits</code></h3>
<blockquote>
<p>
<code>zoned_traits</code> provides a means for customizing the behavior of
<code>zoned_time&lt;Duration, TimeZonePtr&gt;</code> for the
<code>zoned_time</code> default constructor, and constructors taking
<code>string_view</code>. A specialization for <code>const time_zone*</code>
is provided by the implementation.
</p>
<pre>
template &lt;class T&gt; struct zoned_traits {};
template &lt;&gt;
struct zoned_traits&lt;const time_zone*&gt;
{
static const time_zone* default_zone();
static const time_zone* locate_zone(string_view name);
};
</pre>
<pre>
static const time_zone* zoned_traits&lt;const time_zone*&gt;::default_zone();
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>date::locate_zone("UTC")</code>.
</p>
</blockquote>
<pre>
static const time_zone* zoned_traits&lt;const time_zone*&gt;::locate_zone(string_view name);
</pre>
<blockquote>
<p>
<i>Returns:</i> <code>date::locate_zone(name)</code>.
</p>
</blockquote>
</blockquote>
<a name="zoned_time"></a><h3><code>zoned_time</code></h3> <a name="zoned_time"></a><h3><code>zoned_time</code></h3>
<blockquote> <blockquote>
<p> <p>
<code>zoned_time</code> represents a logical paring of <code>time_zone</code> and a <code>zoned_time</code> represents a logical paring of <code>time_zone</code> and a
<code>time_point</code> with precision <code>Duration</code>. If <code>seconds</code> <code>time_point</code> with precision <code>Duration</code>.
is not implicitly convertible to <code>Duration</code>, the instantiation is ill-formed.
[<i>Note:</i> There exist <code>time_zone</code>s with UTC offsets that require a
precision of <code>seconds</code>. <i>&mdash; end note:</i>]
</p> </p>
<pre> <pre>
template &lt;class Duration&gt; template &lt;class Duration, class TimeZonePtr = const time_zone*&gt;
class zoned_time class zoned_time
{ {
const time_zone* zone_; // exposition only public:
sys_time&lt;Duration&gt; tp_; // exposition only using duration = common_type_t&lt;Duration, seconds&gt;;
private:
TimeZonePtr zone_; // exposition only
sys_time&lt;duration&gt; tp_; // exposition only
public: public:
zoned_time();
zoned_time(const zoned_time&amp;) = default; zoned_time(const zoned_time&amp;) = default;
zoned_time&amp; operator=(const zoned_time&amp;) = default; zoned_time&amp; operator=(const zoned_time&amp;) = default;
zoned_time(); zoned_time(const sys_time&lt;Duration&gt;&amp; st);
zoned_time(sys_time&lt;Duration&gt; st); explicit zoned_time(TimeZonePtr z);
explicit zoned_time(const time_zone* z); explicit zoned_time(string_view name);
explicit zoned_time(const std::string&amp; name);
template &lt;class Duration2, template &lt;class Duration2&gt;
class = std::enable_if_t
&lt;
std::is_convertible&lt;sys_time&lt;Duration2&gt;,
sys_time&lt;Duration&gt;&gt;{}
&gt;&gt;
zoned_time(const zoned_time&lt;Duration2&gt;&amp; zt) noexcept; zoned_time(const zoned_time&lt;Duration2&gt;&amp; zt) noexcept;
zoned_time(const time_zone* z, local_time&lt;Duration&gt; tp); zoned_time(TimeZonePtr z, const sys_time&lt;Duration&gt;&amp; st);
zoned_time(const std::string&amp; name, local_time&lt;Duration&gt; tp); zoned_time(string_view name, const sys_time&lt;Duration&gt;&amp; st);
zoned_time(const time_zone* z, local_time&lt;Duration&gt; tp, choose c);
zoned_time(const std::string&amp; name, local_time&lt;Duration&gt; tp, choose c);
zoned_time(const time_zone* z, const zoned_time&lt;Duration&gt;&amp; zt); zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp);
zoned_time(const std::string&amp; name, const zoned_time&lt;Duration&gt;&amp; zt); zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp);
zoned_time(const time_zone* z, const zoned_time&lt;Duration&gt;&amp; zt, choose); zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp, choose c);
zoned_time(const std::string&amp; name, const zoned_time&lt;Duration&gt;&amp; zt, choose); zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp, choose c);
zoned_time(const time_zone* z, const sys_time&lt;Duration&gt;&amp; st); zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; zt);
zoned_time(const std::string&amp; name, const sys_time&lt;Duration&gt;&amp; st); zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; zt);
zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; zt, choose);
zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; zt, choose);
zoned_time&amp; operator=(sys_time&lt;Duration&gt; st); zoned_time&amp; operator=(const sys_time&lt;Duration&gt;&amp; st);
zoned_time&amp; operator=(local_time&lt;Duration&gt; ut); zoned_time&amp; operator=(const local_time&lt;Duration&gt;&amp; ut);
operator sys_time&lt;Duration&gt;() const; operator sys_time&lt;duration&gt;() const;
explicit operator local_time&lt;Duration&gt;() const; explicit operator local_time&lt;duration&gt;() const;
const time_zone* get_time_zone() const; TimeZonePtr get_time_zone() const;
local_time&lt;Duration&gt; get_local_time() const; local_time&lt;duration&gt; get_local_time() const;
sys_time&lt;Duration&gt; get_sys_time() const; sys_time&lt;duration&gt; get_sys_time() const;
sys_info get_info() const; sys_info get_info() const;
}; };
using zoned_seconds = zoned_time&lt;std::chrono::seconds&gt;; using zoned_seconds = zoned_time&lt;std::chrono::seconds&gt;;
template &lt;class Duration1, class Duration2&gt; template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool bool
operator==(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y); operator==(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class Duration1, class Duration2&gt; template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool bool
operator!=(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y); operator!=(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
template &lt;class CharT, class Traits, class Duration&gt; template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
std::basic_ostream&lt;class CharT, class Traits&gt;&amp; basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, const zoned_time&lt;Duration&gt;& t) operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os,
const zoned_time&lt;Duration, TimeZonePtr&gt;& t);
template &lt;class CharT, class Traits, class Duration&gt; template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
std::basic_ostream&lt;CharT, Traits&gt;&amp; basic_ostream&lt;charT, traits&gt;&amp;
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt, to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const zoned_time&lt;Duration&gt;&amp; tp); const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp);
</pre> </pre>
<p> <p>
@@ -1630,8 +1917,23 @@ and is not ambiguous.
</p> </p>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const zoned_time&amp;) = default; zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time();
zoned_time&lt;Duration&gt;&amp; zoned_time&lt;Duration&gt;::operator=(const zoned_time&amp;) = default; </pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
the expression <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> is well formed.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> and
default constructing <code>tp_</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(const zoned_time&amp;) = default;
zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration&gt;::operator=(const zoned_time&amp;) = default;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1644,151 +1946,214 @@ members.
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(const sys_time&lt;Duration&gt;&amp; st);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zt.get_time_zone()-&gt;name() == "UTC"</code>, and the expression <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> is well formed.
<code>zt.get_sys_time() == sys_seconds{}</code>. </p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::default_zone()</code> and
<code>tp_</code> with <code>st</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(sys_time&lt;Duration&gt; st); explicit zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z);
</pre>
<blockquote>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that
<code>zt.get_time_zone()-&gt;name() == "UTC"</code>, and
<code>zt.get_sys_time() == st</code>.
</p>
</blockquote>
<pre>
explicit zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>. <i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p> </p>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Effects:</i> Constructs a <code>zoned_time</code> initializing <code>zone_</code>
<code>zt.get_time_zone()-&gt; == z</code>, and with <code>std::move(z)</code>.
<code>zt.get_sys_time() == sys_seconds{}</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
explicit zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name); explicit zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Equivalent to construction with <code>locate_zone(name)</code>. <i>Remarks:</i> This constructor does not participate in overload resolution unless
the expression <code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(string_view{})</code>
is well formed and <code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(string_view{})</code>.
</p> </p>
<p> <p>
<i>Throws:</i> Any exception propagating out of <code>locate_zone(name)</code>. <i>Effects:</i> Constructs a <code>zoned_time</code> by initializing
<code>zone_</code> with <code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>
and default constructing <code>tp_</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
template &lt;class Duration2, template &lt;class Duration2, TimeZonePtr&gt;
class = std::enable_if_t zoned_time&lt;Duration&gt;::zoned_time(const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y) noexcept;
&lt;
std::is_convertible&lt;sys_time&lt;Duration2&gt;,
sys_time&lt;Duration&gt;&gt;{}
&gt;&gt;
zoned_time&lt;Duration&gt;::zoned_time(const zoned_time&lt;Duration2&gt;&amp; y) noexcept;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Remarks:</i> Does not participate in overload resolution unless
<code>sys_time&lt;Duration2&gt;</code> is implicitly convertible to
<code>sys_time&lt;Duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>x</code> such that <i>Effects:</i> Constructs a <code>zoned_time</code> <code>x</code> such that
<code>x == y</code>. <code>x == y</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, local_time&lt;Duration&gt; tp); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const sys_time&lt;Duration&gt;&amp; st);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>. <i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p> </p>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
<code>zt.get_time_zone()-&gt; == z</code>, and <code>zt.get_local_time() == tp</code>. with <code>std::move(z)</code> and <code>tp_</code> with <code>st</code>.
</p>
<p>
<i>Throws:</i> Any exception that <code>z-&gt;to_sys(tp)</code> would throw.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name, local_time&lt;Duration&gt; tp); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const sys_time&lt;Duration&gt;&amp; st);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), tp}</code>. <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code> and <code>st</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), st}</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, local_time&lt;Duration&gt; tp, choose c); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>. <i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p> </p>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zt.get_time_zone()-&gt; == z</code>, and <code>declval&lt;TimeZonePtr&amp;&gt;()-&gt;to_sys(local_time&lt;Duration&gt;{})</code>
<code>zt.get_sys_time() == z-&gt;to_sys(tp, c)</code>. is convertible to <code>sys_time&lt;duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>zone_-&gt;to_sys(t)</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name, local_time&lt;Duration&gt; tp, choose c); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), tp, c}</code>. <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code> and <code>tp</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), tp}</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, const zoned_time&lt;Duration&gt;&amp; y); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const local_time&lt;Duration&gt;&amp; tp, choose c);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>. <i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p> </p>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zt.get_time_zone()-&gt; == z</code>, and <code>decltype(declval&lt;TimeZonePtr&amp;&gt;()-&gt;to_sys(local_time&lt;Duration&gt;{}, choose::earliest))</code>
<code>zt.get_sys_time() == y.get_sys_time()</code>. is convertible to <code>sys_time&lt;duration&gt;</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
with <code>std::move(z)</code> and <code>tp_</code> with <code>zone_-&gt;to_sys(t, c)</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name, const zoned_time&lt;Duration&gt;&amp; y); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const local_time&lt;Duration&gt;&amp; tp, choose c);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), y}</code>. <i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>,
<code>local_time&lt;Duration&gt;</code> and <code>choose</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with
<code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), tp, c}</code>.
</p> </p>
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, const zoned_time&lt;Duration&gt;&amp; y, choose); zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; y);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>. <i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p> </p>
<p> <p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that <i>Effects:</i> Constructs a <code>zoned_time</code> by initializing <code>zone_</code>
<code>zt.get_time_zone()-&gt; == z</code>, and with <code>std::move(z)</code> and <code>tp_</code> with <code>z.tp_</code>.
<code>zt.get_sys_time() == y.get_sys_time()</code>. </p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; y);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>
and <code>zoned_time</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with
<code>{zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name), y}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(TimeZonePtr z, const zoned_time&lt;Duration&gt;&amp; y, choose);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{z, y}</code>.
</p>
<i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration, TimeZonePtr&gt;::zoned_time(string_view name, const zoned_time&lt;Duration&gt;&amp; y, choose c);
</pre>
<blockquote>
<p>
<i>Remarks:</i> This constructor does not participate in overload resolution unless
<code>zoned_time</code> is constructible from the return type of
<code>zoned_traits&lt;TimeZonePtr&gt;::locate_zone(name)</code>, <code>zoned_time</code>,
and <code>choose</code>.
</p>
<p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), y, c}</code>.
</p> </p>
<p> <p>
<i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact. <i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact.
@@ -1796,41 +2161,7 @@ zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, const zoned_time&lt;D
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name, const zoned_time&lt;Duration&gt;&amp; y, choose); zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration, TimeZonePtr&gt;::operator=(const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), y}</code>.
</p>
<p>
<i>Note:</i> The <code>choose</code> parameter is allowed here, but has no impact.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration&gt;::zoned_time(const time_zone* z, const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Requires:</i> <code>z</code> refers to a valid <code>time_zone</code>.
</p>
<p>
<i>Effects:</i> Constructs a <code>zoned_time</code> <code>zt</code> such that
<code>zt.get_time_zone()-&gt; == z</code>, and <code>zt.get_sys_time() == st</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration&gt;::zoned_time(const std::string&amp; name, const sys_time&lt;Duration&gt;&amp; st);
</pre>
<blockquote>
<p>
<i>Effects:</i> Equivalent to construction with <code>{locate_zone(name), st}</code>.
</p>
</blockquote>
<pre>
zoned_time&lt;Duration&gt;&amp; zoned_time&lt;Duration&gt;::operator=(sys_time&lt;Duration&gt; st);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1843,7 +2174,7 @@ no effect on the return value of <code>get_time_zone()</code>.
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;&amp; zoned_time&lt;Duration&gt;::operator=(local_time&lt;Duration&gt; lt); zoned_time&lt;Duration, TimeZonePtr&gt;&amp; zoned_time&lt;Duration, TimeZonePtr&gt;::operator=(const local_time&lt;Duration&gt;&amp; lt);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1856,7 +2187,7 @@ no effect on the return value of <code>get_time_zone()</code>.
</blockquote> </blockquote>
<pre> <pre>
zoned_time&lt;Duration&gt;::operator sys_time&lt;Duration&gt;() const; zoned_time&lt;Duration, TimeZonePtr&gt;::operator sys_time&lt;duration&gt;() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1865,7 +2196,7 @@ zoned_time&lt;Duration&gt;::operator sys_time&lt;Duration&gt;() const;
</blockquote> </blockquote>
<pre> <pre>
explicit zoned_time&lt;Duration&gt;::operator local_time&lt;Duration&gt;() const; explicit zoned_time&lt;Duration, TimeZonePtr&gt;::operator local_time&lt;duration&gt;() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1874,7 +2205,7 @@ explicit zoned_time&lt;Duration&gt;::operator local_time&lt;Duration&gt;() const
</blockquote> </blockquote>
<pre> <pre>
const time_zone* zoned_time&lt;Duration&gt;::get_time_zone() const; TimeZonePtr zoned_time&lt;Duration, TimeZonePtr&gt;::get_time_zone() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1883,7 +2214,7 @@ const time_zone* zoned_time&lt;Duration&gt;::get_time_zone() const;
</blockquote> </blockquote>
<pre> <pre>
local_time&lt;Duration&gt; zoned_time&lt;Duration&gt;::get_local_time() const; local_time&lt;typename zoned_time&lt;Duration, TimeZonePtr&gt;::duration&gt; zoned_time&lt;Duration, TimeZonePtr&gt;::get_local_time() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1892,7 +2223,7 @@ local_time&lt;Duration&gt; zoned_time&lt;Duration&gt;::get_local_time() const;
</blockquote> </blockquote>
<pre> <pre>
sys_time&lt;Duration&gt; zoned_time&lt;Duration&gt;::get_sys_time() const; sys_time&lt;typename zoned_time&lt;Duration, TimeZonePtr&gt;::duration&gt; zoned_time&lt;Duration, TimeZonePtr&gt;::get_sys_time() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1901,7 +2232,7 @@ sys_time&lt;Duration&gt; zoned_time&lt;Duration&gt;::get_sys_time() const;
</blockquote> </blockquote>
<pre> <pre>
sys_info zoned_time&lt;Duration&gt;::get_info() const; sys_info zoned_time&lt;Duration, TimeZonePtr&gt;::get_info() const;
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1910,9 +2241,10 @@ sys_info zoned_time&lt;Duration&gt;::get_info() const;
</blockquote> </blockquote>
<pre> <pre>
template &lt;class Duration1, class Duration2&gt; template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool bool
operator==(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y); operator==(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1921,9 +2253,10 @@ operator==(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duratio
</blockquote> </blockquote>
<pre> <pre>
template &lt;class Duration1, class Duration2&gt; template &lt;class Duration1, class Duration2, class TimeZonePtr&gt;
bool bool
operator!=(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duration2&gt;&amp; y); operator!=(const zoned_time&lt;Duration1, TimeZonePtr&gt;&amp; x,
const zoned_time&lt;Duration2, TimeZonePtr&gt;&amp; y);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
@@ -1932,13 +2265,15 @@ operator!=(const zoned_time&lt;Duration1&gt;&amp; x, const zoned_time&lt;Duratio
</blockquote> </blockquote>
<pre> <pre>
template &lt;class CharT, class Traits, class Duration&gt; template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
std::basic_ostream&lt;class CharT, class Traits&gt;&amp; basic_ostream&lt;charT, traits&gt;&
operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, const zoned_time&lt;Duration&gt;& t) operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;& os,
const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; t)
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Calls <code>to_stream(os, "%F %T %Z", t)</code>. <i>Effects:</i> Streams <code>t</code> to <code>os</code> using the format "%F %T %Z"
and the value returned from <code>t.get_local_time()</code>.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.
@@ -1946,17 +2281,17 @@ operator&lt;&lt;(std::basic_ostream&lt;class CharT, class Traits&gt;&amp; os, co
</blockquote> </blockquote>
<pre> <pre>
template &lt;class CharT, class Traits, class Duration&gt; template &lt;class charT, class traits, class Duration, class TimeZonePtr&gt;
std::basic_ostream&lt;CharT, Traits&gt;&amp; basic_ostream&lt;charT, traits&gt;&amp;
to_stream(std::basic_ostream&lt;CharT, Traits&gt;&amp; os, const CharT* fmt, to_stream(basic_ostream&lt;charT, traits&gt;&amp; os, const charT* fmt,
const zoned_time&lt;Duration&gt;&amp; tp); const zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp);
</pre> </pre>
<blockquote> <blockquote>
<p> <p>
<i>Effects:</i> Constructs a copy of the <code>sys_info</code> object by calling <i>Effects:</i> First obtains a <code>sys_info</code> via <code>tp.get_info()</code>
<code>tp.get_info()</code> (stored in a local named <code>info</code> for example). which for exposition purposes will be referred to as <code>info</code>. Then calls
Then calls <code>to_stream(os, fmt, tp.get_local_time(), &amp;info.abbrev, &amp;info.offset)</code>. <code>to_stream(os, fmt, tp.get_local_time(), &amp;info.abbrev, &amp;info.offset)</code>.
</p> </p>
<p> <p>
<i>Returns:</i> <code>os</code>. <i>Returns:</i> <code>os</code>.