[libcxx-commits] [libcxx] [libc++][chrono] Adds the sys_info class. (PR #85619)
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Apr 7 02:52:06 PDT 2024
================
@@ -27,6 +722,169 @@ _LIBCPP_EXPORTED_FROM_ABI time_zone::~time_zone() = default;
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view time_zone::__name() const noexcept { return __impl_->__name(); }
+[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info
+time_zone::__get_info(sys_seconds __time) const {
+ optional<sys_info> __result;
+ bool __valid_result = false; // true iff __result.has_value() is true and
+ // result.begin <= __time < __result.end is true.
+ bool __can_merge = false;
+ sys_seconds __continuation_begin = sys_seconds::min();
+ // Iterates over the Zone entry and its continuations. Internally the Zone
+ // entry is split in a Zone information and the first continuation. The last
+ // continuation has no UNTIL field. This means the loop should always find a
+ // continuation.
+ //
+ // For more information on background of zone information please consult the
+ // following information
+ // [zic manual](https://www.man7.org/linux/man-pages/man8/zic.8.html)
+ // [tz source info](https://data.iana.org/time-zones/tz-how-to.html)
+ // On POSIX systems the zdump tool can be useful:
+ // zdump -v Asia/Hong_Kong
+ // Gives all transitions in the Hong Kong time zone.
+ //
+ // During iteration the result for the current continuation is returned. If
+ // no continuation is applicable it will return the end time as "error". When
+ // two continuations are contiguous and contain the "same" information these
+ // ranges are merged as one range.
+ // The merging requires to keep results occur before __time, likewise when a
+ // valid result is found the algorithm needs test the next continuation to see
+ // when it can be merged. For example, Africa/Ceuta
+ // Continuations
+ // 0 s WE%sT 1929 (C1)
+ // 0 - WET 1967 (C2)
+ // 0 Sp WE%sT 1984 Mar 16 (C3)
+ //
+ // Rules
+ // R s 1926 1929 - O Sa>=1 24s 0 - (R1)
+ //
+ // R Sp 1967 o - Jun 3 12 1 S (R2)
+ //
+ // The rule R1 is the last rule used in C1. The rule R2 is the first rule in
+ // C3. Since R2 is the first rule this means when a continuation uses this
+ // rule its value prior to R2 will be SAVE 0 LETTERS of the first entry with a
+ // SAVE of 0, in this case WET.
+ // This gives the following changes in the information.
+ // 1928-10-07 00:00:00 C1 R1 becomes active: offset 0 save 0 abbrev WET
+ // 1929-01-01 00:00:00 C2 becomes active: offset 0 save 0 abbrev WET
+ // 1967-01-01 00:00:00 C3 becomes active: offset 0 save 0 abbrev WET
+ // 1967-06-03 12:00:00 C3 R2 becomes active: offset 0 save 1 abbrev WEST
+ //
+ // The first 3 entries are contiguous and contain the same information, this
+ // means the period [1928-10-07 00:00:00, 1967-06-03 12:00:00) should be
+ // returned in one sys_info object.
+
+ const auto& __continuations = __impl_->__continuations();
+ for (auto __it = __continuations.begin(); __it != __continuations.end(); ++__it) {
+ const auto& __continuation = *__it;
+ __sys_info_result __sys_info = chrono::__get_sys_info(__time, __continuation_begin, __continuation);
----------------
mordante wrote:
This is quite hard to do and actually not needed. The `time_zone` keeps track of its continuations. This class is not really aware of the `tzdb` entry it originates from. This origin information is only needed to extract to rules, which would be a cumbersome to do. (It involves iterating the members under a reader lock to find the offset the `tzdb` in the `tzdb_list`, then return the rules at the same offset in its list.) Instead I changed to code directly keep track of the rules; this is trivial to do. I added a test for this.
https://github.com/llvm/llvm-project/pull/85619
More information about the libcxx-commits
mailing list