devela::_dep::jiff::tz

Struct AmbiguousTimestamp

pub struct AmbiguousTimestamp { /* private fields */ }
Available on crate features dep_jiff and alloc only.
Expand description

A possibly ambiguous Timestamp, created by TimeZone::to_ambiguous_timestamp.

While this is called an ambiguous timestamp, the thing that is actually ambiguous is the offset. That is, an ambiguous timestamp is actually a pair of a civil::DateTime and an AmbiguousOffset.

When the offset is ambiguous, it either represents a gap (civil time is skipped) or a fold (civil time is repeated). In both cases, there are, by construction, two different offsets to choose from: the offset from before the transition and the offset from after the transition.

The purpose of this type is to represent that ambiguity (when it occurs) and enable callers to make a choice about how to resolve that ambiguity. In some cases, you might want to reject ambiguity altogether, which is supported by the AmbiguousTimestamp::unambiguous routine.

This type provides four different out-of-the-box disambiguation strategies:

The AmbiguousTimestamp::disambiguate method can be used with the Disambiguation enum when the disambiguation strategy isn’t known until runtime.

Note also that these aren’t the only disambiguation strategies. The AmbiguousOffset type, accessible via AmbiguousTimestamp::offset, exposes the full details of the ambiguity. So any strategy can be implemented.

§Example

This example shows how the “compatible” disambiguation strategy is implemented. Recall that the “compatible” strategy chooses the offset corresponding to the civil datetime after a gap, and the offset corresponding to the civil datetime before a gap.

use jiff::{civil::date, tz::{self, AmbiguousOffset}};

let tz = tz::db().get("America/New_York")?;
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let offset = match tz.to_ambiguous_timestamp(dt).offset() {
    AmbiguousOffset::Unambiguous { offset } => offset,
    // This is counter-intuitive, but in order to get the civil datetime
    // *after* the gap, we need to select the offset from *before* the
    // gap.
    AmbiguousOffset::Gap { before, .. } => before,
    AmbiguousOffset::Fold { before, .. } => before,
};
assert_eq!(offset.to_timestamp(dt)?.to_string(), "2024-03-10T07:30:00Z");

Implementations§

§

impl AmbiguousTimestamp

pub fn datetime(&self) -> DateTime

Returns the civil datetime that was used to create this ambiguous timestamp.

§Example
use jiff::{civil::date, tz};

let tz = tz::db().get("America/New_York")?;
let dt = date(2024, 7, 10).at(17, 15, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(ts.datetime(), dt);

pub fn offset(&self) -> AmbiguousOffset

Returns the possibly ambiguous offset that is the ultimate source of ambiguity.

Most civil datetimes are not ambiguous, and thus, the offset will not be ambiguous either. In this case, the offset returned will be the AmbiguousOffset::Unambiguous variant.

But, not all civil datetimes are unambiguous. There are exactly two cases where a civil datetime can be ambiguous: when a civil datetime does not exist (a gap) or when a civil datetime is repeated (a fold). In both such cases, the offset is the thing that is ambiguous as there are two possible choices for the offset in both cases: the offset before the transition (whether it’s a gap or a fold) or the offset after the transition.

This type captures the fact that computing an offset from a civil datetime in a particular time zone is in one of three possible states:

  1. It is unambiguous.
  2. It is ambiguous because there is a gap in time.
  3. It is ambiguous because there is a fold in time.
§Example
use jiff::{civil::date, tz::{self, AmbiguousOffset}};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(ts.offset(), AmbiguousOffset::Unambiguous {
    offset: tz::offset(-4),
});

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(ts.offset(), AmbiguousOffset::Gap {
    before: tz::offset(-5),
    after: tz::offset(-4),
});

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(ts.offset(), AmbiguousOffset::Fold {
    before: tz::offset(-4),
    after: tz::offset(-5),
});

pub fn is_ambiguous(&self) -> bool

Returns true if and only if this possibly ambiguous timestamp is actually ambiguous.

This occurs precisely in cases when the offset is not AmbiguousOffset::Unambiguous.

§Example
use jiff::{civil::date, tz::{self, AmbiguousOffset}};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert!(!ts.is_ambiguous());

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert!(ts.is_ambiguous());

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert!(ts.is_ambiguous());

pub fn compatible(self) -> Result<Timestamp, Error>

Disambiguates this timestamp according to the Disambiguation::Compatible strategy.

If this timestamp is unambiguous, then this is a no-op.

The “compatible” strategy selects the offset corresponding to the civil time after a gap, and the offset corresponding to the civil time before a fold. This is what is specified in RFC 5545.

§Errors

This returns an error when the combination of the civil datetime and offset would lead to a Timestamp outside of the Timestamp::MIN and Timestamp::MAX limits. This only occurs when the civil datetime is “close” to its own DateTime::MIN and DateTime::MAX limits.

§Example
use jiff::{civil::date, tz};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.compatible()?.to_string(),
    "2024-07-15T21:30:00Z",
);

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.compatible()?.to_string(),
    "2024-03-10T07:30:00Z",
);

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.compatible()?.to_string(),
    "2024-11-03T05:30:00Z",
);

pub fn earlier(self) -> Result<Timestamp, Error>

Disambiguates this timestamp according to the Disambiguation::Earlier strategy.

If this timestamp is unambiguous, then this is a no-op.

The “earlier” strategy selects the offset corresponding to the civil time before a gap, and the offset corresponding to the civil time before a fold.

§Errors

This returns an error when the combination of the civil datetime and offset would lead to a Timestamp outside of the Timestamp::MIN and Timestamp::MAX limits. This only occurs when the civil datetime is “close” to its own DateTime::MIN and DateTime::MAX limits.

§Example
use jiff::{civil::date, tz};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.earlier()?.to_string(),
    "2024-07-15T21:30:00Z",
);

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.earlier()?.to_string(),
    "2024-03-10T06:30:00Z",
);

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.earlier()?.to_string(),
    "2024-11-03T05:30:00Z",
);

pub fn later(self) -> Result<Timestamp, Error>

Disambiguates this timestamp according to the Disambiguation::Later strategy.

If this timestamp is unambiguous, then this is a no-op.

The “later” strategy selects the offset corresponding to the civil time after a gap, and the offset corresponding to the civil time after a fold.

§Errors

This returns an error when the combination of the civil datetime and offset would lead to a Timestamp outside of the Timestamp::MIN and Timestamp::MAX limits. This only occurs when the civil datetime is “close” to its own DateTime::MIN and DateTime::MAX limits.

§Example
use jiff::{civil::date, tz};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.later()?.to_string(),
    "2024-07-15T21:30:00Z",
);

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.later()?.to_string(),
    "2024-03-10T07:30:00Z",
);

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.later()?.to_string(),
    "2024-11-03T06:30:00Z",
);

pub fn unambiguous(self) -> Result<Timestamp, Error>

Disambiguates this timestamp according to the Disambiguation::Reject strategy.

If this timestamp is unambiguous, then this is a no-op.

The “reject” strategy always returns an error when the timestamp is ambiguous.

§Errors

This returns an error when the combination of the civil datetime and offset would lead to a Timestamp outside of the Timestamp::MIN and Timestamp::MAX limits. This only occurs when the civil datetime is “close” to its own DateTime::MIN and DateTime::MAX limits.

This also returns an error when the timestamp is ambiguous.

§Example
use jiff::{civil::date, tz};

let tz = tz::db().get("America/New_York")?;

// Not ambiguous.
let dt = date(2024, 7, 15).at(17, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert_eq!(
    ts.later()?.to_string(),
    "2024-07-15T21:30:00Z",
);

// Ambiguous because of a gap.
let dt = date(2024, 3, 10).at(2, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert!(ts.unambiguous().is_err());

// Ambiguous because of a fold.
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ts = tz.to_ambiguous_timestamp(dt);
assert!(ts.unambiguous().is_err());

pub fn disambiguate(self, option: Disambiguation) -> Result<Timestamp, Error>

Disambiguates this (possibly ambiguous) timestamp into a specific timestamp.

This is the same as calling one of the disambiguation methods, but the method chosen is indicated by the option given. This is useful when the disambiguation option needs to be chosen at runtime.

§Errors

This returns an error if this would have returned a timestamp outside of its minimum and maximum values.

This can also return an error when using the Disambiguation::Reject strategy. Namely, when using the Reject strategy, any ambiguous timestamp always results in an error.

§Example

This example shows the various disambiguation modes when given a datetime that falls in a “fold” (i.e., a backwards DST transition).

use jiff::{civil::date, tz::{self, Disambiguation}};

let newyork = tz::db().get("America/New_York")?;
let dt = date(2024, 11, 3).at(1, 30, 0, 0);
let ambiguous = newyork.to_ambiguous_timestamp(dt);

// In compatible mode, backward transitions select the earlier
// time. In the EDT->EST transition, that's the -04 (EDT) offset.
let ts = ambiguous.clone().disambiguate(Disambiguation::Compatible)?;
assert_eq!(ts.to_string(), "2024-11-03T05:30:00Z");

// The earlier time in the EDT->EST transition is the -04 (EDT) offset.
let ts = ambiguous.clone().disambiguate(Disambiguation::Earlier)?;
assert_eq!(ts.to_string(), "2024-11-03T05:30:00Z");

// The later time in the EDT->EST transition is the -05 (EST) offset.
let ts = ambiguous.clone().disambiguate(Disambiguation::Later)?;
assert_eq!(ts.to_string(), "2024-11-03T06:30:00Z");

// Since our datetime is ambiguous, the 'reject' strategy errors.
assert!(ambiguous.disambiguate(Disambiguation::Reject).is_err());

Trait Implementations§

§

impl Clone for AmbiguousTimestamp

§

fn clone(&self) -> AmbiguousTimestamp

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for AmbiguousTimestamp

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for AmbiguousTimestamp

§

fn eq(&self, other: &AmbiguousTimestamp) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
§

impl Copy for AmbiguousTimestamp

§

impl Eq for AmbiguousTimestamp

§

impl StructuralPartialEq for AmbiguousTimestamp

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> ArchivePointee for T

§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByteSized for T

Source§

const BYTE_ALIGN: usize = _

The alignment of this type in bytes.
Source§

const BYTE_SIZE: usize = _

The size of this type in bytes.
Source§

fn byte_align(&self) -> usize

Returns the alignment of this type in bytes.
Source§

fn byte_size(&self) -> usize

Returns the size of this type in bytes. Read more
Source§

fn ptr_size_ratio(&self) -> [usize; 2]

Returns the size ratio between Ptr::BYTES and BYTE_SIZE. Read more
Source§

impl<T, R> Chain<R> for T
where T: ?Sized,

Source§

fn chain<F>(self, f: F) -> R
where F: FnOnce(Self) -> R, Self: Sized,

Chain a function which takes the parameter by value.
Source§

fn chain_ref<F>(&self, f: F) -> R
where F: FnOnce(&Self) -> R,

Chain a function which takes the parameter by shared reference.
Source§

fn chain_mut<F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self) -> R,

Chain a function which takes the parameter by exclusive reference.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> ExtAny for T
where T: Any + ?Sized,

Source§

fn type_id() -> TypeId

Returns the TypeId of Self. Read more
Source§

fn type_of(&self) -> TypeId

Returns the TypeId of self. Read more
Source§

fn type_name(&self) -> &'static str

Returns the type name of self. Read more
Source§

fn type_is<T: 'static>(&self) -> bool

Returns true if Self is of type T. Read more
Source§

fn as_any_ref(&self) -> &dyn Any
where Self: Sized,

Upcasts &self as &dyn Any. Read more
Source§

fn as_any_mut(&mut self) -> &mut dyn Any
where Self: Sized,

Upcasts &mut self as &mut dyn Any. Read more
Source§

fn as_any_box(self: Box<Self>) -> Box<dyn Any>
where Self: Sized,

Upcasts Box<self> as Box<dyn Any>. Read more
Source§

fn downcast_ref<T: 'static>(&self) -> Option<&T>

Available on crate feature unsafe_layout only.
Returns some shared reference to the inner value if it is of type T. Read more
Source§

fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T>

Available on crate feature unsafe_layout only.
Returns some exclusive reference to the inner value if it is of type T. Read more
Source§

impl<T> ExtMem for T
where T: ?Sized,

Source§

const NEEDS_DROP: bool = _

Know whether dropping values of this type matters, in compile-time.
Source§

fn mem_align_of<T>() -> usize

Returns the minimum alignment of the type in bytes. Read more
Source§

fn mem_align_of_val(&self) -> usize

Returns the alignment of the pointed-to value in bytes. Read more
Source§

fn mem_size_of<T>() -> usize

Returns the size of a type in bytes. Read more
Source§

fn mem_size_of_val(&self) -> usize

Returns the size of the pointed-to value in bytes. Read more
Source§

fn mem_copy(&self) -> Self
where Self: Copy,

Bitwise-copies a value. Read more
Source§

fn mem_needs_drop(&self) -> bool

Returns true if dropping values of this type matters. Read more
Source§

fn mem_drop(self)
where Self: Sized,

Drops self by running its destructor. Read more
Source§

fn mem_forget(self)
where Self: Sized,

Forgets about self without running its destructor. Read more
Source§

fn mem_replace(&mut self, other: Self) -> Self
where Self: Sized,

Replaces self with other, returning the previous value of self. Read more
Source§

fn mem_take(&mut self) -> Self
where Self: Default,

Replaces self with its default value, returning the previous value of self. Read more
Source§

fn mem_swap(&mut self, other: &mut Self)
where Self: Sized,

Swaps the value of self and other without deinitializing either one. Read more
Source§

unsafe fn mem_zeroed<T>() -> T

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

fn mem_as_bytes(&self) -> &[u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &[u8]. Read more
Source§

fn mem_as_bytes_mut(&mut self) -> &mut [u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &mut [u8]. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T> Hook for T

Source§

fn hook_ref<F>(self, f: F) -> Self
where F: FnOnce(&Self),

Applies a function which takes the parameter by shared reference, and then returns the (possibly) modified owned value. Read more
Source§

fn hook_mut<F>(self, f: F) -> Self
where F: FnOnce(&mut Self),

Applies a function which takes the parameter by exclusive reference, and then returns the (possibly) modified owned value. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> LayoutRaw for T

§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Pointee for T

§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Ungil for T
where T: Send,