From 632d1158124220fbaa13653bc2bcfd72f5861814 Mon Sep 17 00:00:00 2001
From: Howard Hinnant
-Returns:
Returns: A
@@ -2742,34 +2756,6 @@ second insertion), then the conversion counts that leap second as inserted.
-Returns:
-Note:
-Returns:
-Note:
-Returns:
-Equivalent to:
-Equivalent to:
-Returns:
Note:
-Returns:
-Note:
-Returns:
-Equivalent to:
-Equivalent to:
-Returns:
Note:
-Returns:
-Note:
Howard E. Hinnant
-2017-10-28
+2017-11-26
Time Zone Database Parser
@@ -61,6 +61,7 @@
utc_clock
tai_clock
gps_clock
clock_cast
leap
link
to_utc_time(system_clock::now())
.
+Returns: from_sys(system_clock::now())
, or a more accurate
+value of utc_time
.
-template <class Duration>
+template <typename Duration>
+static
sys_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_sys_time(utc_time<Duration> u)
+utc_clock::to_sys(const utc_time<Duration>& u);
sys_time
t
, such that
-to_utc_time(t) == u
if such a mapping exists. Otherwise u
+from_sys(t) == u
if such a mapping exists. Otherwise u
represents a time_point
during a leap second insertion and the last
representable value of sys_time
prior to the insertion of the leap
second is returned.
@@ -2728,9 +2741,10 @@ second is returned.
-template <class Duration>
+template <typename Duration>
+static
utc_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_utc_time(sys_time<Duration> t)
+utc_clock::from_sys(const sys_time<Duration>& t);
-
-template <class Duration>
-utc_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_utc_time(tai_time<Duration> t) noexcept
-
-
-
-
-utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
-378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
-
-template <class Duration>
-utc_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_utc_time(gps_time<Duration> t) noexcept
-
-
-
-
utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
-315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
-
template <class CharT, class Traits, class Duration>
std::basic_ostream<class CharT, class Traits>&
@@ -2838,13 +2824,23 @@ If
abbrev
is not equal to nullptr
, the information par
class tai_clock
{
public:
- using duration = std::chrono::system_clock::duration;
- using rep = duration::rep;
- using period = duration::period;
+ using rep = a signed arithmetic type;
+ using period = ratio<unspecified, unspecified>;
+ using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<tai_clock>;
- static constexpr bool is_steady = false;
+ static constexpr bool is_steady = unspecified;
static time_point now() noexcept;
+
+ template <class Duration>
+ static
+ utc_time<std::common_type_t<Duration, std::chrono::seconds>>
+ to_utc(const std::chrono::time_point<tai_clock, Duration>&) noexcept;
+
+ template <class Duration>
+ static
+ tai_time<std::common_type<Duration, std::chrono::seconds>>
+ from_utc(const utc_time<Duration>&) noexcept;
};
template <class Duration>
@@ -2872,40 +2868,20 @@ static tai_clock::time_point tai_clock::now() noexcept;
to_tai_time(system_clock::now())
.
+Returns: from_utc(utc_clock::now())
, or a more accurate
+value of tai_time
.
template <class Duration>
-sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_sys_time(tai_time<Duration> t)
+static
+utc_time<std::common_type_t<Duration, std::chrono::seconds>>
+to_utc(const std::chrono::time_point<tai_clock, Duration>& t) noexcept;
-
-return to_sys_time(to_utc_time(t))
.
-
-template <class Duration>
-tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_tai_time(sys_time<Duration> t)
-
-
-
-
-return to_tai_time(to_utc_time(t))
.
-
-template <class Duration>
-tai_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_tai_time(utc_time<Duration> u) noexcept
-
-
-
tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
+Returns: utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
@@ -2914,15 +2890,16 @@ to_tai_time(utc_time<Duration> u) noexcept
template <class Duration>
-tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_tai_time(gps_time<Duration> t) noexcept
+static
+tai_time<std::common_type<Duration, std::chrono::seconds>>
+tai_clock::from_utc(const utc_time<Duration>& t) noexcept;
@@ -2992,13 +2969,23 @@ If tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 694656019s
+Returns: tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s
+Note: 378691210s == sys_days{1970y/jan/1} - sys_days{1958y/jan/1} + 10s
abbrev
is not equal to nullptr
, the information par
class gps_clock
{
public:
- using duration = std::chrono::system_clock::duration;
- using rep = duration::rep;
- using period = duration::period;
+ using rep = a signed arithmetic type;
+ using period = ratio<unspecified, unspecified>;
+ using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<gps_clock>;
- static constexpr bool is_steady = false;
+ static constexpr bool is_steady = unspecified;
static time_point now() noexcept;
+
+ template <class Duration>
+ static
+ utc_time<std::common_type_t<Duration, std::chrono::seconds>>
+ to_utc(const gps_time<Duration>&) noexcept;
+
+ template <class Duration>
+ static
+ gps_time<std::common_type_t<Duration, std::chrono::seconds>>
+ from_utc(const utc_time<Duration>&) noexcept;
};
template <class Duration>
@@ -3025,40 +3012,20 @@ static gps_clock::time_point gps_clock::now() noexcept;
to_gps_time(system_clock::now())
.
+Returns: from_utc(utc_clock::now())
, or a more accurate
+value of gps_time
.
template <class Duration>
-sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_sys_time(gps_time<Duration> t)
+static
+utc_time<std::common_type_t<Duration, std::chrono::seconds>>
+gps_clock::to_utc(const gps_time<Duration>& t) noexcept;
-
-return to_sys_time(to_utc_time(t))
.
-
-template <class Duration>
-gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_gps_time(sys_time<Duration> t)
-
-
-
-
-return to_gps_time(to_utc_time(t))
.
-
-template <class Duration>
-gps_time<std::common_type_t<Duration, std::chrono::seconds>>
-to_gps_time(utc_time<Duration> u) noexcept
-
-
-
gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
+Returns: gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
@@ -3067,15 +3034,16 @@ to_gps_time(utc_time<Duration> u) noexcept
template <class Duration>
-gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
-to_gps_time(tai_time<Duration> t) noexcept
+static
+gps_time<std::common_type_t<Duration, std::chrono::seconds>>
+gps_clock::from_utc(const utc_time<Duration>& t) noexcept;
@@ -3156,14 +3124,14 @@ int
main()
{
using namespace date;
- using namespace std::chrono_literals;
- auto start = to_utc_time(sys_days{2015_y/jul/1} - 500ms);
+ using namespace std::chrono;
+ auto start = clock_cast<utc_clock>(sys_days{2015_y/jul/1} - 500ms);
auto end = start + 2s;
for (auto utc = start; utc < end; utc += 100ms)
{
- auto sys = to_sys_time(utc);
- auto tai = to_tai_time(utc);
- auto gps = to_gps_time(utc);
+ auto sys = clock_cast<system_clock>(utc);
+ auto tai = clock_cast<tai_clock>(utc);
+ auto gps = clock_cast<gps_clock>(utc);
std::cout << format("%F %T SYS == ", sys)
<< format("%F %T %Z == ", utc)
<< format("%F %T %Z == ", tai)
@@ -3203,6 +3171,303 @@ Output:
gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 694656019s
+Returns: gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
694656019s == sys_days{1980y/jan/sun[1]} - sys_days{1958y/jan/1} + 19s
+Note: 315964809s == sys_days{1980y/jan/sun[1]} - sys_days{1970y/jan/1} + 9s
clock_cast
+++template <class DestClock, class SourceClock> +struct clock_time_conversion +{}; +++
+ +clock_time_conversion
serves as trait which can be used to specify how to +converttime_point<SourceClock, Duration>
to +time_point<DestClock, Duration>
via a specialization: +clock_time_conversion<DestClock, SourceClock>
. A specialization of +clock_time_conversion<DestClock, SourceClock>
shall provide a +const
-qualifiedoperator()
that takes a parameter of type +time_point<SourceClock, Duration>
and returns a +time_point<DestClock, some duration>
representing an equivalent +point in time. A program may specializeclock_time_conversion
if at least +one of the template parameters is user-defined clock type. ++Several specializations are provided by the implementation: +
++// Identity + +template <typename Clock> +struct clock_time_conversion<Clock, Clock> +{ + template <class Duration> + std::chrono::time_point<Clock, Duration> + operator()(const std::chrono::time_point<Clock, Duration>& t) const; +}; + +template <class Duration> +std::chrono::time_point<Clock, Duration> +operator()(const std::chrono::time_point<Clock, Duration>& t) const; ++ +++ ++Returns:
+t
. ++template <> +struct clock_time_conversion<std::chrono::system_clock, std::chrono::system_clock> +{ + template <class Duration> + sys_time<Duration> + operator()(const sys_time<Duration>& t) const; +}; + +template <class Duration> +sys_time<Duration> +operator()(const sys_time<Duration>& t) const; ++ +++ ++Returns:
+t
. ++template <> +struct clock_time_conversion<utc_clock, utc_clock> +{ + template <class Duration> + utc_time<Duration> + operator()(const utc_time<Duration>& t) const; +}; + +template <class Duration> +utc_time<Duration> +operator()(const utc_time<Duration>& t) const; ++ +++ ++Returns:
+t
. ++// system_clock <-> utc_clock ++ ++template <> +struct clock_time_conversion<utc_clock, std::chrono::system_clock> +{ + template <class Duration> + utc_time<std::common_type_t<Duration, std::chrono::seconds>> + operator()(const sys_time<Duration>& t) const; +}; + +template <class Duration> +utc_time<std::common_type_t<Duration, std::chrono::seconds>> +operator()(const sys_time<Duration>& t) const; ++ +++ ++Returns:
+utc_clock::from_sys(t)
. ++template <> +struct clock_time_conversion<std::chrono::system_clock, utc_clock> +{ + template <class Duration> + sys_time<std::common_type_t<Duration, std::chrono::seconds>> + operator()(const utc_time<Duration>& t) const; +}; + +template <class Duration> +sys_time<std::common_type_t<Duration, std::chrono::seconds>> +operator()(const utc_time<Duration>& t) const; ++ +++ ++Returns:
+utc_clock::to_sys(t)
. ++// Clock <-> system_clock ++ ++template <class SourceClock> +struct clock_time_conversion<std::chrono::system_clock, SourceClock> +{ + template <class Duration> + auto + operator()(const std::chrono::time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_sys(t)); +}; + +template <class Duration> +auto +operator()(const std::chrono::time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_sys(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+SourceClock::to_sys(t)
is well formed. If +SourceClock::to_sys(t)
does not return +sys_time<some duration>
the program is ill-formed. ++Returns:
+SourceClock::to_sys(t)
. ++template <class DestClock> +struct clock_time_conversion<DestClock, std::chrono::system_clock> +{ + template <class Duration> + auto + operator()(const sys_time<Duration>& t) const + -> decltype(DestClock::from_sys(t)); +}; + +template <class Duration> +auto +operator()(const sys_time<Duration>& t) const + -> decltype(DestClock::from_sys(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+DestClock::from_sys(t)
is well formed. If +DestClock::from_sys(t)
does not return +time_point<DestClock, some duration>
the program is ill-formed. ++Returns:
+DestClock::from_sys(t)
. ++// Clock <-> utc_clock ++ ++template <class SourceClock> +struct clock_time_conversion<utc_clock, SourceClock> +{ + template <class Duration> + auto + operator()(const std::chrono::time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_utc(t)); +}; + +template <class Duration> +auto +operator()(const std::chrono::time_point<SourceClock, Duration>& t) const + -> decltype(SourceClock::to_utc(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+SourceClock::to_utc(t)
is well formed. If +SourceClock::to_utc(t)
does not return +utc_time<some duration>
the program is ill-formed. ++Returns:
+SourceClock::to_utc(t)
. ++template <class DestClock> +struct clock_time_conversion<DestClock, utc_clock> +{ + template <class Duration> + auto + operator()(const utc_time<Duration>& t) const + -> decltype(DestClock::from_utc(t)); +}; + +template <class Duration> +auto +operator()(const utc_time<Duration>& t) const + -> decltype(DestClock::from_utc(t)); ++ +++ ++Remarks: This function does not participate in overload resolution unless +
+DestClock::from_utc(t)
is well formed. If +DestClock::from_utc(t)
does not return +time_point<DestClock, some duration>
the program is ill-formed. +. +
+Returns:
+DestClock::from_utc(t)
. ++// clock_cast ++ ++template <class DestClock, class SourceClock, class Duration> +std::chrono::time_point<DestClock, some duration> +clock_cast(const std::chrono::time_point<SourceClock, Duration>& t); ++ +++ ++Remarks: This function does not participate in overload resolution unless +at least one of the following expressions are well formed: +
++
+- +
clock_time_conversion<DestClock, SourceClock>{}(t)
- Exactly one of: +
++
- +
clock_time_conversion<DestClock, system_clock>{}( + clock_time_conversion<system_clock, SourceClock>{}(t))
+- +
clock_time_conversion<DestClock, utc_clock>{}( + clock_time_conversion<utc_clock, SourceClock>{}(t))
- Exactly one of: +
++
- +
clock_time_conversion<DestClock, utc_clock>{}( + clock_time_conversion<utc_clock, system_clock>{}( + clock_time_conversion<system_clock, SourceClock>{}(t)))
- +
clock_time_conversion<DestClock, system_clock>{}( + clock_time_conversion<system_clock, utc_clock>{}( + clock_time_conversion<utc_clock, SourceClock>{}(t)))
+Returns: The first expression in the above list that is well-formed. If item 1 is +not well-formed and both expressions in item 2 are well-formed, the +
+clock_cast
is ambiguous (ill-formed). If items 1 and 2 are not well-formed +and both expressions in item 3 are well-formed, theclock_cast
is ambiguous +(ill-formed). +
leap
@@ -3556,7 +3821,7 @@ influencing the date.h library.And I would also especially like to thank contributors to this library: gmcode, -Ivan Pizhenko, tomy2105 and Ville Voutilainen. +Ivan Pizhenko, Tomasz Kamiński, tomy2105 and Ville Voutilainen.