[PATCH] libstdc++: Document std::chrono::tzdb database implementation.
Jonathan Wakely <[email protected]> Mon, 3 Aug 2026 17:31:00 +0100
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.libstdc++.devel |
|---|---|
| Message-ID | <[email protected]> |
From: Tomasz KamiĆski <[email protected]> libstdc++-v3/ChangeLog: * doc/Makefile.am: Add time.xml. * doc/Makefile.in: Regenerate. * doc/html/*: Regenerate. * doc/xml/manual/spine.xml: Add time.xml. * doc/xml/manual/time.xml: New file. --- Same patch again but without the huge changes to the generated HTML files, because that made the patch too big for gcc-patches. libstdc++-v3/doc/Makefile.am | 1 + libstdc++-v3/doc/Makefile.in | 1 + libstdc++-v3/doc/html/index.html | 15 +- libstdc++-v3/doc/html/manual/api.html | 2 +- libstdc++-v3/doc/html/manual/atomics.html | 8 +- .../doc/html/manual/bitmap_allocator.html | 4 +- .../html/manual/bitmap_allocator_impl.html | 6 +- libstdc++-v3/doc/html/manual/concurrency.html | 8 +- libstdc++-v3/doc/html/manual/debug.html | 6 +- libstdc++-v3/doc/html/manual/debug_mode.html | 6 +- .../doc/html/manual/debug_mode_design.html | 4 +- .../doc/html/manual/debug_mode_semantics.html | 4 +- .../doc/html/manual/debug_mode_using.html | 6 +- .../doc/html/manual/ext_algorithms.html | 6 +- .../doc/html/manual/ext_compile_checks.html | 6 +- .../doc/html/manual/ext_concurrency.html | 6 +- .../doc/html/manual/ext_concurrency_impl.html | 4 +- .../doc/html/manual/ext_concurrency_use.html | 2 +- .../doc/html/manual/ext_containers.html | 4 +- .../doc/html/manual/ext_demangling.html | 6 +- libstdc++-v3/doc/html/manual/ext_io.html | 6 +- .../doc/html/manual/ext_iterators.html | 6 +- .../doc/html/manual/ext_numerics.html | 6 +- libstdc++-v3/doc/html/manual/ext_preface.html | 4 +- libstdc++-v3/doc/html/manual/ext_sgi.html | 4 +- .../doc/html/manual/ext_utilities.html | 6 +- libstdc++-v3/doc/html/manual/extensions.html | 8 +- libstdc++-v3/doc/html/manual/fstreams.html | 2 +- libstdc++-v3/doc/html/manual/index.html | 31 ++- libstdc++-v3/doc/html/manual/io.html | 13 +- libstdc++-v3/doc/html/manual/io_and_c.html | 6 +- libstdc++-v3/doc/html/manual/memory.html | 6 +- .../doc/html/manual/mt_allocator.html | 4 +- .../doc/html/manual/mt_allocator_design.html | 4 +- .../html/manual/mt_allocator_ex_multi.html | 4 +- .../html/manual/mt_allocator_ex_single.html | 2 +- .../doc/html/manual/mt_allocator_impl.html | 2 +- .../doc/html/manual/numerics_and_c.html | 8 +- .../doc/html/manual/parallel_mode.html | 4 +- .../doc/html/manual/parallel_mode_design.html | 2 +- .../html/manual/parallel_mode_semantics.html | 4 +- .../doc/html/manual/parallel_mode_test.html | 4 +- .../doc/html/manual/parallel_mode_using.html | 4 +- .../policy_based_data_structures_test.html | 2 +- .../html/manual/policy_data_structures.html | 16 +- .../manual/policy_data_structures_ack.html | 4 +- .../manual/policy_data_structures_design.html | 70 ++--- .../manual/policy_data_structures_using.html | 6 +- libstdc++-v3/doc/html/manual/status.html | 4 +- .../doc/html/manual/std_contents.html | 9 +- libstdc++-v3/doc/html/manual/streambufs.html | 4 +- .../doc/html/manual/stringstreams.html | 2 +- libstdc++-v3/doc/html/manual/test.html | 8 +- libstdc++-v3/doc/html/manual/time.html | 176 +++++++++++++ libstdc++-v3/doc/html/manual/using.html | 2 +- .../doc/html/manual/using_macros.html | 10 +- libstdc++-v3/doc/xml/manual/spine.xml | 10 +- libstdc++-v3/doc/xml/manual/time.xml | 242 ++++++++++++++++++ 58 files changed, 623 insertions(+), 187 deletions(-) create mode 100644 libstdc++-v3/doc/html/manual/time.html create mode 100644 libstdc++-v3/doc/xml/manual/time.xml diff --git a/libstdc++-v3/doc/Makefile.am b/libstdc++-v3/doc/Makefile.am index 330b07ccf8ce..69f5faafc266 100644 --- a/libstdc++-v3/doc/Makefile.am +++ b/libstdc++-v3/doc/Makefile.am @@ -357,6 +357,7 @@ xml_sources_manual = \ ${xml_dir}/manual/support.xml \ ${xml_dir}/manual/test.xml \ ${xml_dir}/manual/test_policy_data_structures.xml \ + ${xml_dir}/manual/time.xml \ ${xml_dir}/manual/using.xml \ ${xml_dir}/manual/using_exceptions.xml \ ${xml_dir}/manual/utilities.xml \ diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in index 6e7a5a0f9084..39a6988d4853 100644 --- a/libstdc++-v3/doc/Makefile.in +++ b/libstdc++-v3/doc/Makefile.in @@ -509,6 +509,7 @@ xml_sources_manual = \ ${xml_dir}/manual/support.xml \ ${xml_dir}/manual/test.xml \ ${xml_dir}/manual/test_policy_data_structures.xml \ + ${xml_dir}/manual/time.xml \ ${xml_dir}/manual/using.xml \ ${xml_dir}/manual/using_exceptions.xml \ ${xml_dir}/manual/utilities.xml \ diff --git a/libstdc++-v3/doc/xml/manual/spine.xml b/libstdc++-v3/doc/xml/manual/spine.xml index eff72bc13d72..47536f000778 100644 --- a/libstdc++-v3/doc/xml/manual/spine.xml +++ b/libstdc++-v3/doc/xml/manual/spine.xml @@ -197,15 +197,19 @@ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="xml" href="numerics.xml"> </xi:include> -<!-- Chapter 10 : Input Output --> +<!-- Chapter 10 : Time --> +<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="xml" href="time.xml"> +</xi:include> + +<!-- Chapter 11 : Input Output --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="xml" href="io.xml"> </xi:include> -<!-- Chapter 11 : Atomics --> +<!-- Chapter 12 : Atomics --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="xml" href="atomics.xml"> </xi:include> -<!-- Chapter 12 : Concurrency --> +<!-- Chapter 13 : Concurrency --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="xml" href="concurrency.xml"> </xi:include> diff --git a/libstdc++-v3/doc/xml/manual/time.xml b/libstdc++-v3/doc/xml/manual/time.xml new file mode 100644 index 000000000000..b61be5852ef2 --- /dev/null +++ b/libstdc++-v3/doc/xml/manual/time.xml @@ -0,0 +1,242 @@ +<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" + xml:id="std.time" xreflabel="Time"> +<?dbhtml filename="time.html"?> + +<info><title> + Time + <indexterm><primary>Time</primary></indexterm> +</title> + <keywordset> + <keyword>ISO C++</keyword> + <keyword>library</keyword> + </keywordset> +</info> + +<!-- Sect1 01 : Time zone database --> +<section xml:id="std.time.zone.db" xreflabel=""><info><title>Time zone database</title></info> +<?dbhtml filename="tzdb.html"?> + + <para> + Since C++20 the <code><chrono></code> header provides time zone + support via <code>std::chrono::tzdb</code>, a complete interface to the + <link xmlns:xlink="http://www.w3.org/1999/xlink" + xlink:href="https://www.iana.org/time-zones">IANA Time Zone Database</link>. + 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>std::chrono::get_tzdb()</code> to access + the database, <code>std::chrono::locate_zone()</code> to look up + a zone by name, and <code>std::chrono::current_zone()</code> to obtain + the system's local time zone. The <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>std::chrono::reload_tzdb()</code> to pick up updated zone + data without restarting the program. + </para> + + <para> + The <link xmlns:xlink="http://www.w3.org/1999/xlink" + xlink:href="https://howardhinnant.github.io/date/tz.html">Time Zone Database + Parser</link> by Howard E. Hinnant is a valuable source of information and + examples of usage for the <code>date</code> library, on which the standard + API is based. + </para> + + <section xml:id="zone.db.zic" xreflabel="tzdb uses zic format"><info><title>tzdb uses zic format</title></info> + + <para> + When support is enabled (which is default) the time zone database class, + <code>tzdb</code>, uses the <link xmlns:xlink="http://www.w3.org/1999/xlink" + xlink:href="https://man7.org/linux/man-pages/man8/zic.8.html#FILES"> + <code>zic</code> file format</link>, 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. + </para> + <para> + 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>time_zone</code> object is slower. + To mitigate this, a <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>sys_info</code> dequence, as in the example below. + </para> + <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); + } + } + </programlisting> + </section> + + <section xml:id="zone.current" xreflabel="current zone"><info><title>current zone</title></info> + + <para> + The <code>time_zone</code> pointer returned from + <code>std::chrono::current_zone</code>, is determined by looking up + (by <code>std::chrono::locate_zone</code>) IANA zone name + determined as follows (for platforms other than AIX and Windows): + </para> + <itemizedlist> + <listitem> + On system supporting <code>readlink</code>, suffix components of the + path of the file linked by <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>//</code>) are eliminated. + </listitem> + <listitem> + Names stored in the files <code>/etc/timezone</code> (Debian + derivatives) or <code>/var/db/zoneinfo</code> (FreeBSD) in that order. + </listitem> + <listitem> + Values for <code>TIMEZONE</code> and <code>ZONE</code> keys in + <code>/etc/sysconfig/clock</code>. + </listitem> + <listitem> + <code>UTC</code>. + </listitem> + </itemizedlist> + + <para> + For AIX, the value of <code>TZ</code> environment value is used, with + fallback to <code>UTC</code>. + </para> + + <para> + On Windows <code>TimeZoneKeyName</code> is mapped to the IANA zone, using + internal mapping hard-coded in library, with fallback to <code>UTC</code>: + </para> + <itemizedlist> + <listitem> + If the returned <code>TimeZoneKeyName</code> is empty or DST is disabled, + then a value based on <code>Bias</code> is returned: <code>Etc/UTC</code> + for zero, <code>Etc/GMT+/-N</code> for value that is multiply of 60, + and empty string otherwise. + </listitem> + <listitem> + If the mapping contains a single entry for <code>TimeZoneKeyName</code>, + that name is used. + </listitem> + <listitem> + If <code>TimeZoneKeyName</code> corresponds to multiple IANA zones, + a 2-letter country code is used, retrieved by applying <code>GetGeoInfoW</code> + on the result of <code>GetUserGeoID(GEOCLASS_NATION)</code>. + If determining the country code fails, or no entry exits for a given code, + the first mapping entry (<code>001</code>) is returned. + </listitem> + </itemizedlist> + </section> + + <section xml:id="zone.db.sources" xreflabel="data sources"><info><title>data sources</title></info> + <para> + Depending on the build configuration (see + <code>--with-libstdcxx-zoneinfo=</code> documentation in + <xref linkend="manual.intro.setup.configure">Configure section</xref>). + the content of the time zone database is sourced from + <filename>tzdata.zi</filename> and <filename>leapseconds</filename> files + located in <emphasis>zoneinfo_dir</emphasis>, or from static information + embedded in the library. + </para> + + <para> + By default, <emphasis>zoneinfo_dir</emphasis> is set to the + system-specific default directory (if a suitable dir is known for target), + usually <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. + </para> + + <para> + In addition to <code>--with-libstdcxx-zoneinfo=</code> configure option + (used during GCC build), the path of <emphasis>zoneinfo_dir</emphasis> + can be overridden by the application by providing a definition of the + <code>__gnu_cxx::zoneinfo_dir_overrride()</code> function. The + returned path should be directory that contains <code>tzdata.zi</code> + and <code>leapseconds</code> files in the + <link xmlns:xlink="http://www.w3.org/1999/xlink" + xlink:href="https://man7.org/linux/man-pages/man8/zic.8.html#FILES"> + <code>zic</code> format</link>. + </para> + + <para> + 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>std::chrono::get_tzdb().version</code>. + </para> + + <para> + 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>chrono::get_tzdb().version</code> + being set to <code>"ersatz"</code>. This database contains leapseconds + data, <code>Etc/UTC</code>, <code>Etc/GMT</code> zones, and their aliases + (<code>Etc/Zulu</code>, <code>Etc/UCT</code>, <code>Etc/Universal</code>, + <code>Etc/Greenwich</code>, <code>Etc/GMT0</code>, <code>Etc/GMT+0</code>, + <code>Etc/GMT-0</code>). This information is sufficient to support + conversion between <code>utc_clock</code> and <code>sys_clock</code>, + as well as a <code>UTC</code> fallback for <code>current_zone</code> + (<xref linkend="zone.current">link</xref>). + </para> + </section> + + <section xml:id="zone.db.iterator" xreflabel="tzdb_list::const_iterator extends lifetime"> + <info><title>tzdb_list::const_iterator extends lifetime</title></info> + + <para> + The <code>std::chrono::reload_tzdb()</code> function may be used to load + updated content of the <code>tzdata.zi</code> and <code>leapseconds</code> + files from <emphasis>zoneinfo_dir</emphasis> (if + <xref linkend="zone.db.sources">enabled</xref>). If the version is different + (<code>std::chrono::remote_version() != std::chrono::get_tzdb().version</code>), + a new element is added at the front of the <code>tzdb_list</code>. + This new database is used for subsequent calls to <code>current_zone</code> + and <code>locate_zone</code>. + </para> + + <para> + The above process is thread-safe, and does not invalidate nor change any + pre-existing pointers to <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 + <xref linkend="zone.db.zic">link</xref>). + </para> + + <para> + If accumulating old <code>tzdb</code> databases is not acceptable + (e.g. due to memory constraints), entries + may be removed from <code>tzdb_list</code> using <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>time_zone*</code> to a removed database. + If you erase a <code>tzdb</code> while some part of the application is still + using it (or one of its <code>time_zone</code> objects) you will create + a dangling pointer, leading to undefined behaviour. + To make <code>tzdb_list::erase_after</code> safer, libstdc++ provides an + <emphasis>extension</emphasis> that avoids creating dangling pointers. + The <code>tzdb_list</code> uses <code>shared_ptr<tzdb></code> to + refer to each entry in the list, and <code>tzdb_list::const_iterator</code> + also uses a <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>tzdb</code> and <code>time_zone</code> + objects are not destroyed while they're still being used. The lifetime + of a <code>tzdb</code> that is still in use can be extended by holding + onto a <code>tzdb_list::const_iterator</code> that refers to it. + </para> + </section> + +</section> + +</chapter> -- 2.55.0