| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 13. Time</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><meta name="keywords" content="ISO C++, library" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="../index.html" title="The GNU C++ Library" /><link rel="up" href="std_contents.html" title="Part II. Standard Contents" /><link rel="prev" href="numerics_and_c.html" title="Interacting with C" /><link rel="next" href="io.html" title="Chapter 14. Input and Output" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 13. |
| Time |
| |
| </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="numerics_and_c.html">Prev</a> </td><th width="60%" align="center">Part II. |
| Standard Contents |
| </th><td width="20%" align="right"> <a accesskey="n" href="io.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="std.time"></a>Chapter 13. |
| Time |
| <a id="id-1.3.4.11.1.1.1" class="indexterm"></a> |
| </h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="time.html#std.time.zone.db">Time zone database</a></span></dt><dd><dl><dt><span class="section"><a href="time.html#zone.db.zic">tzdb uses zic format</a></span></dt><dt><span class="section"><a href="time.html#zone.current">current zone</a></span></dt><dt><span class="section"><a href="time.html#zone.db.sources">data sources</a></span></dt><dt><span class="section"><a href="time.html#zone.db.iterator">tzdb_list::const_iterator extends lifetime</a></span></dt></dl></dd></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.time.zone.db"></a>Time zone database</h2></div></div></div><p> |
| Since C++20 the <code class="code"><chrono></code> header provides time zone |
| support via <code class="code">std::chrono::tzdb</code>, a complete interface to the |
| <a class="link" href="https://www.iana.org/time-zones" target="_top">IANA Time Zone Database</a>. |
| The library supports converting times between UTC and the local time |
| in a specific time zone, querying UTC offsets and DST information for a |
| given time zone on a given date, and finding the system's current time zone. |
| Key entry points are <code class="code">std::chrono::get_tzdb()</code> to access |
| the database, <code class="code">std::chrono::locate_zone()</code> to look up |
| a zone by name, and <code class="code">std::chrono::current_zone()</code> to obtain |
| the system's local time zone. The <code class="code">std::chrono::zoned_time</code> |
| class template represents a time point in a given time zone. |
| The database can be reloaded at runtime |
| via <code class="code">std::chrono::reload_tzdb()</code> to pick up updated zone |
| data without restarting the program. |
| </p><p> |
| The <a class="link" href="https://howardhinnant.github.io/date/tz.html" target="_top">Time Zone Database |
| Parser</a> by Howard E. Hinnant is a valuable source of information and |
| examples of usage for the <code class="code">date</code> library, on which the standard |
| API is based. |
| </p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="zone.db.zic"></a>tzdb uses zic format</h3></div></div></div><p> |
| When support is enabled (which is default) the time zone database class, |
| <code class="code">tzdb</code>, uses the <a class="link" href="https://man7.org/linux/man-pages/man8/zic.8.html#FILES" target="_top"> |
| <code class="code">zic</code> file format</a>, both as the format of the input |
| files, and for in-memory representation. This results in a reduced |
| memory footprint for many programs, as time zone data is stored in |
| a compact form until needed by the application. |
| </p><p> |
| The transitions to/from DST (Daylight Savings Time) are generated and |
| cached on the fly, when information |
| for a given zone is requested. Consequently, the initial request for |
| UTC conversion for a given <code class="code">time_zone</code> object is slower. |
| To mitigate this, a <code class="code">time_zone</code> can be expanded for a |
| particular time range at the start |
| of the program (and after each reload), by iterating over the |
| <code class="code">sys_info</code> dequence, as in the example below. |
| </p><pre class="programlisting"> |
| void |
| expand_zone(const std::chrono::time_zone* tz, |
| const std::chrono::sys_seconds start, |
| const std::chrono::sys_seconds end) |
| { |
| std::chrono::sys_seconds time = start; |
| while (time < end) { |
| const std::chrono::sys_info& info = tz->get_info(time); |
| time = info.end + std::chrono::seconds(1); |
| } |
| } |
| </pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="zone.current"></a>current zone</h3></div></div></div><p> |
| The <code class="code">time_zone</code> pointer returned from |
| <code class="code">std::chrono::current_zone</code>, is determined by looking up |
| (by <code class="code">std::chrono::locate_zone</code>) IANA zone name |
| determined as follows (for platforms other than AIX and Windows): |
| </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> |
| On system supporting <code class="code">readlink</code>, suffix components of the |
| path of the file linked by <code class="code">/etc/localtime</code>. The suffixes |
| are matched in the other of increasing length, starting from the final |
| component, until the match is found in the time zone database. |
| Any repeated slashes (<code class="code">//</code>) are eliminated. |
| </li><li class="listitem"> |
| Names stored in the files <code class="code">/etc/timezone</code> (Debian |
| derivatives) or <code class="code">/var/db/zoneinfo</code> (FreeBSD) in that order. |
| </li><li class="listitem"> |
| Values for <code class="code">TIMEZONE</code> and <code class="code">ZONE</code> keys in |
| <code class="code">/etc/sysconfig/clock</code>. |
| </li><li class="listitem"><code class="code">UTC</code>. |
| </li></ul></div><p> |
| For AIX, the value of <code class="code">TZ</code> environment value is used, with |
| fallback to <code class="code">UTC</code>. |
| </p><p> |
| On Windows <code class="code">TimeZoneKeyName</code> is mapped to the IANA zone, using |
| internal mapping hard-coded in library, with fallback to <code class="code">UTC</code>: |
| </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> |
| If the returned <code class="code">TimeZoneKeyName</code> is empty or DST is disabled, |
| then a value based on <code class="code">Bias</code> is returned: <code class="code">Etc/UTC</code> |
| for zero, <code class="code">Etc/GMT+/-N</code> for value that is multiply of 60, |
| and empty string otherwise. |
| </li><li class="listitem"> |
| If the mapping contains a single entry for <code class="code">TimeZoneKeyName</code>, |
| that name is used. |
| </li><li class="listitem"> |
| If <code class="code">TimeZoneKeyName</code> corresponds to multiple IANA zones, |
| a 2-letter country code is used, retrieved by applying <code class="code">GetGeoInfoW</code> |
| on the result of <code class="code">GetUserGeoID(GEOCLASS_NATION)</code>. |
| If determining the country code fails, or no entry exits for a given code, |
| the first mapping entry (<code class="code">001</code>) is returned. |
| </li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="zone.db.sources"></a>data sources</h3></div></div></div><p> |
| Depending on the build configuration (see |
| <code class="code">--with-libstdcxx-zoneinfo=</code> documentation in |
| <a class="xref" href="configure.html" title="Configure">Configuring</a>). |
| the content of the time zone database is sourced from |
| <code class="filename">tzdata.zi</code> and <code class="filename">leapseconds</code> files |
| located in <span class="emphasis"><em>zoneinfo_dir</em></span>, or from static information |
| embedded in the library. |
| </p><p> |
| By default, <span class="emphasis"><em>zoneinfo_dir</em></span> is set to the |
| system-specific default directory (if a suitable dir is known for target), |
| usually <code class="code">/usr/share/zoneinfo</code>. If no such directory |
| exits, or it does not contain the required files in the correct format, |
| embedded static data is used as fallback. |
| </p><p> |
| In addition to <code class="code">--with-libstdcxx-zoneinfo=</code> configure option |
| (used during GCC build), the path of <span class="emphasis"><em>zoneinfo_dir</em></span> |
| can be overridden by the application by providing a definition of the |
| <code class="code">__gnu_cxx::zoneinfo_dir_overrride()</code> function. The |
| returned path should be directory that contains <code class="code">tzdata.zi</code> |
| and <code class="code">leapseconds</code> files in the |
| <a class="link" href="https://man7.org/linux/man-pages/man8/zic.8.html#FILES" target="_top"> |
| <code class="code">zic</code> format</a>. |
| </p><p> |
| The embedded timezone information corresponds to the copy of the |
| IANA database at the time of the release, and its version can be queried |
| using <code class="code">std::chrono::get_tzdb().version</code>. |
| </p><p> |
| The full time zone database can be disabled when GCC is configured, |
| in which case a minimal time zone database is provided. This minimal |
| database can be identified by <code class="code">chrono::get_tzdb().version</code> |
| being set to <code class="code">"ersatz"</code>. This database contains leapseconds |
| data, <code class="code">Etc/UTC</code>, <code class="code">Etc/GMT</code> zones, and their aliases |
| (<code class="code">Etc/Zulu</code>, <code class="code">Etc/UCT</code>, <code class="code">Etc/Universal</code>, |
| <code class="code">Etc/Greenwich</code>, <code class="code">Etc/GMT0</code>, <code class="code">Etc/GMT+0</code>, |
| <code class="code">Etc/GMT-0</code>). This information is sufficient to support |
| conversion between <code class="code">utc_clock</code> and <code class="code">sys_clock</code>, |
| as well as a <code class="code">UTC</code> fallback for <code class="code">current_zone</code> |
| (<a class="xref" href="time.html#zone.current" title="current zone">current zone</a>). |
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="zone.db.iterator"></a>tzdb_list::const_iterator extends lifetime</h3></div></div></div><p> |
| The <code class="code">std::chrono::reload_tzdb()</code> function may be used to load |
| updated content of the <code class="code">tzdata.zi</code> and <code class="code">leapseconds</code> |
| files from <span class="emphasis"><em>zoneinfo_dir</em></span> (if |
| <a class="xref" href="time.html#zone.db.sources" title="data sources">data sources</a>). If the version is different |
| (<code class="code">std::chrono::remote_version() != std::chrono::get_tzdb().version</code>), |
| a new element is added at the front of the <code class="code">tzdb_list</code>. |
| This new database is used for subsequent calls to <code class="code">current_zone</code> |
| and <code class="code">locate_zone</code>. |
| </p><p> |
| The above process is thread-safe, and does not invalidate nor change any |
| pre-existing pointers to <code class="code">time_zone</code> objects. However, for a |
| long-running application it may lead to accumulation of time zone data, |
| and thus increased memory usage. In most cases, this is acceptable even |
| for long-running applications, due to infrequent updates to the IANA database, |
| and the reduced footprint of the libstdc++ implementation (see |
| <a class="xref" href="time.html#zone.db.zic" title="tzdb uses zic format">tzdb uses zic format</a>). |
| </p><p> |
| If accumulating old <code class="code">tzdb</code> databases is not acceptable |
| (e.g. due to memory constraints), entries |
| may be removed from <code class="code">tzdb_list</code> using <code class="code">tzdb_list::erase_after</code>. |
| When using this function, you are responsible for ensuring that the application |
| no longer is no longer using any <code class="code">time_zone*</code> to a removed database. |
| If you erase a <code class="code">tzdb</code> while some part of the application is still |
| using it (or one of its <code class="code">time_zone</code> objects) you will create |
| a dangling pointer, leading to undefined behaviour. |
| To make <code class="code">tzdb_list::erase_after</code> safer, libstdc++ provides an |
| <span class="emphasis"><em>extension</em></span> that avoids creating dangling pointers. |
| The <code class="code">tzdb_list</code> uses <code class="code">shared_ptr<tzdb></code> to |
| refer to each entry in the list, and <code class="code">tzdb_list::const_iterator</code> |
| also uses a <code class="code">shared_ptr<tzdb></code> to refer to its target. |
| This means that iterators into the list share ownership of the list elements, |
| so that erasing an element from the list does not destroy it if there are |
| any iterators which share ownership of the element. The application can |
| use this to ensure that <code class="code">tzdb</code> and <code class="code">time_zone</code> |
| objects are not destroyed while they're still being used. The lifetime |
| of a <code class="code">tzdb</code> that is still in use can be extended by holding |
| onto a <code class="code">tzdb_list::const_iterator</code> that refers to it. |
| </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="numerics_and_c.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="std_contents.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="io.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Interacting with C </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 14. |
| Input and Output |
| |
| </td></tr></table></div></body></html> |