@@ -88,7 +88,6 @@ mod offset;
88
88
pub mod windows;
89
89
90
90
#[ doc( inline) ]
91
- pub use crate :: provider:: { TimeZone , TimeZoneVariant } ;
92
91
pub use offset:: InvalidOffsetError ;
93
92
pub use offset:: UtcOffset ;
94
93
pub use offset:: VariantOffsets ;
@@ -102,7 +101,12 @@ pub use windows::WindowsParser;
102
101
103
102
use crate :: { scaffold:: IntoOption , Time } ;
104
103
use core:: fmt;
104
+ use core:: ops:: Deref ;
105
105
use icu_calendar:: { Date , Iso } ;
106
+ use icu_provider:: prelude:: yoke;
107
+ use tinystr:: TinyAsciiStr ;
108
+ use zerovec:: ule:: { AsULE , ULE } ;
109
+ use zerovec:: { ZeroSlice , ZeroVec } ;
106
110
107
111
/// Time zone data model choices.
108
112
pub mod models {
@@ -158,7 +162,120 @@ pub mod models {
158
162
}
159
163
}
160
164
165
+ /// A CLDR time zone identity.
166
+ ///
167
+ /// **The primary definition of this type is in the [`icu_time`](docs.rs/icu_time) crate. Other ICU4X crates re-export it for convenience.**
168
+ ///
169
+ /// This can be created directly from BCP-47 strings, or it can be parsed from IANA IDs.
170
+ ///
171
+ /// CLDR uses difference equivalence classes than IANA. For example, `Europe/Oslo` is
172
+ /// an alias to `Europe/Berlin` in IANA (because they agree since 1970), but these are
173
+ /// different identities in CLDR, as we want to be able to say "Norway Time" and
174
+ /// "Germany Time". On the other hand `Europe/Belfast` and `Europe/London` are the same
175
+ /// CLDR identity ("UK Time").
176
+ ///
177
+ /// ```
178
+ /// use icu::time::zone::{IanaParser, TimeZone};
179
+ /// use tinystr::tinystr;
180
+ ///
181
+ /// let parser = IanaParser::new();
182
+ /// assert_eq!(parser.parse("Europe/Oslo"), TimeZone(tinystr!(8, "noosl")));
183
+ /// assert_eq!(
184
+ /// parser.parse("Europe/Berlin"),
185
+ /// TimeZone(tinystr!(8, "deber"))
186
+ /// );
187
+ /// assert_eq!(
188
+ /// parser.parse("Europe/Belfast"),
189
+ /// TimeZone(tinystr!(8, "gblon"))
190
+ /// );
191
+ /// assert_eq!(
192
+ /// parser.parse("Europe/London"),
193
+ /// TimeZone(tinystr!(8, "gblon"))
194
+ /// );
195
+ /// ```
196
+ #[ repr( transparent) ]
197
+ #[ derive( Debug , Clone , Copy , Eq , Ord , PartialEq , PartialOrd , yoke:: Yokeable , ULE , Hash ) ]
198
+ #[ cfg_attr( feature = "datagen" , derive( serde:: Serialize , databake:: Bake ) ) ]
199
+ #[ cfg_attr( feature = "datagen" , databake( path = icu_time) ) ]
200
+ #[ cfg_attr( feature = "serde" , derive( serde:: Deserialize ) ) ]
201
+ #[ allow( clippy:: exhaustive_structs) ] // This is a stable newtype
202
+ pub struct TimeZone ( pub TinyAsciiStr < 8 > ) ;
203
+
204
+ impl TimeZone {
205
+ /// The synthetic `Etc/Unknown` time zone.
206
+ ///
207
+ /// This is the result of parsing unknown zones. It's important that such parsing does not
208
+ /// fail, as new zones are added all the time, and ICU4X might not be up to date.
209
+ pub const fn unknown ( ) -> Self {
210
+ Self ( tinystr:: tinystr!( 8 , "unk" ) )
211
+ }
212
+ }
213
+
214
+ /// This module exists so we can cleanly reexport TimeZoneVariantULE from the provider module, whilst retaining a public stable TimeZoneVariant type.
215
+ pub ( crate ) mod ule {
216
+ /// A time zone variant, such as Standard Time, or Daylight/Summer Time.
217
+ ///
218
+ /// This should not generally be constructed by client code. Instead, use
219
+ /// * [`TimeZoneVariant::from_rearguard_isdst`]
220
+ /// * [`TimeZoneInfo::infer_zone_variant`](crate::TimeZoneInfo::infer_zone_variant)
221
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
222
+ #[ zerovec:: make_ule( TimeZoneVariantULE ) ]
223
+ #[ repr( u8 ) ]
224
+ #[ cfg_attr( feature = "datagen" , derive( serde:: Serialize , databake:: Bake ) ) ]
225
+ #[ cfg_attr( feature = "datagen" , databake( path = icu_time) ) ]
226
+ #[ cfg_attr( feature = "serde" , derive( serde:: Deserialize ) ) ]
227
+ #[ non_exhaustive]
228
+ pub enum TimeZoneVariant {
229
+ /// The variant corresponding to `"standard"` in CLDR.
230
+ ///
231
+ /// The semantics vary from time zone to time zone. The time zone display
232
+ /// name of this variant may or may not be called "Standard Time".
233
+ ///
234
+ /// This is the variant with the lower UTC offset.
235
+ Standard = 0 ,
236
+ /// The variant corresponding to `"daylight"` in CLDR.
237
+ ///
238
+ /// The semantics vary from time zone to time zone. The time zone display
239
+ /// name of this variant may or may not be called "Daylight Time".
240
+ ///
241
+ /// This is the variant with the higher UTC offset.
242
+ Daylight = 1 ,
243
+ }
244
+ }
245
+ pub use ule:: TimeZoneVariant ;
246
+
247
+ impl Deref for TimeZone {
248
+ type Target = TinyAsciiStr < 8 > ;
249
+
250
+ fn deref ( & self ) -> & Self :: Target {
251
+ & self . 0
252
+ }
253
+ }
254
+
255
+ impl AsULE for TimeZone {
256
+ type ULE = Self ;
257
+
258
+ #[ inline]
259
+ fn to_unaligned ( self ) -> Self :: ULE {
260
+ self
261
+ }
262
+
263
+ #[ inline]
264
+ fn from_unaligned ( unaligned : Self :: ULE ) -> Self {
265
+ unaligned
266
+ }
267
+ }
268
+
269
+ impl < ' a > zerovec:: maps:: ZeroMapKV < ' a > for TimeZone {
270
+ type Container = ZeroVec < ' a , TimeZone > ;
271
+ type Slice = ZeroSlice < TimeZone > ;
272
+ type GetType = TimeZone ;
273
+ type OwnedType = TimeZone ;
274
+ }
275
+
161
276
/// A utility type that can hold time zone information.
277
+ ///
278
+ /// **The primary definition of this type is in the [`icu_time`](docs.rs/icu_time) crate. Other ICU4X crates re-export it for convenience.**
162
279
#[ derive( Debug , PartialEq , Eq ) ]
163
280
#[ allow( clippy:: exhaustive_structs) ] // these four fields fully cover the needs of UTS 35
164
281
pub struct TimeZoneInfo < Model : models:: TimeZoneModel > {
0 commit comments