25 Time library [time]

25.10 Time zones [time.zone]

25.10.1 In general [time.zone.general]

[time.zone] describes an interface for accessing the IANA Time Zone database described in RFC 6557, that interoperates with sys_­time and local_­time.
This interface provides time zone support to both the civil calendar types ([time.cal]) and to user-defined calendars.

25.10.2 Time zone database [time.zone.db]

25.10.2.1 Class tzdb [time.zone.db.tzdb]

namespace std::chrono {
  struct tzdb {
    string            version;
    vector<time_zone> zones;
    vector<link>      links;
    vector<leap>      leaps;

    const time_zone* locate_zone(string_view tz_name) const;
    const time_zone* current_zone() const;
  };
}
Each vector in a tzdb object is sorted to enable fast lookup.
const time_zone* locate_zone(string_view tz_name) const;
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 for which tz_­name == link.name(), then a pointer is returned to the time_­zone for which zone.name() == link.target().
[ Note
:
A link specifies an alternative name for a time_­zone.
— end note
 ]
Throws: If a const time_­zone* cannot be found as described in the Returns: clause, throws a 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() const;
Returns: A pointer to the time zone which the computer has set as its local time zone.

25.10.2.2 Class tzdb_­list [time.zone.db.list]

namespace std::chrono {
  class tzdb_list {
  public:
    tzdb_list(const tzdb_list&) = delete;
    tzdb_list& operator=(const tzdb_list&) = delete;

    // unspecified additional constructors

    class const_iterator;

    const tzdb& front() const noexcept;

    const_iterator erase_after(const_iterator p);

    const_iterator begin() const noexcept;
    const_iterator end()   const noexcept;

    const_iterator cbegin() const noexcept;
    const_iterator cend()   const noexcept;
  };
}
The tzdb_­list database is a singleton; the unique object of type tzdb_­list can be accessed via the get_­tzdb_­list() function.
[ Note
:
This access is only needed for those applications that need to have long uptimes and have a need to update the time zone database while running.
Other applications can implicitly access the front() of this list via the read-only namespace scope functions get_­tzdb(), locate_­zone(), and current_­zone().
— end note
 ]
The tzdb_­list object contains a list of tzdb objects.
tzdb_­list::const_­iterator is a constant iterator which meets the Cpp17ForwardIterator requirements and has a value type of tzdb.
const tzdb& front() const noexcept;
Returns: A reference to the first tzdb in the container.
Remarks: This operation is thread-safe with respect to reload_­tzdb().
[ Note
:
reload_­tzdb() pushes a new tzdb onto the front of this container.
— end note
 ]
const_iterator erase_after(const_iterator p);
Requires: The iterator following p is dereferenceable.
Effects: Erases the tzdb referred to by the iterator following p.
Returns: An iterator pointing to the element following the one that was erased, or end() if no such element exists.
Remarks: No pointers, references, or iterators are invalidated except those referring to the erased tzdb.
[ Note
:
It is not possible to erase the tzdb referred to by begin().
— end note
 ]
Throws: Nothing.
const_iterator begin() const noexcept;
Returns: An iterator referring to the first tzdb in the container.
const_iterator end() const noexcept;
Returns: An iterator referring to the position one past the last tzdb in the container.
const_iterator cbegin() const noexcept;
Returns: begin().
const_iterator cend() const noexcept;
Returns: end().

25.10.2.3 Time zone database access [time.zone.db.access]

tzdb_list& get_tzdb_list();
Effects: If this is the first access to the time zone database, initializes the database.
If this call initializes the database, the resulting database will be a tzdb_­list holding a single initialized tzdb.
Returns: A reference to the database.
Remarks: It is safe to call this function from multiple threads at one time.
Throws: runtime_­error if for any reason a reference cannot be returned to a valid tzdb_­list containing one or more valid tzdbs.
const tzdb& get_tzdb();
Returns: get_­tzdb_­list().front().
const time_zone* locate_zone(string_view tz_name);
Returns: get_­tzdb().locate_­zone(tz_­name).
[ Note
:
The time zone database will be initialized if this is the first reference to the database.
— end note
 ]
const time_zone* current_zone();
Returns: get_­tzdb().current_­zone().

25.10.2.4 Remote time zone database support [time.zone.db.remote]

The local time zone database is that supplied by the implementation when the program first accesses the database, for example via current_­zone().
While the program is running, the implementation may choose to update the time zone database.
This update shall not impact the program in any way unless the program calls the functions in this subclause.
This potentially updated time zone database is referred to as the remote time zone database.
const tzdb& reload_tzdb();
Effects: This function first checks the version of the remote time zone database.
If the versions of the local and remote databases are the same, there are no effects.
Otherwise the remote database is pushed to the front of the tzdb_­list accessed by get_­tzdb_­list().
Returns: get_­tzdb_­list().front().
Remarks: No pointers, references, or iterators are invalidated.
Remarks: This function is thread-safe with respect to get_­tzdb_­list().front() and get_­tzdb_­list().erase_­after().
Throws: runtime_­error if for any reason a reference cannot be returned to a valid tzdb.
string remote_version();
Returns: The latest remote database version.
[ Note
:
This can be compared with get_­tzdb().version to discover if the local and remote databases are equivalent.
— end note
 ]

25.10.3 Exception classes [time.zone.exception]

25.10.3.1 Class nonexistent_­local_­time [time.zone.exception.nonexist]

namespace std::chrono {
  class nonexistent_local_time : public runtime_error {
  public:
    template<class Duration>
      nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
  };
}
nonexistent_­local_­time is thrown when an attempt is made to convert a non-existent local_­time to a sys_­time without specifying choose::earliest or choose::latest.
template<class Duration> nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
Requires: i.result == local_­info::nonexistent.
Effects: Constructs a nonexistent_­local_­time by initializing the base class with a sequence of char equivalent to that produced by os.str() initialized as shown below:
ostringstream os;
os << tp << " is in a gap between\n"
   << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' '
   << i.first.abbrev << " and\n"
   << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' '
   << i.second.abbrev
   << " which are both equivalent to\n"
   << i.first.end << " UTC";
[ Example
:
#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;
  try {
    auto zt = zoned_time{"America/New_York",
                         local_days{Sunday[2]/March/2016} + 2h + 30min};
  } catch (const nonexistent_local_time& e) {
    std::cout << e.what() << '\n';
  }
}
Produces the output:
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
 ]

25.10.3.2 Class ambiguous_­local_­time [time.zone.exception.ambig]

namespace std::chrono {
  class ambiguous_local_time : public runtime_error {
  public:
    template<class Duration>
      ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
  };
}
ambiguous_­local_­time is thrown when an attempt is made to convert an ambiguous local_­time to a sys_­time without specifying choose::earliest or choose::latest.
template<class Duration> ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
Requires: i.result == local_­info::ambiguous.
Effects: Constructs an ambiguous_­local_­time by initializing the base class with a sequence of char equivalent to that produced by os.str() initialized as shown below:
ostringstream os;
os << tp << " is ambiguous.  It could be\n"
   << tp << ' ' << i.first.abbrev << " == "
   << tp - i.first.offset << " UTC or\n"
   << tp << ' ' << i.second.abbrev  << " == "
   << tp - i.second.offset  << " UTC";
[ Example
:
#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;
  try {
    auto zt = zoned_time{"America/New_York",
                         local_days{Sunday[1]/November/2016} + 1h + 30min};
  } catch (const ambiguous_local_time& e) {
    std::cout << e.what() << '\n';
  }
}
Produces the output:
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
 ]

25.10.4 Information classes [time.zone.info]

25.10.4.1 Class sys_­info [time.zone.info.sys]

namespace std::chrono {
  struct sys_info {
    sys_seconds   begin;
    sys_seconds   end;
    seconds       offset;
    minutes       save;
    string        abbrev;
  };
}
A sys_­info object 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.
[ Note
:
This type provides a low-level interface to time zone information.
Typical conversions from sys_­time to local_­time will use this class implicitly, not explicitly.
— end note
 ]
The begin and end data members 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 data member 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 data member 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 offset this time_­zone might use if it were off daylight saving time.
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 a sys_­info where save == 0min.
There is no guarantee what time_­point might return such a sys_­info except that it is guaranteed not to be in the range [begin, end) (if save != 0min for this sys_­info).
The abbrev data member indicates the current abbreviation used for the associated time_­zone and time_­point.
Abbreviations are not unique among the time_­zones, and so one cannot reliably map abbreviations back to a time_­zone and UTC offset.
template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const sys_info& r);
Effects: Streams out the sys_­info object r in an unspecified format.

25.10.4.2 Class local_­info [time.zone.info.local]

namespace std::chrono {
  struct local_info {
    static constexpr int unique      = 0;
    static constexpr int nonexistent = 1;
    static constexpr int ambiguous   = 2;

    int result;
    sys_info first;
    sys_info second;
  };
}
[ Note
:
This type provides a low-level interface to time zone information.
Typical conversions from local_­time to sys_­time will use this class implicitly, not explicitly.
— end note
 ]
Describes the result of converting a local_­time to a sys_­time as follows:
  • 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.
template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const local_info& r);
Streams out the local_­info object r in an unspecified format.

25.10.5 Class time_­zone [time.zone.timezone]

25.10.5.1 Overview [time.zone.overview]

namespace std::chrono {
  class time_zone {
  public:
    time_zone(time_zone&&) = default;
    time_zone& operator=(time_zone&&) = default;

    // unspecified additional constructors

    string_view name() const noexcept;

    template<class Duration> sys_info   get_info(const sys_time<Duration>& st)   const;
    template<class Duration> local_info get_info(const local_time<Duration>& tp) const;

    template<class Duration>
      sys_time<common_type_t<Duration, seconds>>
        to_sys(const local_time<Duration>& tp) const;

    template<class Duration>
      sys_time<common_type_t<Duration, seconds>>
        to_sys(const local_time<Duration>& tp, choose z) const;

    template<class Duration>
      local_time<common_type_t<Duration, seconds>>
        to_local(const sys_time<Duration>& tp) const;
  };
}
A time_­zone represents all time zone transitions for a specific geographic area.
time_­zone construction is unspecified, and performed as part of database initialization.
[ Note
:
const time_­zone objects can be accessed via functions such as locate_­zone.
— end note
 ]

25.10.5.2 Member functions [time.zone.members]

string_view name() const noexcept;
Returns: The name of the time_­zone.
[ Example
:
"America/New_­York".
— end example
 ]
template<class Duration> sys_info get_info(const 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 get_info(const local_time<Duration>& tp) const;
Returns: A local_­info for tp.
template<class Duration> sys_time<common_type_t<Duration, seconds>> to_sys(const 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 tp represents a non-existent time between two UTC time_­points, throws nonexistent_­local_­time.
template<class Duration> sys_time<common_type_t<Duration, seconds>> to_sys(const 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<common_type_t<Duration, seconds>> to_local(const sys_time<Duration>& tp) const;
Returns: The local_­time associated with tp and this time_­zone.

25.10.5.3 Non-member functions [time.zone.nonmembers]

bool operator==(const time_zone& x, const time_zone& y) noexcept;
Returns: x.name() == y.name().
bool operator<(const time_zone& x, const time_zone& y) noexcept;
Returns: x.name() < y.name().

25.10.6 Class template zoned_­traits [time.zone.zonedtraits]

namespace std::chrono {
  template<class T> struct zoned_traits {};
}
zoned_­traits provides a means for customizing the behavior of zoned_­time<Duration, TimeZonePtr> for the zoned_­time default constructor, and constructors taking string_­view.
A specialization for const time_­zone* is provided by the implementation:
namespace std::chrono {
  template<> struct zoned_traits<const time_zone*> {
    static const time_zone* default_zone();
    static const time_zone* locate_zone(string_view name);
  };
}
static const time_zone* default_zone();
Returns: std::chrono::locate_­zone("UTC").
static const time_zone* locate_zone(string_view name);
Returns: std::chrono::locate_­zone(name).

25.10.7 Class template zoned_­time [time.zone.zonedtime]

25.10.7.1 Overview [time.zone.zonedtime.overview]

namespace std::chrono {
  template<class Duration, class TimeZonePtr = const time_zone*>
  class zoned_time {
  public:
    using duration = common_type_t<Duration, seconds>;

  private:
    TimeZonePtr        zone_;                   // exposition only
    sys_time<duration> tp_;                     // exposition only

    using traits = zoned_traits<TimeZonePtr>;   // exposition only

  public:
    zoned_time();
    zoned_time(const zoned_time&) = default;
    zoned_time& operator=(const zoned_time&) = default;

    zoned_time(const sys_time<Duration>& st);
    explicit zoned_time(TimeZonePtr z);
    explicit zoned_time(string_view name);

    template<class Duration2>
      zoned_time(const zoned_time<Duration2, TimeZonePtr>& zt) noexcept;

    zoned_time(TimeZonePtr z,    const sys_time<Duration>& st);
    zoned_time(string_view name, const sys_time<Duration>& st);

    zoned_time(TimeZonePtr z,    const local_time<Duration>& tp);
    zoned_time(string_view name, const local_time<Duration>& tp);
    zoned_time(TimeZonePtr z,    const local_time<Duration>& tp, choose c);
    zoned_time(string_view name, const local_time<Duration>& tp, choose c);

    template<class Duration2, class TimeZonePtr2>
      zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& zt);
    template<class Duration2, class TimeZonePtr2>
      zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& zt, choose);

    zoned_time(string_view name, const zoned_time<Duration>& zt);
    zoned_time(string_view name, const zoned_time<Duration>& zt, choose);

    zoned_time& operator=(const sys_time<Duration>& st);
    zoned_time& operator=(const local_time<Duration>& ut);

    operator sys_time<duration>() const;
    explicit operator local_time<duration>() const;

    TimeZonePtr          get_time_zone()  const;
    local_time<duration> get_local_time() const;
    sys_time<duration>   get_sys_time()   const;
    sys_info             get_info()       const;
  };

  zoned_time() -> zoned_time<seconds>;

  template<class Duration>
    zoned_time(sys_time<Duration>)
      -> zoned_time<common_type_t<Duration, seconds>>;

  template<class TimeZonePtr, class Duration>
    zoned_time(TimeZonePtr, sys_time<Duration>)
      -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;

  template<class TimeZonePtr, class Duration>
    zoned_time(TimeZonePtr, local_time<Duration>, choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;

  template<class TimeZonePtr, class Duration>
    zoned_time(TimeZonePtr, zoned_time<Duration>, choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;

  zoned_time(string_view) -> zoned_time<seconds>;

  template<class Duration>
    zoned_time(string_view, sys_time<Duration>)
      -> zoned_time<common_type_t<Duration, seconds>>;

  template<class Duration>
    zoned_time(string_view, local_time<Duration>, choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>>;

  template<class Duration, class TimeZonePtr, class TimeZonePtr2>
    zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
      -> zoned_time<Duration, TimeZonePtr>;
}
zoned_­time represents a logical pairing of a time_­zone and a time_­point with precision Duration.
zoned_­time<Duration> maintains the invariant that it always refers to a valid time zone and represents a point in time that exists and is not ambiguous in that time zone.
If Duration is not a specialization of chrono::duration, the program is ill-formed.

25.10.7.2 Constructors [time.zone.zonedtime.ctor]

zoned_time();
Remarks: This constructor does not participate in overload resolution unless traits::default_­zone() is a well-formed expression.
Effects: Constructs a zoned_­time by initializing zone_­ with traits::default_­zone() and default constructing tp_­.
zoned_time(const sys_time<Duration>& st);
Remarks: This constructor does not participate in overload resolution unless traits::default_­zone() is a well-formed expression.
Effects: Constructs a zoned_­time by initializing zone_­ with traits::default_­zone() and tp_­ with st.
explicit zoned_time(TimeZonePtr z);
Requires: z refers to a time zone.
Effects: Constructs a zoned_­time by initializing zone_­ with std::move(z).
explicit zoned_time(string_view name);
Remarks: This constructor does not participate in overload resolution unless traits::locate_­zone(string_­view{}) is a well-formed expression and zoned_­time is constructible from the return type of traits::locate_­zone(string_­view{}).
Effects: Constructs a zoned_­time by initializing zone_­ with traits::locate_­zone(name) and default constructing tp_­.
template<class Duration2> zoned_time(const zoned_time<Duration2, TimeZonePtr>& y) noexcept;
Remarks: Does not participate in overload resolution unless sys_­time<Duration2> is implicitly convertible to sys_­time<Duration>.
Effects: Constructs a zoned_­time by initializing zone_­ with y.zone_­ and tp_­ with y.tp_­.
zoned_time(TimeZonePtr z, const sys_time<Duration>& st);
Requires: z refers to a time zone.
Effects: Constructs a zoned_­time by initializing zone_­ with std::move(z) and tp_­ with st.
zoned_time(string_view name, const sys_time<Duration>& st);
Remarks: This constructor does not participate in overload resolution unless zoned_­time is constructible from the return type of traits::locate_­zone(name) and st.
Effects: Equivalent to construction with {traits::locate_­zone(name), st}.
zoned_time(TimeZonePtr z, const local_time<Duration>& tp);
Requires: z refers to a time zone.
Remarks: This constructor does not participate in overload resolution unless
decltype(declval<TimeZonePtr&>()->to_sys(local_time<Duration>{}))
is convertible to sys_­time<duration>.
Effects: Constructs a zoned_­time by initializing zone_­ with std::move(z) and tp_­ with zone_­->to_­sys(tp).
zoned_time(string_view name, const local_time<Duration>& tp);
Remarks: This constructor does not participate in overload resolution unless zoned_­time is constructible from the return type of traits::locate_­zone(name) and tp.
Effects: Equivalent to construction with {traits::locate_­zone(name), tp}.
zoned_time(TimeZonePtr z, const local_time<Duration>& tp, choose c);
Requires: z refers to a time zone.
Remarks: This constructor does not participate in overload resolution unless
decltype(declval<TimeZonePtr&>()->to_sys(local_time<Duration>{}, choose::earliest))
is convertible to sys_­time<duration>.
Effects: Constructs a zoned_­time by initializing zone_­ with std::move(z) and tp_­ with zone_­->to_­sys(tp, c).
zoned_time(string_view name, const local_time<Duration>& tp, choose c);
Remarks: This constructor does not participate in overload resolution unless zoned_­time is constructible from the return type of traits::locate_­zone(name), local_­time<Duration>, and choose.
Effects: Equivalent to construction with {traits::locate_­zone(name), tp, c}.
template<class Duration2, class TimeZonePtr2> zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y);
Remarks: Does not participate in overload resolution unless sys_­time<Duration2> is implicitly convertible to sys_­time<Duration>.
Requires: z refers to a valid time zone.
Effects: Constructs a zoned_­time by initializing zone_­ with std::move(z) and tp_­ with y.tp_­.
template<class Duration2, class TimeZonePtr2> zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y, choose);
Remarks: Does not participate in overload resolution unless sys_­time<Duration2> is implicitly convertible to sys_­time<Duration>.
Requires: z refers to a valid time zone.
Effects: Equivalent to construction with {z, y}.
[ Note
:
The choose parameter has no effect.
— end note
 ]
zoned_time(string_view name, const zoned_time<Duration>& y);
Remarks: This constructor does not participate in overload resolution unless zoned_­time is constructible from the return type of traits::locate_­zone(name) and zoned_­time.
Effects: Equivalent to construction with {traits::locate_­zone(name), y}.
zoned_time(string_view name, const zoned_time<Duration>& y, choose c);
Remarks: This constructor does not participate in overload resolution unless zoned_­time is constructible from the return type of traits::locate_­zone(name), zoned_­time, and choose.
Effects: Equivalent to construction with {traits::locate_­zone(name), y, c}.
[ Note
:
The choose parameter has no effect.
— end note
 ]

25.10.7.3 Member functions [time.zone.zonedtime.members]

zoned_time& operator=(const 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& operator=(const 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.
operator sys_time<duration>() const;
Returns: get_­sys_­time().
explicit operator local_time<duration>() const;
Returns: get_­local_­time().
TimeZonePtr get_time_zone() const;
Returns: zone_­.
local_time<duration> get_local_time() const;
Returns: zone_­->to_­local(tp_­).
sys_time<duration> get_sys_time() const;
Returns: tp_­.
sys_info get_info() const;
Returns: zone_­->get_­info(tp_­).

25.10.7.4 Non-member functions [time.zone.zonedtime.nonmembers]

template<class Duration1, class Duration2, class TimeZonePtr> bool operator==(const zoned_time<Duration1, TimeZonePtr>& x, const zoned_time<Duration2, TimeZonePtr>& y);
Returns: x.zone_­ == y.zone_­ && x.tp_­ == y.tp_­.
template<class Duration1, class Duration2, class TimeZonePtr> bool operator!=(const zoned_time<Duration1, TimeZonePtr>& x, const zoned_time<Duration2, TimeZonePtr>& y);
Returns: !(x == y).
template<class charT, class traits, class Duration, class TimeZonePtr> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const zoned_time<Duration, TimeZonePtr>& t);
Effects: Streams the value returned from t.get_­local_­time() to os using the format "%F %T %Z".
Returns: os.
template<class charT, class traits, class Duration, class TimeZonePtr> basic_ostream<charT, traits>& to_stream(basic_ostream<charT, traits>& os, const charT* fmt, const zoned_time<Duration, TimeZonePtr>& tp);
Effects: First obtains a sys_­info via tp.get_­info() which for exposition purposes will be referred to as info.
Then calls to_­stream(os, fmt, tp.get_­local_­time(), &info.abbrev, &info.offset).
Returns: os.

25.10.8 Class leap [time.zone.leap]

25.10.8.1 Overview [time.zone.leap.overview]

namespace std::chrono {
  class leap {
  public:
    leap(const leap&)            = default;
    leap& operator=(const leap&) = default;

    // unspecified additional constructors

    constexpr sys_seconds date() const noexcept;
  };
}
Objects of type leap representing the date of the leap second insertions are constructed and stored in the time zone database when initialized.
[ Example
:
for (auto& l : get_tzdb().leaps)
  if (l <= 2018y/March/17d)
    cout << l.date() << '\n';
Produces the output:
1972-07-01 00:00:00
1973-01-01 00:00:00
1974-01-01 00:00:00
1975-01-01 00:00:00
1976-01-01 00:00:00
1977-01-01 00:00:00
1978-01-01 00:00:00
1979-01-01 00:00:00
1980-01-01 00:00:00
1981-07-01 00:00:00
1982-07-01 00:00:00
1983-07-01 00:00:00
1985-07-01 00:00:00
1988-01-01 00:00:00
1990-01-01 00:00:00
1991-01-01 00:00:00
1992-07-01 00:00:00
1993-07-01 00:00:00
1994-07-01 00:00:00
1996-01-01 00:00:00
1997-07-01 00:00:00
1999-01-01 00:00:00
2006-01-01 00:00:00
2009-01-01 00:00:00
2012-07-01 00:00:00
2015-07-01 00:00:00
2017-01-01 00:00:00
— end example
 ]

25.10.8.2 Member functions [time.zone.leap.members]

constexpr sys_seconds date() const noexcept;
Returns: The date and time at which the leap second was inserted.

25.10.8.3 Non-member functions [time.zone.leap.nonmembers]

constexpr bool operator==(const leap& x, const leap& y) noexcept;
Returns: x.date() == y.date().
constexpr bool operator<(const leap& x, const leap& y) noexcept;
Returns: x.date() < y.date().
template<class Duration> constexpr bool operator==(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: x.date() == y.
template<class Duration> constexpr bool operator==(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: y == x.
template<class Duration> constexpr bool operator!=(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: !(x == y).
template<class Duration> constexpr bool operator!=(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: !(x == y).
template<class Duration> constexpr bool operator<(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: x.date() < y.
template<class Duration> constexpr bool operator<(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: x < y.date().
template<class Duration> constexpr bool operator>(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: y < x.
template<class Duration> constexpr bool operator>(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: y < x.
template<class Duration> constexpr bool operator<=(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: !(y < x).
template<class Duration> constexpr bool operator<=(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: !(y < x).
template<class Duration> constexpr bool operator>=(const leap& x, const sys_time<Duration>& y) noexcept;
Returns: !(x < y).
template<class Duration> constexpr bool operator>=(const sys_time<Duration>& x, const leap& y) noexcept;
Returns: !(x < y).