diff --git a/src/offset/local/mod.rs b/src/offset/local/mod.rs index a9ec6f822d..8d040665d1 100644 --- a/src/offset/local/mod.rs +++ b/src/offset/local/mod.rs @@ -222,21 +222,23 @@ impl TzInfo { // // The correct order in `LocalResult::Ambiguous` is the offset right before the transition, then // the offset right after. - fn lookup_with_dst_transitions(&self, dt: NaiveDateTime) -> LocalResult { + fn lookup_with_dst_transitions(&self, dt: NaiveDateTime) -> Option> { let std_offset = self.std_offset; let dst_offset = self.dst_offset; - let std_transition_after = self.std_transition.unwrap() + std_offset - dst_offset; - let dst_transition_after = self.dst_transition.unwrap() + dst_offset - std_offset; + let std_transition = self.std_transition?; + let dst_transition = self.dst_transition?; + let std_transition_after = std_transition + std_offset - dst_offset; + let dst_transition_after = dst_transition + dst_offset - std_offset; // Depending on the dst and std offsets, *_transition_after can have a local time that is // before or after *_transition. To remain sane we define *_min and *_max values that have // the times in order. - let std_transition_min = cmp::min(self.std_transition.unwrap(), std_transition_after); - let std_transition_max = cmp::max(self.std_transition.unwrap(), std_transition_after); - let dst_transition_min = cmp::min(self.dst_transition.unwrap(), dst_transition_after); - let dst_transition_max = cmp::max(self.dst_transition.unwrap(), dst_transition_after); + let std_transition_min = cmp::min(std_transition, std_transition_after); + let std_transition_max = cmp::max(std_transition, std_transition_after); + let dst_transition_min = cmp::min(dst_transition, dst_transition_after); + let dst_transition_max = cmp::max(dst_transition, dst_transition_after); - match std_offset.local_minus_utc().cmp(&dst_offset.local_minus_utc()) { + Some(match std_offset.local_minus_utc().cmp(&dst_offset.local_minus_utc()) { Ordering::Equal => LocalResult::Single(std_offset), Ordering::Less => { if dst_transition_min < std_transition_min { @@ -300,7 +302,7 @@ impl TzInfo { } } } - } + }) } } @@ -405,7 +407,7 @@ mod tests { result: LocalResult, ) { let dt = NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap(); - assert_eq!(tz_info.lookup_with_dst_transitions(dt), result); + assert_eq!(tz_info.lookup_with_dst_transitions(dt).unwrap(), result); } // dst transition before std transition diff --git a/src/offset/local/tz_info/rule.rs b/src/offset/local/tz_info/rule.rs index 91d6aaf09c..9d3b51b8c8 100644 --- a/src/offset/local/tz_info/rule.rs +++ b/src/offset/local/tz_info/rule.rs @@ -248,14 +248,12 @@ impl AlternateTime { let tz_info = TzInfo { std_offset: self.std.offset(), dst_offset: self.dst.offset(), - std_transition: Some(NaiveDateTime::from_timestamp_opt(dst_end_transition, 0).unwrap()), - dst_transition: Some( - NaiveDateTime::from_timestamp_opt(dst_start_transition, 0).unwrap(), - ), + std_transition: NaiveDateTime::from_timestamp_opt(dst_end_transition, 0), + dst_transition: NaiveDateTime::from_timestamp_opt(dst_start_transition, 0), }; let local_datetime = NaiveDateTime::from_timestamp_opt(local_time, 0).unwrap(); - Ok(tz_info.lookup_with_dst_transitions(local_datetime)) + Ok(tz_info.lookup_with_dst_transitions(local_datetime).unwrap()) } } diff --git a/src/offset/local/windows.rs b/src/offset/local/windows.rs index 7cb10a64b7..0b370686fe 100644 --- a/src/offset/local/windows.rs +++ b/src/offset/local/windows.rs @@ -57,9 +57,10 @@ pub(super) fn offset_from_local_datetime(local: &NaiveDateTime) -> LocalResult tz_info, None => return LocalResult::None, }; - match (tz_info.std_transition, tz_info.dst_transition) { - (Some(_), Some(_)) => tz_info.lookup_with_dst_transitions(*local), - _ => LocalResult::Single(tz_info.std_offset), + if let Some(result) = tz_info.lookup_with_dst_transitions(*local) { + result + } else { + LocalResult::Single(tz_info.std_offset) } }