Skip to content

Commit 4b696a9

Browse files
committed
[libc++][chrono] Loads tzdata.zi in tzdb.
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
1 parent a176710 commit 4b696a9

File tree

32 files changed

+2148
-14
lines changed

32 files changed

+2148
-14
lines changed

libcxx/docs/Status/Cxx20Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
"`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","|Complete|","16.0"
181181
"`P1976R2 <https://wg21.link/P1976R2>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0","|ranges|"
182182
"`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","* *",""
183-
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","* *",""
183+
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","|Complete|","18.0","|chrono|"
184184
"`P1983R0 <https://wg21.link/P1983R0>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","|Complete|","15.0","|ranges|"
185185
"`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","|Complete|","16.0","|ranges|"
186186
"`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""

libcxx/docs/Status/SpaceshipProjects.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ Section,Description,Dependencies,Assignee,Complete
171171
| `month_weekday_last <https://reviews.llvm.org/D152699>`_
172172
| `year_month_weekday <https://reviews.llvm.org/D152699>`_
173173
| `year_month_weekday_last <https://reviews.llvm.org/D152699>`_",None,Hristo Hristov,|Complete|
174-
`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
174+
`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
175175
`[time.zone.zonedtime.nonmembers] <https://wg21.link/time.zone.zonedtime.nonmembers>`_,"`chrono::zoned_time`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
176176
`[time.zone.leap.nonmembers] <https://wg21.link/time.zone.leap.nonmembers>`_,"`chrono::time_leap_seconds`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
177-
`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
177+
`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
178178
- `5.13 Clause 28: Localization library <https://wg21.link/p1614r2#clause-28-localization-library>`_,,,,
179179
"| `[locale] <https://wg21.link/locale>`_
180180
| `[locale.operators] <https://wg21.link/locale.operators>`_",| remove ops `locale <https://reviews.llvm.org/D152654>`_,None,Hristo Hristov,|Complete|

libcxx/include/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ set(files
287287
__chrono/steady_clock.h
288288
__chrono/system_clock.h
289289
__chrono/time_point.h
290+
__chrono/time_zone.h
291+
__chrono/time_zone_link.h
292+
__chrono/time_zone_types.h
290293
__chrono/tzdb.h
291294
__chrono/tzdb_list.h
292295
__chrono/weekday.h

libcxx/include/__chrono/time_zone.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11+
12+
#ifndef _LIBCPP___CHRONO_TIME_ZONE_H
13+
#define _LIBCPP___CHRONO_TIME_ZONE_H
14+
15+
#include <version>
16+
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17+
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
18+
19+
# include <__chrono/time_zone_types.h>
20+
# include <__compare/strong_order.h>
21+
# include <__config>
22+
# include <string>
23+
# include <string_view>
24+
# include <vector>
25+
26+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27+
# pragma GCC system_header
28+
# endif
29+
30+
_LIBCPP_BEGIN_NAMESPACE_STD
31+
32+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
33+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
34+
35+
namespace chrono {
36+
37+
class _LIBCPP_AVAILABILITY_TZDB time_zone {
38+
public:
39+
explicit _LIBCPP_HIDE_FROM_ABI time_zone(string&& __name) : __name_(std::move(__name)) {}
40+
41+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; }
42+
43+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI vector<__tz::__continuation>& __continuations() { return __continuations_; }
44+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const vector<__tz::__continuation>& __continuations() const {
45+
return __continuations_;
46+
}
47+
48+
private:
49+
string __name_;
50+
// Note the first line has a name + __continuation, the other lines
51+
// are just __continuations. So there is always at least one item in
52+
// the vector.
53+
vector<__tz::__continuation> __continuations_;
54+
};
55+
56+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
57+
operator==(const time_zone& __x, const time_zone& __y) noexcept {
58+
return __x.name() == __y.name();
59+
}
60+
61+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
62+
operator<=>(const time_zone& __x, const time_zone& __y) noexcept {
63+
return __x.name() <=> __y.name();
64+
}
65+
66+
} // namespace chrono
67+
68+
# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
69+
// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
70+
71+
_LIBCPP_END_NAMESPACE_STD
72+
73+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
74+
75+
#endif // _LIBCPP___CHRONO_TIME_ZONE_H
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11+
12+
#ifndef _LIBCPP___CHRONO_TIME_ZONE_LINK_H
13+
#define _LIBCPP___CHRONO_TIME_ZONE_LINK_H
14+
15+
#include <version>
16+
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17+
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
18+
19+
# include <__compare/strong_order.h>
20+
# include <__config>
21+
# include <string>
22+
# include <string_view>
23+
24+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25+
# pragma GCC system_header
26+
# endif
27+
28+
_LIBCPP_BEGIN_NAMESPACE_STD
29+
30+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
31+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
32+
33+
namespace chrono {
34+
35+
class _LIBCPP_AVAILABILITY_TZDB time_zone_link {
36+
public:
37+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit time_zone_link(string_view __name, string_view __target)
38+
: __name_{__name}, __target_{__target} {}
39+
40+
_LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default;
41+
_LIBCPP_HIDE_FROM_ABI time_zone_link& operator=(time_zone_link&&) = default;
42+
43+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; }
44+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; }
45+
46+
private:
47+
string __name_;
48+
// TODO TZDB instead of the name we can store the pointer to a zone. These
49+
// pointers are immutable. This makes it possible to directly return a
50+
// pointer in the time_zone in the 'locate_zone' function.
51+
string __target_;
52+
};
53+
54+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
55+
operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept {
56+
return __x.name() == __y.name();
57+
}
58+
59+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
60+
operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept {
61+
return __x.name() <=> __y.name();
62+
}
63+
64+
} // namespace chrono
65+
66+
# endif //_LIBCPP_STD_VER >= 20
67+
68+
_LIBCPP_END_NAMESPACE_STD
69+
70+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
71+
72+
#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11+
12+
#ifndef _LIBCPP___CHRONO_TIME_ZONE_TYPES_H
13+
#define _LIBCPP___CHRONO_TIME_ZONE_TYPES_H
14+
15+
#include <version>
16+
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17+
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
18+
19+
# include <__chrono/day.h>
20+
# include <__chrono/duration.h>
21+
# include <__chrono/month.h>
22+
# include <__chrono/weekday.h>
23+
# include <__chrono/year.h>
24+
# include <__config>
25+
# include <string>
26+
# include <variant>
27+
28+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29+
# pragma GCC system_header
30+
# endif
31+
32+
_LIBCPP_BEGIN_NAMESPACE_STD
33+
34+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
35+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
36+
37+
namespace chrono::__tz {
38+
39+
// Sun>=8 first Sunday on or after the eighth
40+
// Sun<=25 last Sunday on or before the 25th
41+
struct _LIBCPP_AVAILABILITY_TZDB __constrained_weekday {
42+
/* year_month_day operator()(year __year, month __month);*/ // needed but not implemented
43+
44+
weekday __weekday;
45+
enum __comparison_t { __le, __ge } __comparison;
46+
day __day;
47+
};
48+
49+
// The on field has a few alternative presentations
50+
// 5 the fifth of the month
51+
// lastSun the last Sunday in the month
52+
// lastMon the last Monday in the month
53+
// Sun>=8 first Sunday on or after the eighth
54+
// Sun<=25 last Sunday on or before the 25th
55+
using __on = variant<day, weekday_last, __constrained_weekday>;
56+
57+
enum class _LIBCPP_AVAILABILITY_TZDB __clock { __local, __standard, __universal };
58+
59+
struct _LIBCPP_AVAILABILITY_TZDB __at {
60+
seconds __time{0};
61+
__tz::__clock __clock{__tz::__clock::__local};
62+
};
63+
64+
struct _LIBCPP_AVAILABILITY_TZDB __save {
65+
seconds __time;
66+
bool __is_dst;
67+
};
68+
69+
// The names of the fields match the fields of a Rule.
70+
struct _LIBCPP_AVAILABILITY_TZDB __rule {
71+
year __from;
72+
year __to;
73+
month __in_month; // __in is a reserved name
74+
__tz::__on __on;
75+
__tz::__at __at;
76+
__tz::__save __save;
77+
string __letters;
78+
};
79+
80+
struct _LIBCPP_AVAILABILITY_TZDB __continuation {
81+
seconds __stdoff;
82+
83+
// The RULES is either a SAVE or a NAME.
84+
// The size_t is used as cache. After loading the rules they are
85+
// sorted and remain stable, then an index in the vector can be
86+
// used.
87+
// If this field contains - then standard time always
88+
// applies. This is indicated by the monostate.
89+
using __rules_t = variant<monostate, __tz::__save, string, size_t>;
90+
91+
__rules_t __rules;
92+
93+
string __format;
94+
// TODO TZDB until can be contain more than just a year.
95+
// Parts of the UNTIL, the optional parts are default initialized
96+
// optional<year> __until_;
97+
year __year = chrono::year::min();
98+
month __in_month{January}; // __in is a reserved name
99+
__tz::__on __on{chrono::day{1}};
100+
__tz::__at __at{chrono::seconds{0}, __tz::__clock::__local};
101+
};
102+
103+
} // namespace chrono::__tz
104+
105+
# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
106+
// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
107+
108+
_LIBCPP_END_NAMESPACE_STD
109+
110+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
111+
112+
#endif // _LIBCPP___CHRONO_TIME_ZONE_TYPES_H

libcxx/include/__chrono/tzdb.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@
1616
// Enable the contents of the header only when libc++ was built with experimental features enabled.
1717
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
1818

19+
# include <__availability>
20+
# include <__chrono/time_zone.h>
21+
# include <__chrono/time_zone_link.h>
22+
# include <__chrono/time_zone_types.h>
23+
# include <__config>
1924
# include <string>
25+
# include <vector>
2026

2127
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2228
# pragma GCC system_header
@@ -31,6 +37,9 @@ namespace chrono {
3137

3238
struct _LIBCPP_AVAILABILITY_TZDB tzdb {
3339
string version;
40+
vector<pair<string, vector<__tz::__rule>>> __rules;
41+
vector<time_zone> zones;
42+
vector<time_zone_link> links;
3443
};
3544

3645
} // namespace chrono

libcxx/include/chrono

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,8 @@ constexpr hours make24(const hours& h, bool is_pm) noexcept;
682682
// [time.zone.db], time zone database
683683
struct tzdb { // C++20
684684
string version;
685+
vector<time_zone> zones;
686+
vector<time_zone_link> links;
685687
};
686688
687689
class tzdb_list { // C++20
@@ -712,15 +714,34 @@ tzdb_list& get_tzdb_list();
712714
const tzdb& reload_tzdb(); // C++20
713715
string remote_version(); // C++20
714716
715-
// 25.10.5, class time_zone // C++20
717+
// 25.10.5, class time_zone // C++20
716718
enum class choose {earliest, latest};
717-
class time_zone;
718-
bool operator==(const time_zone& x, const time_zone& y) noexcept;
719-
bool operator!=(const time_zone& x, const time_zone& y) noexcept;
720-
bool operator<(const time_zone& x, const time_zone& y) noexcept;
721-
bool operator>(const time_zone& x, const time_zone& y) noexcept;
722-
bool operator<=(const time_zone& x, const time_zone& y) noexcept;
723-
bool operator>=(const time_zone& x, const time_zone& y) noexcept;
719+
class time_zone {
720+
time_zone(time_zone&&) = default;
721+
time_zone& operator=(time_zone&&) = default;
722+
723+
// unspecified additional constructors
724+
725+
string_view name() const noexcept;
726+
};
727+
bool operator==(const time_zone& x, const time_zone& y) noexcept; // C++20
728+
strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept; // C++20
729+
730+
// [time.zone.link], class time_zone_link
731+
class time_zone_link { // C++20
732+
public:
733+
time_zone_link(time_zone_link&&) = default;
734+
time_zone_link& operator=(time_zone_link&&) = default;
735+
736+
// unspecified additional constructors
737+
738+
string_view name() const noexcept;
739+
string_view target() const noexcept;
740+
};
741+
742+
bool operator==(const time_zone_link& x, const time_zone_link& y); // C++20
743+
strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y); // C++20
744+
724745
} // chrono
725746
726747
namespace std {
@@ -838,6 +859,9 @@ constexpr chrono::year operator ""y(unsigned lo
838859

839860
#if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
840861
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
862+
# include <__chrono/time_zone.h>
863+
# include <__chrono/time_zone_link.h>
864+
# include <__chrono/time_zone_types.h>
841865
# include <__chrono/tzdb.h>
842866
# include <__chrono/tzdb_list.h>
843867
#endif

libcxx/include/module.modulemap.in

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,18 @@ module std_private_chrono_steady_clock [system] {
11631163
header "__chrono/steady_clock.h"
11641164
export std_private_chrono_time_point
11651165
}
1166+
module std_private_chrono_time_zone [system] {
1167+
header "__chrono/time_zone.h"
1168+
export *
1169+
}
1170+
module std_private_chrono_time_zone_link [system] {
1171+
header "__chrono/time_zone_link.h"
1172+
export *
1173+
}
1174+
module std_private_chrono_time_zone_types [system] {
1175+
header "__chrono/time_zone_types.h"
1176+
export *
1177+
}
11661178
module std_private_chrono_system_clock [system] {
11671179
header "__chrono/system_clock.h"
11681180
export std_private_chrono_time_point

0 commit comments

Comments
 (0)