From da51856fae805bb3acbd8127d45c8adc62422e3f Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sun, 8 May 2016 23:01:27 -0400 Subject: [PATCH] Create Reference --- tz.html | 1315 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1288 insertions(+), 27 deletions(-) diff --git a/tz.html b/tz.html index a633e72..6c19929 100644 --- a/tz.html +++ b/tz.html @@ -26,7 +26,7 @@

Howard E. Hinnant
-2016-04-09
+2016-05-08
Creative
 Commons License
This work is licensed @@ -60,6 +60,7 @@ Commons Attribution 4.0 International License.
  • Thread Safety
  • +
  • Reference
  • Installation — this is where you find the implementation
  • Acknowledgements
  • @@ -209,7 +210,7 @@ namespace date using second_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>; -struct Info +struct sys_info { second_point begin; second_point end; @@ -219,9 +220,8 @@ struct Info }; std::ostream& -operator<<(std::ostream& os, const Info& r); +operator<<(std::ostream& os, const sys_info& r); -enum class tz {utc, local}; enum class choose {earliest, latest}; class nonexistent_local_time @@ -268,7 +268,7 @@ public: choose z) const; template <class Rep, class Period> - Info + sys_info get_info(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<Rep, Period>> tp, tz timezone) const; @@ -645,7 +645,7 @@ using second_point = std::chrono::time_point<std::chrono::system_clock, system_clock but with the precision of seconds. This library will interoperate with system_clock::time_points of any precision. However the data in the database is largely based on second_point, and -some of the data which is presented, such as that in the Info class, uses +some of the data which is presented, such as that in the sys_info class, uses this type alias as a convenience, and to reduce verbosity. second_point will implicitly convert to system_clock::time_point. And coarser time_points such as the day_point from the @@ -654,7 +654,7 @@ will implicitly convert to system_clock::time_point. And coarser

    -struct Info
    +struct sys_info
     {
         second_point         begin;
         second_point         end;
    @@ -665,13 +665,13 @@ struct Info
     

    -The Info struct is the return type of the get_info member +The sys_info struct is the return type of the get_info member function of the Zone class. It contains very detailed information about the Zone at the time_point (UTC or local) input into this member -function. Info contains no pointers or references into the database. -Therefore clients do not need to be concerned about holding on to Infos +function. sys_info contains no pointers or references into the database. +Therefore clients do not need to be concerned about holding on to sys_infos during a call to reload_tzdb(). Though a call to reload_tzdb() -could potentially make the data in an outstanding Info obsolete. See +could potentially make the data in an outstanding sys_info obsolete. See Zone::get_info for more details.

    @@ -766,7 +766,7 @@ public: choose z) const; template <class Rep, class Period> - Info + sys_info get_info(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<Rep, Period>> tp, tz timezone) const; @@ -1089,7 +1089,7 @@ are guaranteed to stay valid:
     template <class Rep, class Period>
    -Info
    +sys_info
     get_info(std::chrono::time_point<std::chrono::system_clock,
                                      std::chrono::duration<Rep, Period>> tp,
              tz timezone) const;
    @@ -1098,48 +1098,48 @@ get_info(std::chrono::time_point<std::chrono::system_clock,
     

    Input a time_point tp, and indicate whether tp represents a UTC time_point (tz::utc) or a local time_point -(tz::local), and a struct Info for that time_point +(tz::local), and a struct sys_info for that time_point is returned:

    -auto info = locate_zone("America/New_York")->get_info(system_clock::now(), tz::utc);
    +auto sys_info = locate_zone("America/New_York")->get_info(system_clock::now(), tz::utc);
     

    -Upon return info will contain the following information: +Upon return sys_info will contain the following information:

    • -info.offset has type std::chrono::seconds and indicates the +sys_info.offset has type std::chrono::seconds and indicates the current offset from UTC. A positive offset indicates that local time is ahead of UTC and a negative offset indicates that local time is behind UTC.

    • -info.abbrev has type std::string and indicates the +sys_info.abbrev has type std::string and indicates the current abbreviation for the local time zone.

    • -info.begin has type second_point and indicates the first +sys_info.begin has type second_point and indicates the first instant guaranteed to have this same offset and abbrev. The -time_point info.begin is implicitly in the UTC time zone. Note that it is +time_point sys_info.begin is implicitly in the UTC time zone. Note that it is possible that the instant prior to begin may or may not have a different offset or abbrev.

    • -info.end has type second_point and indicates the last instant +sys_info.end has type second_point and indicates the last instant before which it is guaranteed to have this same offset and -abbrev. The time_point info.end is implicitly in the UTC time +abbrev. The time_point sys_info.end is implicitly in the UTC time zone. The offset and abbrev associated with -info.end and beyond may or may not be different. +sys_info.end and beyond may or may not be different.

    • -info.save has type std::chrono::minutes and indicates the +sys_info.save has type std::chrono::minutes and indicates the amount of time that daylight savings time has moved the current offset. This can be used to detect whether or not daylight savings is in effect (no if the value is 0min). Note that save is already incorporated into the value of offset, @@ -1149,7 +1149,7 @@ just in the spirit of more information is better.

    -The Info also has a streaming operator which is mainly useful for debugging +The sys_info also has a streaming operator which is mainly useful for debugging purposes. Here is sample code and output:

    @@ -1844,7 +1844,7 @@ const TZ_DB& get_tzdb(); // Zone functions const Zone* locate_zone(const std::string& tz_name); const Zone* current_zone(); -Info Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const; +info Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const; template <class Rep, class Period> auto @@ -1889,6 +1889,1260 @@ reference or pointer. is read-only and there is no need for synchronization with an external mutex.

    +

    Reference

    + +

    The database

    +
    + +

    +The following data structure is the time zone database, and the following +functions access it. +

    + +
    +struct TZ_DB
    +{
    +    std::string            version;
    +    std::vector<time_zone> zones;
    +    std::vector<Link>      links;
    +    std::vector<Leap>      leaps;
    +    std::vector<Rule>      rules;
    +};
    +
    + +

    +The TZ_DB database is a singleton. And access to it is +read-only, except for reload_tzdb() which re-initializes it. +Each vector is sorted to enable fast lookup. You don't have to explicitly +program binary search lookups on it. That is handled by the API. But you can +explicitly iterate over and inspect this database. And knowing that it is sorted may +be of benefit to your inspection logic. +

    + +

    +All information in the +IANA time zone database is +represented in the above TZ_DB data structure, except for the +comments in the database. Thus it is up to you, the client of this library, to +decide what to do with this data. This library makes it especially easy and +convenient to extract the data in the way that is most commonly used (e.g. time +conversions among time zones). But it represents all of the data, and +hides none of it. +

    + +
    +const TZ_DB& get_tzdb();
    +
    +
    +

    +Effects: If this is the first access to the database, will initialize +the database. If tz.cpp was compiled with the configuration macro +AUTO_DOWNLOAD == 1, initialization will include checking the +IANA website for the latest +version, and downloading the latest version if your local version is out of +date, or doesn't exist at the location referred to by the install +configuration variable in tz.cpp. If tz.cpp was +compiled with AUTO_DOWNLOAD == 0, you will have to download and +decompress the IANA database from the +IANA website and place it at the +location referred to by the install configuration variable. +

    +

    +AUTO_DOWNLOAD == 1 requires linking tz.cpp to +libcurl. +

    +

    +Returns: A const reference to the database. +

    +

    +Thread Safety: It is safe to call this function from multiple threads at +one time. There will be no race to initialize the singleton database as long as +your compiler implements threadsafe function-local statics as specified by C++11. +

    +

    +Throws: std::runtime_error if for any reason a reference can not +be returned to a valid TZ_DB. +

    +
    + +
    +const time_zone* locate_zone(const std::string& tz_name);
    +
    +
    +

    +Effects: Calls get_tzdb() which will initialize the timezone +database if this is the first reference to the database. +

    +

    +Returns: If a time_zone is found for which +name() == tz_name, returns a pointer to that time_zone. +Otherwise if a Link is found where tz_name == link.name(), +then a pointer is returned to the time_zone for which +zone.name() == link.target() [Note: A Link is an +alternative name for a time_zone. — end note] +

    +

    +Throws: Any exception propagated from get_tzdb(). If a +const time_zone* can not be found as described in the +Returns clause, throws a std::runtime_error. [Note: +On non-exceptional return, the return value is always a pointer to a +valid time_zone. — end note] +

    +
    + +
    +const time_zone* current_zone();
    +
    +
    +Effects: Calls locate_zone() which will initialize the timezone +database if this is the first reference to the database. +

    +

    +Returns: A const time_zone* referring to the time zone which your +computer has set as its local time zone. +

    +

    +Throws: Any exception propagated from locate_zone(). +[Note: On non-exceptional return, the return value is always a +pointer to a valid time_zone. — end note] +

    + +
    +const TZ_DB& reload_tzdb();
    +
    +
    +

    +Effects: +

    +
    +

    +If If tz.cpp was compiled with the configuration macro +AUTO_DOWNLOAD == 1, this function first checks the latest version at the +IANA website. If the +IANA website is unavailable, or if the +latest version is already installed, there are no effects. Otherwise, a new version +is available. It is downloaded and installed, and then the program re-initializes +the TZ_DB singleton from the new disk files. +

    + +

    +If tz.cpp was compiled with the configuration macro +AUTO_DOWNLOAD == 0, this function re-initializes the +TZ_DB singleton from the disk files. You can manually replace the +database without ill-effects after your program has called +get_tzdb() and before it calls reload_tzdb(), as there is +no access to the files on disk between the first call to get_tzdb() and +subsequent calls to reload_tzdb(). +

    +
    +

    +Returns: A const reference to the database. +

    +

    +Thread Safety: This function is not thread safe. You must +provide your own synchronization among threads accessing the time zone database +to safely use this function. If this function re-initializes the database (as +it always does when AUTO_DOWNLOAD == 0), all outstanding +const time_zone* are invalidated (including those held within +zoned_time objects). And afterwards, all outstanding +sys_info may hold obsolete data. +

    +

    +Throws: std::runtime_error if for any reason a reference can not +be returned to a valid TZ_DB. +

    +
    + +

    +The following functions are available only if you compile with the configuration macro +HAS_REMOTE_API == 1. Use of this API requires linking to +libcurl. +AUTO_DOWNLOAD == 1 requires HAS_REMOTE_API == 1. You +will be notified at compile time if AUTO_DOWNLOAD == 1 and +HAS_REMOTE_API == 0. If HAS_REMOTE_API == 1, then +AUTO_DOWNLOAD defaults to 1, otherwise +AUTO_DOWNLOAD defaults to 0. On Windows, +HAS_REMOTE_API defaults to 0. Everywhere else it +defaults to 1. This is because +libcurl comes preinstalled +everywhere but Windows, but it is available for Windows. +

    + +

    +[Note: Even with AUTO_DOWNLOAD == 1, there are no thread-safety +issues with this library unless one of the following functions are explicitly +called by your code: +

    + +
    +const TZ_DB& reload_tzdb();
    +bool remote_download(const std::string& version);
    +bool remote_install(const std::string& version);
    +
    + +

    +Once your program has initialized the TZ_DB singleton, that singleton +can never be changed without explicit use of reload_tzdb(). +— end note] +

    + +
    + +
    +std::string remote_version();
    +
    +
    +

    +Returns: The latest database version number from the +IANA website. If the +IANA website can not be reached, or +if it can be reached but the latest version number is unexpectedly not +available, the empty string is returned. +

    +

    +Note: If non-empty, this can be compared with get_tzdb().version to +discover if you have the latest database installed. +

    +
    + +
    +bool remote_download(const std::string& version);
    +
    +
    +

    +Effects: If version == remote_version() this function will download +the compressed tar file holding the latest time zone database from the +IANA website. The tar file will be placed +at the location indicated by the install configuration variable in +tz.cpp. +

    +

    +Returns: true if the database was successfully downloaded, else +false. +

    +

    +Thread safety: If called by multiple threads, there will be a race on the +creation of the tar file at install. +

    +
    + +
    +bool remote_install(const std::string& version);
    +
    +
    +

    +Effects: If version refers to the file successfully +downloaded by remote_download() this function will remove the +existing time zone database at install, then extract a new database +from the tar file and place it at install, and finally will delete +the tar file. +

    +

    +This function does not cause your program to re-initialize itself from +this new database. In order to do that, you must call +reload_tzdb() (or get_tzdb() if the database has yet +to be initialized). If tz.cpp was compiled with +AUTO_DOWNLOAD == 1, then reload_tzdb() uses this API +to check if the database is out of date, and reinitializes it with a freshly downloaded +database only if it needs to. Indeed, if AUTO_DOWNLOAD == 1 there is +never any need to call remote_download() or remote_install() +explicitly. You can just call reload_tzdb() instead. This API is +only exposed so that you can take care of this manually if desired +(HAS_REMOTE_API == 1 && AUTO_DOWNLOAD == 0). +

    +

    +Returns: true if the database was successfully replaced by +the tar file , else false. +

    +

    +Thread safety: If called by multiple threads, there will be a race on the +creation of the new database at install. +

    +
    + +
    + +

    +Everything else in this library concerns read-only access to this +database, and intuitive ways to compute with that information, even while being +oblivious to the fact that you are accessing a database. +

    + +

    +The entire database on disk occupies less than half of the disk space consumed by +an average Beatles song. Don't sweat multiple copies of it. It will easily fit in +your smart toaster. +

    + +
    + +

    choose

    + +
    +

    +For some conversions from local_time to a sys_time, +choose::earliest or choose::latest can be used to +convert a non-existent or ambiguous local_time into a +sys_time, instead of throwing an exception. +

    +
    +enum class choose {earliest, latest};
    +
    +
    + +

    nonexistent_local_time

    + +
    +

    +nonexistent_local_time is thrown when one attempts to convert a +non-existent local_time to a sys_time without specifying +choose::earliest or choose::latest. +

    +
    +class nonexistent_local_time
    +    : public std::runtime_error
    +{
    +public:
    +    // Construction is undocumented
    +};
    +
    +

    +[Example: +

    +
    +
    +#include "tz.h"
    +#include <iostream>
    +
    +int
    +main()
    +{
    +    using namespace date;
    +    using namespace std::chrono_literals;
    +    try
    +    {
    +        auto zt = make_zoned("America/New_York", local_days{sun[2]/mar/2016} + 2h + 30min);
    +    }
    +    catch (const nonexistent_local_time& e)
    +    {
    +        std::cout << e.what() << '\n';
    +    }
    +}
    +
    +

    +Which outputs: +

    +
    +2016-03-13 02:30:00 is in a gap between
    +2016-03-13 02:00:00 EST and
    +2016-03-13 03:00:00 EDT which are both equivalent to
    +2016-03-13 07:00:00 UTC
    +
    +
    +

    +— end example:] +

    +
    + +

    ambiguous_local_time

    + +
    +

    +ambiguous_local_time is thrown when one attempts to convert an ambiguous +local_time to a sys_time without specifying +choose::earliest or choose::latest. +

    +
    +class ambiguous_local_time
    +    : public std::runtime_error
    +{
    +public:
    +    // Construction is undocumented
    +};
    +
    +

    +[Example: +

    +
    +
    +#include "tz.h"
    +#include <iostream>
    +
    +int
    +main()
    +{
    +    using namespace date;
    +    using namespace std::chrono_literals;
    +    try
    +    {
    +        auto zt = make_zoned("America/New_York", local_days{sun[1]/nov/2016} + 1h + 30min);
    +    }
    +    catch (const ambiguous_local_time& e)
    +    {
    +        std::cout << e.what() << '\n';
    +    }
    +}
    +
    +

    +Which outputs: +

    +
    +2016-11-06 01:30:00 is ambiguous.  It could be
    +2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or
    +2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC
    +
    +
    +

    +— end example:] +

    +
    + +

    sys_info

    + +
    +

    +This structure can be obtained from the combination of a time_zone and +either a sys_time, or local_time. It can also be obtained +from a zoned_time which is effectively a pair of +a time_zone and sys_time. +

    +

    +This structure represents a lower-level API. Typical conversions from +sys_time to local_time will use this structure +implicitly, not explicitly. +

    +
    +struct sys_info
    +{
    +    sys_seconds          begin;
    +    sys_seconds          end;
    +    std::chrono::seconds offset;
    +    std::chrono::minutes save;
    +    std::string          abbrev;
    +};
    +
    +

    +The begin and end fields indicate that for the +associated time_zone and time_point, the +offset and abbrev are in effect in the range +[begin, end). This information can be used to efficiently iterate the +transitions of a time_zone. +

    +

    +The offset field indicates the UTC offset in effect for the associated +time_zone and time_point. The relationship between +local_time and sys_time is: +

    +
    +offset = local_time - sys_time
    +
    +

    +The save field is "extra" information not normally needed for +conversion between local_time and sys_time. If +save != 0min, this sys_info is said to be on "daylight +saving" time, and offset - save suggests what this +time_zone might use if it were off daylight saving. However +this information should not be taken as authoritative. The only sure way to get +such information is to query the time_zone with a +time_point that returns an sys_info where save == +0min. There is no guarantee what time_point might return such +an sys_info except that it is guaranteed not to be in the range +[begin, end) (if save != 0min for this sys_info). +

    +

    +The abbrev field indicates the current abbreviation used for the +associated time_zone and time_point. Abbreviations +are not unique among the time_zones, and so one can not reliably +map abbreviations back to a time_zone and UTC offset. +

    +

    +You can stream out a sys_info: +

    +
    +std::ostream& operator<<(std::ostream& os, const sys_info& r);
    +
    +
    + +

    local_info

    + +
    +

    +This structure represents a lower-level API. Typical conversions from +local_time to sys_time will use this structure +implicitly, not explicitly. +

    +
    +struct local_info
    +{
    +    enum {unique, nonexistent, ambiguous} result;
    +    sys_info first;
    +    sys_info second;
    +};
    +
    +

    +When a local_time to sys_time conversion is unique, +result == unique, first will be filled out with the +correct sys_info and second will be zero-initialized. +If the conversion stems from a nonexistent local_time then +result == nonexistent, first will be filled out with +the sys_info that ends just prior to the local_time +and second will be filled out with the sys_info that +begins just after the local_time. If the conversion stems from an +ambiguous local_time then result == ambiguous, +first will be filled out with the sys_info that ends +just after the local_time and second will be filled +out with the sys_info that starts just before the +local_time. +

    +

    +You can stream out a local_info: +

    +
    +std::ostream& operator<<(std::ostream& os, const local_info& r);
    +
    + +
    + +

    time_zone

    + +
    +

    +A time_zone represents all time zone transitions for a specific geographic +area. time_zone construction is undocumented, and done for you during +the database initialization. You can gain const access to a +time_zone via functions such as locate_zone. +

    +
    +class time_zone
    +{
    +public:
    +    time_zone(const time_zone&) = delete;
    +    time_zone& operator=(const time_zone&) = delete;
    +
    +    const std::string& name() const;
    +
    +    template <class Duration> sys_info   get_info(sys_time<Duration> st) const;
    +    template <class Duration> local_info get_info(local_time<Duration> tp) const;
    +
    +    template <class Duration>
    +        sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +        to_sys(local_time<Duration> tp) const;
    +
    +    template <class Duration>
    +        sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +        to_sys(local_time<Duration> tp, choose z) const;
    +
    +    template <class Duration>
    +        local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +        to_local(sys_time<Duration> tp) const;
    +};
    +
    +bool operator==(const time_zone& x, const time_zone& y);
    +bool operator!=(const time_zone& x, const time_zone& y);
    +bool operator< (const time_zone& x, const time_zone& y);
    +bool operator> (const time_zone& x, const time_zone& y);
    +bool operator<=(const time_zone& x, const time_zone& y);
    +bool operator>=(const time_zone& x, const time_zone& y);
    +
    +std::ostream& operator<<(std::ostream& os, const time_zone& z)
    +
    +
    +const std::string& time_zone::name() const;
    +
    +
    +

    +Returns: The name of the time_zone. +

    +

    +Example: "America/New_York". +

    +

    +Note: Here is an unofficial list of time_zone names: +https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. +

    +
    + +
    +template <class Duration> sys_info time_zone::get_info(sys_time<Duration> st) const;
    +
    +
    +

    +Returns: A sys_info i for which st is in the +range [i.begin, i.end). +

    +
    + +
    +template <class Duration> local_info time_zone::get_info(local_time<Duration> tp) const;
    +
    +
    +

    +Returns: A local_info for tp. +

    +
    + +
    +template <class Duration>
    +sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +time_zone::to_sys(local_time<Duration> tp) const;
    +
    +
    +

    +Returns: A sys_time that is at least as fine as seconds, +and will be finer if the argument tp has finer precision. This +sys_time is the UTC equivalent of tp according to the rules +of this time_zone. +

    +

    +Throws: If the conversion from tp to a sys_time +is ambiguous, throws ambiguous_local_time. If the conversion from +tp to a sys_time is nonexistent, throws +nonexistent_local_time. +

    +
    + +
    +template <class Duration>
    +sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +time_zone::to_sys(local_time<Duration> tp, choose z) const;
    +
    +
    +

    +Returns: A sys_time that is at least as fine as +seconds, and will be finer if the argument tp has +finer precision. This sys_time is the UTC equivalent of +tp according to the rules of this time_zone. If the +conversion from tp to a sys_time is ambiguous, returns +the earlier sys_time if z == choose::earliest, and +returns the later sys_time if z == choose::latest. If +the tp represents a non-existent time between two UTC +time_points, then the two UTC time_points will be the +same, and that UTC time_point will be returned. +

    +
    + +
    +template <class Duration>
    +local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
    +time_zone::to_local(sys_time<Duration> tp) const;
    +
    +
    +

    +Returns: The local_time associated with tp and this +time_zone. +

    +
    + +
    +bool operator==(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: x.name() == y.name(). +

    +
    + +
    +bool operator!=(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: !(x == y). +

    +
    + +
    +bool operator<(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: x.name() < y.name(). +

    +
    + +
    +bool operator>(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: y < x. +

    +
    + +
    +bool operator<=(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: !(y < x). +

    +
    + +
    +bool operator>=(const time_zone& x, const time_zone& y);
    +
    +
    +

    +Returns: !(x < y). +

    +
    + +
    +std::ostream& operator<<(std::ostream& os, const time_zone& z)
    +
    +
    +

    +Produces an output that is probably more meaningful to me than it is to you. I found it +useful for debugging this library. +

    +
    + +
    + +

    zoned_time

    + +
    +

    +zoned_time represents a logical paring of time_zone and a +time_point with precision Duration. If seconds +is not implicitly convertible to Duration, the instantiation is ill-formed. +[Note: There exist time_zones with UTC offsets that require a +precision of seconds. — end note:] +

    + +
    +template <class Duration>
    +class zoned_time
    +{
    +    const time_zone*   zone_;  // exposition only
    +    sys_time<Duration> tp_;    // exposition only
    +
    +public:
    +    zoned_time(const zoned_time&) = default;
    +    zoned_time& operator=(const zoned_time&) = default;
    +
    +             zoned_time(sys_time<Duration> st);
    +    explicit zoned_time(const time_zone* z);
    +    explicit zoned_time(const std::string& name);
    +
    +    template <class Duration2,
    +              class = std::enable_if_t
    +                      <
    +                          std::is_convertible<sys_time<Duration2>,
    +                                              sys_time<Duration>>{}
    +                      >>
    +        zoned_time(const zoned_time<Duration2>& zt) noexcept;
    +
    +    zoned_time(const time_zone* z,      local_time<Duration> tp);
    +    zoned_time(const std::string& name, local_time<Duration> tp);
    +    zoned_time(const time_zone* z,      local_time<Duration> tp, choose c);
    +    zoned_time(const std::string& name, local_time<Duration> tp, choose c);
    +
    +    zoned_time(const time_zone* z,      const zoned_time<Duration>& zt);
    +    zoned_time(const std::string& name, const zoned_time<Duration>& zt);
    +    zoned_time(const time_zone* z,      const zoned_time<Duration>& zt, choose);
    +    zoned_time(const std::string& name, const zoned_time<Duration>& zt, choose);
    +
    +    zoned_time(const time_zone* z,      const sys_time<Duration>& st);
    +    zoned_time(const std::string& name, const sys_time<Duration>& st);
    +
    +    zoned_time& operator=(sys_time<Duration> st);
    +    zoned_time& operator=(local_time<Duration> ut);
    +
    +             operator sys_time<Duration>() const;
    +    explicit operator local_time<Duration>() const;
    +
    +    const time_zone*     get_time_zone() const;
    +    local_time<Duration> get_local_time() const;
    +    sys_time<Duration>   get_sys_time() const;
    +    sys_info             get_info() const;
    +};
    +
    +using zoned_seconds = zoned_time<std::chrono::seconds>;
    +
    +template <class Duration1, class Duration2>
    +bool
    +operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y);
    +
    +template <class Duration1, class Duration2>
    +bool
    +operator!=(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y);
    +
    + +

    +An invariant of zoned_time<Duration> is that it always refers +to a valid time_zone, and represents a point in time that exists +and is not ambiguous. +

    + +
    +zoned_time<Duration>::zoned_time(const zoned_time&) = default;
    +zoned_time<Duration>& zoned_time<Duration>::operator=(const zoned_time&) = default;
    +
    +
    +

    +The copy members transfer the associated time_zone from the source +to the destination. After copying, source and destination compare equal. If +Duration has noexcept copy members, then +zoned_time<Duration> has noexcept copy +members. +

    +
    + +
    +zoned_time<Duration>::zoned_time(sys_time<Duration> st);
    +
    +
    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()->name() == "UTC", and +zt.get_sys_time() == st. +

    +
    + +
    +explicit zoned_time<Duration>::zoned_time(const time_zone* z);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and +zt.get_sys_time() == sys_seconds{}. +

    +
    + +
    +explicit zoned_time<Duration>::zoned_time(const std::string& name);
    +
    +
    +

    +Effects: Equivalent to construction with locate_zone(name). +

    +

    +Throws: Any exception propagating out of locate_zone(name). +

    +
    + +
    +template <class Duration2,
    +          class = std::enable_if_t
    +                  <
    +                      std::is_convertible<sys_time<Duration2>,
    +                                          sys_time<Duration>>{}
    +                  >>
    +    zoned_time<Duration>::zoned_time(const zoned_time<Duration2>& y) noexcept;
    +
    +
    +

    +Effects: Constructs a zoned_time x such that +x == y. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> tp);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and zt.get_local_time() == tp. +

    +

    +Throws: Any exception that z->to_sys(tp) would throw. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const std::string& name, local_time<Duration> tp);
    +
    +
    +

    +Effects: Equivalent to construction with {locate_zone(name), tp}. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const time_zone* z, local_time<Duration> tp, choose c);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and +zt.get_sys_time() == z->to_sys(tp, c). +

    +
    + +
    +zoned_time<Duration>::zoned_time(const std::string& name, local_time<Duration> tp, choose c);
    +
    +
    +

    +Effects: Equivalent to construction with {locate_zone(name), tp, c}. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const time_zone* z, const zoned_time<Duration>& y);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and +zt.get_sys_time() == y.get_sys_time(). +

    +
    + +
    +zoned_time<Duration>::zoned_time(const std::string& name, const zoned_time<Duration>& y);
    +
    +
    +

    +Effects: Equivalent to construction with {locate_zone(name), y}. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const time_zone* z, const zoned_time<Duration>& y, choose);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and +zt.get_sys_time() == y.get_sys_time(). +

    +

    +Note: The choose parameter is allowed here, but has no impact. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const std::string& name, const zoned_time<Duration>& y, choose);
    +
    +
    +

    +Effects: Equivalent to construction with {locate_zone(name), y}. +

    +

    +Note: The choose parameter is allowed here, but has no impact. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const time_zone* z, const sys_time<Duration>& st);
    +
    +
    +

    +Requires: z refers to a valid time_zone. +

    +

    +Effects: Constructs a zoned_time zt such that +zt.get_time_zone()-> == z, and zt.get_sys_time() == st. +

    +
    + +
    +zoned_time<Duration>::zoned_time(const std::string& name, const sys_time<Duration>& st);
    +
    +
    +

    +Effects: Equivalent to construction with {locate_zone(name), st}. +

    +
    + +
    +zoned_time<Duration>& zoned_time<Duration>::operator=(sys_time<Duration> st);
    +
    +
    +

    +Effects: After assignment get_sys_time() == st. This assignment has +no effect on the return value of get_time_zone(). +

    +

    +Returns: *this. +

    +
    + +
    +zoned_time<Duration>& zoned_time<Duration>::operator=(local_time<Duration> lt);
    +
    +
    +

    +Effects: After assignment get_local_time() == lt. This assignment has +no effect on the return value of get_time_zone(). +

    +

    +Returns: *this. +

    +
    + +
    +zoned_time<Duration>::operator sys_time<Duration>() const;
    +
    +
    +

    +Returns: get_sys_time(). +

    +
    + +
    +explicit zoned_time<Duration>::operator local_time<Duration>() const;
    +
    +
    +

    +Returns: get_local_time(). +

    +
    + +
    +const time_zone* zoned_time<Duration>::get_time_zone() const;
    +
    +
    +

    +Returns: zone_. +

    +
    + +
    +local_time<Duration> zoned_time<Duration>::get_local_time() const;
    +
    +
    +

    +Returns: zone_->to_local(tp_). +

    +
    + +
    +sys_time<Duration> zoned_time<Duration>::get_sys_time() const;
    +
    +
    +

    +Returns: tp_. +

    +
    + +
    +sys_info zoned_time<Duration>::get_info() const;
    +
    +
    +

    +Returns: zone_->get_info(tp_). +

    +
    + +
    +template <class Duration1, class Duration2>
    +bool
    +operator==(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y);
    +
    +
    +

    +Returns: x.zone_ == y.zone_ && x.tp_ == y.tp_. +

    +
    + +
    +template <class Duration1, class Duration2>
    +bool
    +operator!=(const zoned_time<Duration1>& x, const zoned_time<Duration2>& y);
    +
    +
    +

    +Returns: !(x == y). +

    +
    + +
    +template 
    +std::ostream&
    +operator<<(std::ostream& os, const zoned_time& t)
    +
    +
    +

    +Effects: Streams t to os using the format "%F %T %Z" +and the value returned from t.get_local_time(). +

    +

    +Returns: os. +

    +
    + +
    + +

    make_zoned

    + +
    +

    +There exist several overloaded functions named make_zoned +which serve as factory functions for zoned_time<Duration> and +will deduce the correct Duration from the argument list. In every +case the correct return type is +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>. +

    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(sys_time<Duration> tp)
    +
    +
    +

    +Returns: {tp}. +

    +
    + + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const time_zone* zone, local_time<Duration> tp)
    +
    +
    +

    +Returns: {zone, tp}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const std::string& name, local_time<Duration> tp)
    +
    +
    +

    +Returns: {name, tp}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const time_zone* zone, local_time<Duration> tp, choose c)
    +
    +
    +

    +Returns: {zone, tp, c}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const std::string& name, local_time<Duration> tp, choose c)
    +
    +
    +

    +Returns: {name, tp, c}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt)
    +
    +
    +

    +Returns: {zone, zt}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const std::string& name, const zoned_time<Duration>& zt)
    +
    +
    +

    +Returns: {name, zt}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const time_zone* zone, const zoned_time<Duration>& zt, choose c)
    +
    +
    +

    +Returns: {zone, zt, c}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const std::string& name, const zoned_time<Duration>& zt, choose c)
    +
    +
    +

    +Returns: {name, zt, c}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const time_zone* zone, const sys_time<Duration>& st)
    +
    +
    +

    +Returns: {zone, st}. +

    +
    + +
    +template <class Duration>
    +zoned_time<std::common_type_t<Duration, std::chrono::seconds>>
    +make_zoned(const std::string& name, const sys_time<Duration>& st)
    +
    +
    +

    +Returns: {name, st}. +

    +
    + +
    + +

    format

    +
    +

    needs documentation

    +
    + +

    parse

    +
    +

    needs documentation

    +
    + +

    Leap

    +
    +

    needs documentation

    +
    + +

    utc_clock

    +
    +

    needs documentation

    +
    + +

    Link

    +
    +

    needs documentation

    +
    +

    Installation

    @@ -2101,6 +3355,13 @@ Arthur David Olson. I would also like to thank the entire group of people who c maintain it, and especially the IESG-designated TZ Coordinator, Paul Eggert. Without the work of these people, this software would have no data to parse.

    - +

    +I would also like to thank Jiangang Zhuang and Bjarne Stroustrup for invaluable feedback +for the timezone portion of this library, which ended up influencing the date.h library. +

    +

    +And I would also especially like to thank contributors to this library: gmcode, +Ivan Pizhenko, tomy2105 and Ville Voutilainen. +