@@ -11,17 +11,29 @@ use crate::{
1111 epoch_nanoseconds:: { seconds_to_nanoseconds, EpochNanoseconds , NS_IN_S } ,
1212 TimeZoneProviderError ,
1313} ;
14- use icu_time :: zone :: UtcOffset ;
14+ use zoneinfo64 :: UtcOffset ;
1515
1616impl From < UtcOffset > for UtcOffsetSeconds {
1717 fn from ( other : UtcOffset ) -> Self {
18- Self ( i64:: from ( other. to_seconds ( ) ) )
18+ Self ( i64:: from ( other. seconds ( ) ) )
1919 }
2020}
2121
22+ pub use zoneinfo64:: ZONEINFO64_RES_FOR_TESTING ;
23+
2224/// A TimeZoneProvider that works using ICU4C zoneinfo64.res data
2325pub type ZoneInfo64TzdbProvider < ' a > = NormalizerAndResolver < CompiledNormalizer , ZoneInfo64 < ' a > > ;
2426
27+ impl ZoneInfo64TzdbProvider < ' _ > {
28+ /// Produces a zoneinfo64 provider using the builtin zoneinfo64 data,
29+ /// for testing use only. We do not provide strong guarantees for which version of zoneinfo64
30+ /// this will be.
31+ pub fn zoneinfo64_provider_for_testing ( ) -> Option < Self > {
32+ let zi_data = zoneinfo64:: ZoneInfo64 :: try_from_u32s ( ZONEINFO64_RES_FOR_TESTING ) . ok ( ) ?;
33+ Some ( ZoneInfo64TzdbProvider :: new ( zi_data) )
34+ }
35+ }
36+
2537fn get < ' a > ( zi : & ' a ZoneInfo64 < ' a > , id : ResolvedId ) -> TimeZoneProviderResult < Zone < ' a > > {
2638 let id = u16:: try_from ( id. 0 )
2739 . map_err ( |_| TimeZoneProviderError :: Range ( "Unknown timezone identifier" ) ) ?;
@@ -55,53 +67,40 @@ impl TimeZoneResolver for ZoneInfo64<'_> {
5567 local_datetime. second ,
5668 ) ;
5769
58- const FIVE_DAYS_NANOS : i128 = 5 * 24 * 60 * 60 * 1_000_000_000 ;
5970 let result = match possible_offset {
60- // TODO(Manishearth) This is wrong. It mostly works: we do not have any transitions with gaps that last
61- // longer than 5 days, and for the purpose of calculating an offset when you are that far away from a transition
62- // treating local datetime as epoch time works fine.
63- // Can be fixed once we have https://github.com/unicode-org/icu4x/pull/6913
64- PossibleOffset :: None => CandidateEpochNanoseconds :: Zero ( GapEntryOffsets {
65- offset_before : self . transition_nanoseconds_for_utc_epoch_nanoseconds (
66- identifier,
67- epoch_nanos. 0 - FIVE_DAYS_NANOS ,
68- ) ?,
69- offset_after : self . transition_nanoseconds_for_utc_epoch_nanoseconds (
70- identifier,
71- epoch_nanos. 0 + FIVE_DAYS_NANOS ,
72- ) ?,
73- transition_epoch : self
74- . get_time_zone_transition (
75- identifier,
76- epoch_nanos. 0 - FIVE_DAYS_NANOS ,
77- TransitionDirection :: Next ,
78- ) ?
79- . unwrap_or_default ( ) ,
71+ PossibleOffset :: None {
72+ before,
73+ after,
74+ transition,
75+ } => CandidateEpochNanoseconds :: Zero ( GapEntryOffsets {
76+ offset_before : before. offset . into ( ) ,
77+ offset_after : after. offset . into ( ) ,
78+ transition_epoch : EpochNanoseconds :: from ( seconds_to_nanoseconds ( transition) ) ,
8079 } ) ,
8180 PossibleOffset :: Single ( o) => {
8281 let epoch_ns = EpochNanoseconds :: from (
83- epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( o. offset . to_seconds ( ) ) ) ,
82+ epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( o. offset . seconds ( ) ) ) ,
8483 ) ;
8584 CandidateEpochNanoseconds :: One ( EpochNanosecondsAndOffset {
8685 ns : epoch_ns,
8786 offset : o. offset . into ( ) ,
8887 } )
8988 }
90- PossibleOffset :: Ambiguous ( first , second ) => {
89+ PossibleOffset :: Ambiguous { before , after , .. } => {
9190 let first_epoch_ns = EpochNanoseconds :: from (
92- epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( first . offset . to_seconds ( ) ) ) ,
91+ epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( before . offset . seconds ( ) ) ) ,
9392 ) ;
9493 let second_epoch_ns = EpochNanoseconds :: from (
95- epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( second . offset . to_seconds ( ) ) ) ,
94+ epoch_nanos. 0 - seconds_to_nanoseconds ( i64:: from ( after . offset . seconds ( ) ) ) ,
9695 ) ;
9796 CandidateEpochNanoseconds :: Two ( [
9897 EpochNanosecondsAndOffset {
9998 ns : first_epoch_ns,
100- offset : first . offset . into ( ) ,
99+ offset : before . offset . into ( ) ,
101100 } ,
102101 EpochNanosecondsAndOffset {
103102 ns : second_epoch_ns,
104- offset : second . offset . into ( ) ,
103+ offset : after . offset . into ( ) ,
105104 } ,
106105 ] )
107106 }
0 commit comments