diff options
author | Mark de Wever <koraq@xs4all.nl> | 2024-02-17 14:28:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-17 14:28:01 +0100 |
commit | d332d88b919faa15564ab70b0633d94f21bc3e3c (patch) | |
tree | 3108d99ec93b8678cf22b84c05f2cdfdcdbcbed5 /libcxx/src/tz.cpp | |
parent | ded3ca224f7c2b1df769d625985ab20bb60dfba4 (diff) | |
download | llvm-d332d88b919faa15564ab70b0633d94f21bc3e3c.zip llvm-d332d88b919faa15564ab70b0633d94f21bc3e3c.tar.gz llvm-d332d88b919faa15564ab70b0633d94f21bc3e3c.tar.bz2 |
[libc++][chrono] Loads tzdata.zi in tzdb. (#74928)
This implements the loading of the tzdata.zi file and store its contents
in the tzdb struct.
This adds all required members except:
- the leap seconds,
- the locate_zone, and
- current_zone.
The class time_zone is incomplete and only contains the parts needed for
storing the parsed data.
The class time_zone_link is fully implemented including its non-member
functions.
Implements parts of:
- P0355 Extending <chrono> to Calendars and Time Zones
- P1614 The Mothership has Landed
Implements:
- P1982 Rename link to time_zone_link
Diffstat (limited to 'libcxx/src/tz.cpp')
-rw-r--r-- | libcxx/src/tz.cpp | 146 |
1 files changed, 0 insertions, 146 deletions
diff --git a/libcxx/src/tz.cpp b/libcxx/src/tz.cpp deleted file mode 100644 index 4425f0e..0000000 --- a/libcxx/src/tz.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html - -#include <chrono> -#include <filesystem> -#include <fstream> -#include <stdexcept> -#include <string> - -// Contains a parser for the IANA time zone data files. -// -// These files can be found at https://data.iana.org/time-zones/ and are in the -// public domain. Information regarding the input can be found at -// https://data.iana.org/time-zones/tz-how-to.html and -// https://man7.org/linux/man-pages/man8/zic.8.html. -// -// As indicated at https://howardhinnant.github.io/date/tz.html#Installation -// For Windows another file seems to be required -// https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml -// This file seems to contain the mapping of Windows time zone name to IANA -// time zone names. -// -// However this article mentions another way to do the mapping on Windows -// https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255 -// This requires Windows 10 Version 1903, which was released in May of 2019 -// and considered end of life in December 2020 -// https://learn.microsoft.com/en-us/lifecycle/announcements/windows-10-1903-end-of-servicing -// -// TODO TZDB Implement the Windows mapping in tzdb::current_zone - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace chrono { - -// This function is weak so it can be overriden in the tests. The -// declaration is in the test header test/support/test_tzdb.h -_LIBCPP_WEAK string_view __libcpp_tzdb_directory() { -#if defined(__linux__) - return "/usr/share/zoneinfo/"; -#else -# error "unknown path to the IANA Time Zone Database" -#endif -} - -[[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; } - -static void __skip_optional_whitespace(istream& __input) { - while (chrono::__is_whitespace(__input.peek())) - __input.get(); -} - -static void __skip_mandatory_whitespace(istream& __input) { - if (!chrono::__is_whitespace(__input.get())) - std::__throw_runtime_error("corrupt tzdb: expected whitespace"); - - chrono::__skip_optional_whitespace(__input); -} - -static void __matches(istream& __input, char __expected) { - if (std::tolower(__input.get()) != __expected) - std::__throw_runtime_error((string("corrupt tzdb: expected character '") + __expected + '\'').c_str()); -} - -static void __matches(istream& __input, string_view __expected) { - for (auto __c : __expected) - if (std::tolower(__input.get()) != __c) - std::__throw_runtime_error((string("corrupt tzdb: expected string '") + string(__expected) + '\'').c_str()); -} - -[[nodiscard]] static string __parse_string(istream& __input) { - string __result; - while (true) { - int __c = __input.get(); - switch (__c) { - case ' ': - case '\t': - case '\n': - __input.unget(); - [[fallthrough]]; - case istream::traits_type::eof(): - if (__result.empty()) - std::__throw_runtime_error("corrupt tzdb: expected a string"); - - return __result; - - default: - __result.push_back(__c); - } - } -} - -static string __parse_version(istream& __input) { - // The first line in tzdata.zi contains - // # version YYYYw - // The parser expects this pattern - // #\s*version\s*\(.*) - // This part is not documented. - chrono::__matches(__input, '#'); - chrono::__skip_optional_whitespace(__input); - chrono::__matches(__input, "version"); - chrono::__skip_mandatory_whitespace(__input); - return chrono::__parse_string(__input); -} - -static tzdb __make_tzdb() { - tzdb __result; - - filesystem::path __root = chrono::__libcpp_tzdb_directory(); - ifstream __tzdata{__root / "tzdata.zi"}; - - __result.version = chrono::__parse_version(__tzdata); - return __result; -} - -//===----------------------------------------------------------------------===// -// Public API -//===----------------------------------------------------------------------===// - -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list() { - static tzdb_list __result{chrono::__make_tzdb()}; - return __result; -} - -_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb() { - if (chrono::remote_version() == chrono::get_tzdb().version) - return chrono::get_tzdb(); - - return chrono::get_tzdb_list().__emplace_front(chrono::__make_tzdb()); -} - -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version() { - filesystem::path __root = chrono::__libcpp_tzdb_directory(); - ifstream __tzdata{__root / "tzdata.zi"}; - return chrono::__parse_version(__tzdata); -} - -} // namespace chrono - -_LIBCPP_END_NAMESPACE_STD |