#[cfg(feature = "alloc")] usecrate::provider::legacy::TimezoneVariantsOffsetsV1; usecrate::provider::{TimezonePeriods, TimezonePeriodsV1}; usecrate::TimeZone; use icu_provider::prelude::*;
use displaydoc::Display;
usesuper::ZoneNameTimestamp;
/// The time zone offset was invalid. Must be within ±18:00:00. #[derive(Display, Debug, Copy, Clone, PartialEq)] #[allow(clippy::exhaustive_structs)] pubstruct InvalidOffsetError;
/// An offset from Coordinated Universal Time (UTC). /// /// Supports ±18:00:00. /// /// **The primary definition of this type is in the [`icu_time`](https://docs.rs/icu_time)crate. Other ICU4X crates re-export it for convenience.** #[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PartialOrd, Ord)] pubstruct UtcOffset(i32);
impl UtcOffset { /// Attempt to create a [`UtcOffset`] from a seconds input. /// /// Returns [`InvalidOffsetError`] if the seconds are out of bounds. pubfn try_from_seconds(seconds: i32) -> Result<Self, InvalidOffsetError> { if seconds.unsigned_abs() > 18 * 60 * 60 {
Err(InvalidOffsetError)
} else {
Ok(Self(seconds))
}
}
/// Creates a [`UtcOffset`] of zero. pubconstfn zero() -> Self { Self(0)
}
/// Parse a [`UtcOffset`] from bytes. /// /// The offset must range from UTC-12 to UTC+14. /// /// The string must be an ISO-8601 time zone designator: /// e.g. Z /// e.g. +05 /// e.g. +0500 /// e.g. +05:00 /// /// # Examples /// /// ``` /// use icu::time::zone::UtcOffset; /// /// let offset0: UtcOffset = UtcOffset::try_from_str("Z").unwrap(); /// let offset1: UtcOffset = UtcOffset::try_from_str("+05").unwrap(); /// let offset2: UtcOffset = UtcOffset::try_from_str("+0500").unwrap(); /// let offset3: UtcOffset = UtcOffset::try_from_str("-05:00").unwrap(); /// /// let offset_err0 = /// UtcOffset::try_from_str("0500").expect_err("Invalid input"); /// let offset_err1 = /// UtcOffset::try_from_str("+05000").expect_err("Invalid input"); /// /// assert_eq!(offset0.to_seconds(), 0); /// assert_eq!(offset1.to_seconds(), 18000); /// assert_eq!(offset2.to_seconds(), 18000); /// assert_eq!(offset3.to_seconds(), -18000); /// ``` #[inline] pubfn try_from_str(s: &str) -> Result<Self, InvalidOffsetError> { Self::try_from_utf8(s.as_bytes())
}
/// See [`Self::try_from_str`] pubfn try_from_utf8(mut code_units: &[u8]) -> Result<Self, InvalidOffsetError> { fn try_get_time_component([tens, ones]: [u8; 2]) -> Option<i32> {
Some(((tens as char).to_digit(10)? * 10 + (ones as char).to_digit(10)?) as i32)
}
/// Create a [`UtcOffset`] from a seconds input without checking bounds. #[inline] pubconstfn from_seconds_unchecked(seconds: i32) -> Self { Self(seconds)
}
/// Returns the raw offset value in seconds. pubconstfn to_seconds(self) -> i32 { self.0
}
/// Whether the [`UtcOffset`] is non-negative. pubfn is_non_negative(self) -> bool { self.0 >= 0
}
/// Whether the [`UtcOffset`] is zero. pubfn is_zero(self) -> bool { self.0 == 0
}
/// Returns the hours part of if the [`UtcOffset`] pubfn hours_part(self) -> i32 { self.0 / 3600
}
/// Returns the minutes part of if the [`UtcOffset`]. pubfn minutes_part(self) -> u32 {
(self.0 % 3600 / 60).unsigned_abs()
}
/// Returns the seconds part of if the [`UtcOffset`]. pubfn seconds_part(self) -> u32 {
(self.0 % 60).unsigned_abs()
}
}
impl FromStr for UtcOffset { type Err = InvalidOffsetError;
/// [`VariantOffsetsCalculator`] uses data from the [data provider] to calculate time zone offsets. /// /// [data provider]: icu_provider #[derive(Debug)] #[deprecated(
since = "2.1.0",
note = "this API is a bad approximation of a time zone database"
)] pubstruct VariantOffsetsCalculator {
offset_period: OffsetData,
}
/// The borrowed version of a [`VariantOffsetsCalculator`] #[derive(Debug)] #[deprecated(
since = "2.1.0",
note = "this API is a bad approximation of a time zone database"
)] pubstruct VariantOffsetsCalculatorBorrowed<'a> {
offset_period: OffsetDataBorrowed<'a>,
}
/// Returns a borrowed version of the calculator that can be queried. /// /// This avoids a small potential indirection cost when querying. pubfn as_borrowed(&self) -> VariantOffsetsCalculatorBorrowed<'_> {
VariantOffsetsCalculatorBorrowed {
offset_period: matchself.offset_period {
OffsetData::New(ref payload) => OffsetDataBorrowed::New(payload.get()), #[cfg(feature = "alloc")]
OffsetData::Old(ref payload) => OffsetDataBorrowed::Old(payload.get()),
},
}
}
}
#[allow(deprecated)] impl VariantOffsetsCalculatorBorrowed<'static> { /// Constructs a `VariantOffsetsCalculatorBorrowed` using compiled data. /// /// ✨ *Enabled with the `compiled_data` Cargo feature.* /// /// [ Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] #[inline] pubconstfn new() -> Self { Self {
offset_period: OffsetDataBorrowed::New( crate::provider::Baked::SINGLETON_TIMEZONE_PERIODS_V1,
),
}
}
/// Cheaply converts a [`VariantOffsetsCalculatorBorrowed<'static>`] into a [`VariantOffsetsCalculator`]. /// /// Note: Due to branching and indirection, using [`VariantOffsetsCalculator`] might inhibit some /// compile-time optimizations that are possible with [`VariantOffsetsCalculatorBorrowed`]. pubfn static_to_owned(&self) -> VariantOffsetsCalculator {
VariantOffsetsCalculator {
offset_period: matchself.offset_period {
OffsetDataBorrowed::New(p) => OffsetData::New(DataPayload::from_static_ref(p)), #[cfg(feature = "alloc")]
OffsetDataBorrowed::Old(p) => OffsetData::Old(DataPayload::from_static_ref(p)),
},
}
}
}
#[allow(deprecated)] impl VariantOffsetsCalculatorBorrowed<'_> { /// Calculate zone offsets from timezone and local datetime. /// /// # Examples /// /// ``` /// use icu::calendar::Date; /// use icu::locale::subtags::subtag; /// use icu::time::zone::UtcOffset; /// use icu::time::zone::VariantOffsetsCalculator; /// use icu::time::zone::ZoneNameTimestamp; /// use icu::time::Time; /// use icu::time::TimeZone; /// /// let zoc = VariantOffsetsCalculator::new(); /// /// // America/Denver observes DST /// let offsets = zoc /// .compute_offsets_from_time_zone_and_name_timestamp( /// TimeZone(subtag!("usden")), /// ZoneNameTimestamp::far_in_future(), /// ) /// .unwrap(); /// assert_eq!( /// offsets.standard, /// UtcOffset::try_from_seconds(-7 * 3600).unwrap() /// ); /// assert_eq!( /// offsets.daylight, /// Some(UtcOffset::try_from_seconds(-6 * 3600).unwrap()) /// ); /// /// // America/Phoenix does not /// let offsets = zoc /// .compute_offsets_from_time_zone_and_name_timestamp( /// TimeZone(subtag!("usphx")), /// ZoneNameTimestamp::far_in_future(), /// ) /// .unwrap(); /// assert_eq!( /// offsets.standard, /// UtcOffset::try_from_seconds(-7 * 3600).unwrap() /// ); /// assert_eq!(offsets.daylight, None); /// ``` pubfn compute_offsets_from_time_zone_and_name_timestamp(
&self,
time_zone_id: TimeZone,
timestamp: ZoneNameTimestamp,
) -> Option<VariantOffsets> { matchself.offset_period {
OffsetDataBorrowed::New(p) => p.get(time_zone_id, timestamp).map(|(os, _)| os), #[cfg(feature = "alloc")]
OffsetDataBorrowed::Old(p) => { use zerovec::ule::AsULE; letmut offsets = None; for (bytes, id) in p.get0(&time_zone_id)?.iter1_copied().rev() { if timestamp >= ZoneNameTimestamp::from_unaligned(*bytes) {
offsets = Some(id); break;
}
}
Some(offsets?)
}
}
}
}
#[deprecated(
since = "2.1.0",
note = "this API is a bad approximation of a time zone database"
)] pubusecrate::provider::VariantOffsets;
#[test] #[allow(deprecated)] pubfn test_legacy_offsets_data() { usecrate::ZonedDateTime; use icu_locale_core::subtags::subtag; use icu_provider_blob::BlobDataProvider;
let c = VariantOffsetsCalculator::try_new_with_buffer_provider(
&BlobDataProvider::try_new_from_static_blob( // icu4x-datagen --markers TimezoneVariantsOffsetsV1 --format blob
include_bytes!("../../tests/data/offset_periods_old.blob"),
)
.unwrap(),
)
.unwrap();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.