Enum TransitionKind
pub enum TransitionKind
The kind of a transition.
This is used when trying to determine the offset for a local datetime. It
indicates how the corresponding civil datetimes in civil_starts and
civil_ends should be interpreted. That is, there are three possible
cases:
- The offset of this transition is equivalent to the offset of the previous transition. That means there are no ambiguous civil datetimes between the transitions. This can occur, e.g., when the time zone abbreviation changes.
- The offset of the transition is greater than the offset of the previous transition. That means there is a "gap" in local time between the transitions. This typically corresponds to entering daylight saving time. It is usually, but not always, 1 hour.
- The offset of the transition is less than the offset of the previous transition. That means there is a "fold" in local time where time is repeated. This typically corresponds to leaving daylight saving time. It is usually, but not always, 1 hour.
More explanation
This, when combined with civil_starts and civil_ends in
Transitions, explicitly represents ambiguous wall clock times that
occur at the boundaries of transitions.
The start of the wall clock time is always the earlier possible wall clock time that could occur with this transition's corresponding offset. For a gap, it's the previous transition's offset. For a fold, it's the current transition's offset.
For example, DST for America/New_York began on 2024-03-10T07:00:00+00.
The offset prior to this instant in time is -05, corresponding
to standard time (EST). Thus, in wall clock time, DST began at
2024-03-10T02:00:00. And since this is a DST transition that jumps ahead
an hour, the start of DST also corresponds to the start of a gap. That is,
the times 02:00:00 through 02:59:59 never appear on a clock for this
hour. The question is thus: which offset should we apply to 02:00:00?
We could apply the offset from the earlier transition -05 and get
2024-03-10T01:00:00-05 (that's 2024-03-10T06:00:00+00), or we could
apply the offset from the later transition -04 and get
2024-03-10T03:00:00-04 (that's 2024-03-10T07:00:00+00).
So in the above, we would have a Gap variant where start (inclusive) is
2024-03-10T02:00:00 and end (exclusive) is 2024-03-10T03:00:00.
The fold case is the same idea, but where the same time is repeated.
For example, in America/New_York, standard time began on
2024-11-03T06:00:00+00. The offset prior to this instant in time
is -04, corresponding to DST (EDT). Thus, in wall clock time, DST
ended at 2024-11-03T02:00:00. However, since this is a fold, the
actual set of ambiguous times begins at 2024-11-03T01:00:00 and
ends at 2024-11-03T01:59:59.999999999. That is, the wall clock time
2024-11-03T02:00:00 is unambiguous.
So in the fold case above, we would have a Fold variant where
start (inclusive) is 2024-11-03T01:00:00 and end (exclusive) is
2024-11-03T02:00:00.
Since this gets bundled in with the sorted sequence of transitions, we'll
use the "start" time in all three cases as our target of binary search.
Once we land on a transition, we'll know our given wall clock time is
greater than or equal to its start wall clock time. At that point, to
determine if there is ambiguity, we merely need to determine if the given
wall clock time is less than the corresponding end time. If it is, then
it falls in a gap or fold. Otherwise, it's unambiguous.
Note that we could compute these datetime values while searching for the correct transition, but there's a fair bit of math involved in going between timestamps (which is what TZif gives us) and calendar datetimes (which is what we're given as input). It is also necessary that we offset the timestamp given in TZif at some point, since it is in UTC and the datetime given is in wall clock time. So I decided it would be worth pre-computing what we need in terms of what the input is. This way, we don't need to do any conversions, or indeed, any arithmetic at all, for time zone lookups. We could store these as transitions, but then the input datetime would need to be converted to a timestamp before searching the transitions.
Variants
-
Unambiguous This transition cannot possibly lead to an unambiguous offset because its offset is equivalent to the offset of the previous transition.
Has an entry in
civil_starts, but corresponding entry incivil_endsis always zeroes (i.e., meaningless).-
Gap This occurs when this transition's offset is strictly greater than the previous transition's offset. This effectively results in a "gap" of time equal to the difference in the offsets between the two transitions.
Has an entry in
civil_startsfor when the gap starts (inclusive) in local time. Also has an entry incivil_endsfor when the fold ends (exclusive) in local time.-
Fold This occurs when this transition's offset is strictly less than the previous transition's offset. This results in a "fold" of time where the two transitions have an overlap where it is ambiguous which one applies given a wall clock time. In effect, a span of time equal to the difference in the offsets is repeated.
Has an entry in
civil_startsfor when the fold starts (inclusive) in local time. Also has an entry incivil_endsfor when the fold ends (exclusive) in local time.
Trait Implementations
impl Clone for TransitionKind
fn clone(&self) -> TransitionKind
impl Copy for TransitionKind
impl Debug for TransitionKind
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Auto Trait Implementations
impl Freeze for TransitionKind
impl RefUnwindSafe for TransitionKind
impl Send for TransitionKind
impl Sync for TransitionKind
impl Unpin for TransitionKind
impl UnsafeUnpin for TransitionKind
impl UnwindSafe for TransitionKind
Blanket Implementations
impl<T> Any for TransitionKind
where
T: 'static + ?Sized,
fn type_id(&self) -> TypeId
impl<T> Borrow<T> for TransitionKind
where
T: ?Sized,
fn borrow(&self) -> &T
impl<T> BorrowMut<T> for TransitionKind
where
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneToUninit for TransitionKind
where
T: Clone,
unsafe fn clone_to_uninit(&self, dest: *mut u8)
impl<T> From<T> for TransitionKind
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for TransitionKind
where
T: Clone,
type Owned = T;fn to_owned(&self) -> Tfn clone_into(&self, target: &mut T)
impl<T, U> Into<U> for TransitionKind
where
U: From<T>,
fn into(self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom<U> for TransitionKind
where
U: Into<T>,
type Error = Infallible;fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto<U> for TransitionKind
where
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error;fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>