From 83b8c24eb6c0d5b4263a6d02192816aec96155a3 Mon Sep 17 00:00:00 2001 From: Robert Bastian Date: Tue, 14 Jan 2025 19:46:22 +0100 Subject: [PATCH] Move icu::calendar::{DateTime, Time} to icu::timezone --- components/calendar/README.md | 6 +- components/calendar/src/datetime.rs | 15 - components/calendar/src/ixdtf.rs | 164 +-------- components/calendar/src/lib.rs | 9 +- components/calendar/src/types.rs | 311 ----------------- components/datetime/README.md | 7 +- components/datetime/benches/datetime.rs | 4 +- components/datetime/examples/work_log.rs | 3 +- components/datetime/src/combo.rs | 4 +- components/datetime/src/dynamic.rs | 3 +- components/datetime/src/fieldsets.rs | 51 +-- components/datetime/src/format/time_zone.rs | 4 +- components/datetime/src/input.rs | 11 +- components/datetime/src/lib.rs | 7 +- components/datetime/src/neo.rs | 12 +- components/datetime/src/options/mod.rs | 4 +- components/datetime/src/parts.rs | 4 +- components/datetime/src/pattern/formatter.rs | 5 +- components/datetime/src/pattern/names.rs | 20 +- components/datetime/src/pattern/pattern.rs | 2 +- components/datetime/src/scaffold/calendar.rs | 6 +- .../datetime/src/scaffold/dynamic_impls.rs | 12 +- .../datetime/src/scaffold/fieldset_traits.rs | 16 +- components/datetime/src/scaffold/get_field.rs | 11 +- components/datetime/tests/datetime.rs | 4 +- .../datetime/tests/resolved_components.rs | 3 +- components/datetime/tests/simple_test.rs | 3 +- components/icu/examples/tui.rs | 4 +- components/timezone/Cargo.toml | 2 +- components/timezone/README.md | 3 +- components/timezone/src/ixdtf.rs | 183 +++++++++- components/timezone/src/lib.rs | 10 +- .../timezone/src/scaffold/into_option.rs | 2 +- components/timezone/src/time_zone.rs | 4 +- components/timezone/src/types.rs | 320 +++++++++++++++++- components/timezone/src/zone_offset.rs | 7 +- ffi/capi/Cargo.toml | 2 +- ffi/capi/bindings/dart/DateTime.g.dart | 24 +- ffi/capi/bindings/dart/IsoDateTime.g.dart | 24 +- ffi/capi/bindings/dart/Time.g.dart | 16 +- ffi/capi/bindings/js/DateTime.d.ts | 2 +- ffi/capi/bindings/js/DateTime.mjs | 2 +- ffi/capi/bindings/js/IsoDateTime.d.ts | 2 +- ffi/capi/bindings/js/IsoDateTime.mjs | 2 +- ffi/capi/bindings/js/Time.d.ts | 2 +- ffi/capi/bindings/js/Time.mjs | 2 +- ffi/capi/src/datetime.rs | 90 ++--- ffi/capi/src/datetime_formatter.rs | 8 +- ffi/capi/src/errors.rs | 14 + ffi/capi/src/time.rs | 30 +- ffi/capi/src/timezone.rs | 4 +- provider/source/src/time_zones/convert.rs | 2 +- tools/make/diplomat-coverage/src/allowlist.rs | 23 +- tutorials/intro_interactive.md | 2 +- tutorials/rust/buffer/src/main.rs | 3 +- 55 files changed, 764 insertions(+), 726 deletions(-) delete mode 100644 components/calendar/src/datetime.rs diff --git a/components/calendar/README.md b/components/calendar/README.md index c6bce53e539..671e1088fe9 100644 --- a/components/calendar/README.md +++ b/components/calendar/README.md @@ -2,11 +2,11 @@ -Types for dealing with dates, times, and custom calendars. +Types for dealing with dates and custom calendars. This module is published as its own crate ([`icu_calendar`](https://docs.rs/icu_calendar/latest/icu_calendar/)) and as part of the [`icu`](https://docs.rs/icu/latest/icu/) crate. See the latter for more details on the ICU4X project. -The [`types`] module has a lot of common types for dealing with dates and times. +The [`types`] module has a lot of common types for dealing with dates. [`Calendar`] is a trait that allows one to define custom calendars, and [`Date`] can represent dates for arbitrary calendars. @@ -14,7 +14,7 @@ can represent dates for arbitrary calendars. The [`Iso`] and [`Gregorian`] types are implementations for the ISO and Gregorian calendars respectively. Further calendars can be found in the [`cal`] module. -Most interaction with this crate will be done via the [`Date`] and [`DateTime`] types. +Most interaction with this crate will be done via the [`Date`] type. Some of the algorithms implemented here are based on Dershowitz, Nachum, and Edward M. Reingold. _Calendrical calculations_. Cambridge University Press, 2008. diff --git a/components/calendar/src/datetime.rs b/components/calendar/src/datetime.rs deleted file mode 100644 index 06cf069587a..00000000000 --- a/components/calendar/src/datetime.rs +++ /dev/null @@ -1,15 +0,0 @@ -// This file is part of ICU4X. For terms of use, please see the file -// called LICENSE at the top level of the ICU4X source tree -// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). - -use crate::{AsCalendar, Date, Time}; - -/// A date + time for a given calendar. -#[derive(Debug)] -#[allow(clippy::exhaustive_structs)] // this type is stable -pub struct DateTime { - /// The date - pub date: Date, - /// The time - pub time: Time, -} diff --git a/components/calendar/src/ixdtf.rs b/components/calendar/src/ixdtf.rs index 2735f5a083e..a99d26e1b3d 100644 --- a/components/calendar/src/ixdtf.rs +++ b/components/calendar/src/ixdtf.rs @@ -4,7 +4,7 @@ use core::str::FromStr; -use crate::{AnyCalendarKind, AsCalendar, Calendar, Date, DateTime, Iso, RangeError, Time}; +use crate::{AnyCalendarKind, AsCalendar, Calendar, Date, Iso, RangeError}; use ixdtf::parsers::records::IxdtfParseRecord; use ixdtf::parsers::IxdtfParser; use ixdtf::ParseError as IxdtfError; @@ -143,165 +143,3 @@ impl Date { Ok(date) } } - -impl Time { - /// Creates a [`Time`] from an IXDTF syntax string of a time. - /// - /// Does not support parsing an IXDTF string with a date and time; for that, use [`DateTime`]. - /// - /// ✨ *Enabled with the `ixdtf` Cargo feature.* - /// - /// # Examples - /// - /// ``` - /// use icu::calendar::Time; - /// - /// let time = Time::try_from_str("16:01:17.045").unwrap(); - /// - /// assert_eq!(time.hour.number(), 16); - /// assert_eq!(time.minute.number(), 1); - /// assert_eq!(time.second.number(), 17); - /// assert_eq!(time.nanosecond.number(), 45000000); - /// ``` - pub fn try_from_str(ixdtf_str: &str) -> Result { - Self::try_from_utf8(ixdtf_str.as_bytes()) - } - - /// Creates a [`Time`] in the ISO-8601 calendar from an IXDTF syntax string. - /// - /// ✨ *Enabled with the `ixdtf` Cargo feature.* - /// - /// See [`Self::try_from_str()`]. - pub fn try_from_utf8(ixdtf_str: &[u8]) -> Result { - let ixdtf_record = IxdtfParser::from_utf8(ixdtf_str).parse_time()?; - Self::try_from_ixdtf_record(&ixdtf_record) - } - - fn try_from_ixdtf_record(ixdtf_record: &IxdtfParseRecord) -> Result { - let time_record = ixdtf_record.time.ok_or(ParseError::MissingFields)?; - let time = Self::try_new( - time_record.hour, - time_record.minute, - time_record.second, - time_record.nanosecond, - )?; - Ok(time) - } -} - -impl FromStr for Time { - type Err = ParseError; - fn from_str(ixdtf_str: &str) -> Result { - Self::try_from_str(ixdtf_str) - } -} - -impl DateTime { - /// Creates a [`DateTime`] in the ISO-8601 calendar from an IXDTF syntax string. - /// - /// Ignores any calendar annotations in the string. - /// - /// ✨ *Enabled with the `ixdtf` Cargo feature.* - /// - /// # Examples - /// - /// ``` - /// use icu::calendar::DateTime; - /// - /// let datetime = - /// DateTime::try_iso_from_str("2024-07-17T16:01:17.045").unwrap(); - /// - /// assert_eq!(datetime.date.year().era_year_or_extended(), 2024); - /// assert_eq!( - /// datetime.date.month().standard_code, - /// icu::calendar::types::MonthCode(tinystr::tinystr!(4, "M07")) - /// ); - /// assert_eq!(datetime.date.day_of_month().0, 17); - /// - /// assert_eq!(datetime.time.hour.number(), 16); - /// assert_eq!(datetime.time.minute.number(), 1); - /// assert_eq!(datetime.time.second.number(), 17); - /// assert_eq!(datetime.time.nanosecond.number(), 45000000); - /// ``` - pub fn try_iso_from_str(ixdtf_str: &str) -> Result { - Self::try_iso_from_utf8(ixdtf_str.as_bytes()) - } - - /// Creates a [`DateTime`] in the ISO-8601 calendar from an IXDTF syntax string. - /// - /// ✨ *Enabled with the `ixdtf` Cargo feature.* - /// - /// See [`Self::try_iso_from_str()`]. - pub fn try_iso_from_utf8(ixdtf_str: &[u8]) -> Result { - let ixdtf_record = IxdtfParser::from_utf8(ixdtf_str).parse()?; - Self::try_from_ixdtf_record(&ixdtf_record) - } - - fn try_from_ixdtf_record(ixdtf_record: &IxdtfParseRecord) -> Result { - let date = Date::::try_from_ixdtf_record(ixdtf_record)?; - let time = Time::try_from_ixdtf_record(ixdtf_record)?; - Ok(Self { date, time }) - } -} - -impl FromStr for DateTime { - type Err = ParseError; - fn from_str(ixdtf_str: &str) -> Result { - Self::try_iso_from_str(ixdtf_str) - } -} - -impl DateTime { - /// Creates a [`DateTime`] in any calendar from an IXDTF syntax string with compiled data. - /// - /// # Examples - /// - /// ``` - /// use icu::calendar::cal::Hebrew; - /// use icu::calendar::DateTime; - /// - /// let datetime = - /// DateTime::try_from_str("2024-07-17T16:01:17.045[u-ca=hebrew]", Hebrew).unwrap(); - /// - /// assert_eq!(datetime.date.year().era_year_or_extended(), 5784); - /// assert_eq!( - /// datetime.date.month().standard_code, - /// icu::calendar::types::MonthCode(tinystr::tinystr!(4, "M10")) - /// ); - /// assert_eq!(datetime.date.day_of_month().0, 11); - /// - /// assert_eq!(datetime.time.hour.number(), 16); - /// assert_eq!(datetime.time.minute.number(), 1); - /// assert_eq!(datetime.time.second.number(), 17); - /// assert_eq!(datetime.time.nanosecond.number(), 45000000); - /// ``` - pub fn try_from_str(ixdtf_str: &str, calendar: A) -> Result { - Self::try_from_utf8(ixdtf_str.as_bytes(), calendar) - } - - /// Creates a [`DateTime`] in any calendar from an IXDTF syntax string with compiled data. - /// - /// See [`Self::try_from_str()`]. - pub fn try_from_utf8(ixdtf_str: &[u8], calendar: A) -> Result { - let ixdtf_record = IxdtfParser::from_utf8(ixdtf_str).parse()?; - if let Some(ixdtf_calendar) = ixdtf_record.calendar { - let parsed_calendar = crate::AnyCalendarKind::get_for_bcp47_bytes(ixdtf_calendar) - .ok_or(ParseError::UnknownCalendar)?; - let expected_calendar = calendar - .as_calendar() - .any_calendar_kind() - .ok_or(ParseError::UnknownCalendar)?; - if parsed_calendar != expected_calendar { - return Err(ParseError::MismatchedCalendar( - expected_calendar, - parsed_calendar, - )); - } - } - let DateTime { date, time } = DateTime::::try_from_ixdtf_record(&ixdtf_record)?; - Ok(DateTime { - date: date.to_any().to_calendar(calendar), - time, - }) - } -} diff --git a/components/calendar/src/lib.rs b/components/calendar/src/lib.rs index 570e41c0f28..e22b58b2491 100644 --- a/components/calendar/src/lib.rs +++ b/components/calendar/src/lib.rs @@ -2,11 +2,11 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -//! Types for dealing with dates, times, and custom calendars. +//! Types for dealing with dates and custom calendars. //! //! This module is published as its own crate ([`icu_calendar`](https://docs.rs/icu_calendar/latest/icu_calendar/)) //! and as part of the [`icu`](https://docs.rs/icu/latest/icu/) crate. See the latter for more details on the ICU4X project. -//! The [`types`] module has a lot of common types for dealing with dates and times. +//! The [`types`] module has a lot of common types for dealing with dates. //! //! [`Calendar`] is a trait that allows one to define custom calendars, and [`Date`] //! can represent dates for arbitrary calendars. @@ -14,7 +14,7 @@ //! The [`Iso`] and [`Gregorian`] types are implementations for the ISO and //! Gregorian calendars respectively. Further calendars can be found in the [`cal`] module. //! -//! Most interaction with this crate will be done via the [`Date`] and [`DateTime`] types. +//! Most interaction with this crate will be done via the [`Date`] type. //! //! Some of the algorithms implemented here are based on //! Dershowitz, Nachum, and Edward M. Reingold. _Calendrical calculations_. Cambridge University Press, 2008. @@ -93,7 +93,6 @@ extern crate alloc; // Make sure inherent docs go first mod date; -mod datetime; /// Types for individual calendars pub mod cal { @@ -183,7 +182,6 @@ pub use crate::ixdtf::ParseError; pub use any_calendar::{AnyCalendar, AnyCalendarKind, AnyCalendarPreferences}; pub use calendar::Calendar; pub use date::{AsCalendar, Date, Ref}; -pub use datetime::DateTime; #[doc(hidden)] // unstable pub use duration::{DateDuration, DateDurationUnit}; pub use error::{DateError, RangeError}; @@ -191,4 +189,3 @@ pub use error::{DateError, RangeError}; pub use gregorian::Gregorian; #[doc(no_inline)] pub use iso::Iso; -pub use types::Time; diff --git a/components/calendar/src/types.rs b/components/calendar/src/types.rs index 373aa33fa55..961ea1d50a9 100644 --- a/components/calendar/src/types.rs +++ b/components/calendar/src/types.rs @@ -4,9 +4,6 @@ //! This module contains various types used by `icu_calendar` and `icu::datetime` -use crate::error::RangeError; -use core::convert::TryFrom; -use core::convert::TryInto; use core::fmt; use core::num::NonZeroU8; use tinystr::TinyAsciiStr; @@ -406,314 +403,6 @@ fn test_day_of_week_in_month() { assert_eq!(DayOfWeekInMonth::from(DayOfMonth(8)).0, 2); } -/// This macro defines a struct for 0-based date fields: hours, minutes, seconds -/// and fractional seconds. Each unit is bounded by a range. The traits implemented -/// here will return a Result on whether or not the unit is in range from the given -/// input. -macro_rules! dt_unit { - ($name:ident, $storage:ident, $value:expr, $docs:expr) => { - #[doc=$docs] - #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] - pub struct $name($storage); - - impl $name { - /// Gets the numeric value for this component. - pub const fn number(self) -> $storage { - self.0 - } - - /// Creates a new value at 0. - pub const fn zero() -> $name { - Self(0) - } - } - - impl TryFrom<$storage> for $name { - type Error = RangeError; - - fn try_from(input: $storage) -> Result { - if input > $value { - Err(RangeError { - field: "$name", - min: 0, - max: $value, - value: input as i32, - }) - } else { - Ok(Self(input)) - } - } - } - - impl TryFrom for $name { - type Error = RangeError; - - fn try_from(input: usize) -> Result { - if input > $value { - Err(RangeError { - field: "$name", - min: 0, - max: $value, - value: input as i32, - }) - } else { - Ok(Self(input as $storage)) - } - } - } - - impl From<$name> for $storage { - fn from(input: $name) -> Self { - input.0 - } - } - - impl From<$name> for usize { - fn from(input: $name) -> Self { - input.0 as Self - } - } - - impl $name { - /// Attempts to add two values. - /// Returns `Some` if the sum is within bounds. - /// Returns `None` if the sum is out of bounds. - pub fn try_add(self, other: $storage) -> Option { - let sum = self.0.saturating_add(other); - if sum > $value { - None - } else { - Some(Self(sum)) - } - } - - /// Attempts to subtract two values. - /// Returns `Some` if the difference is within bounds. - /// Returns `None` if the difference is out of bounds. - pub fn try_sub(self, other: $storage) -> Option { - self.0.checked_sub(other).map(Self) - } - - /// Returns whether the value is zero. - #[inline] - pub fn is_zero(self) -> bool { - self.0 == 0 - } - } - }; -} - -dt_unit!( - IsoHour, - u8, - 24, - "An ISO-8601 hour component, for use with ISO calendars. - -Must be within inclusive bounds `[0, 24]`. The value could be equal to 24 to -denote the end of a day, with the writing 24:00:00. It corresponds to the same -time as the next day at 00:00:00." -); - -dt_unit!( - IsoMinute, - u8, - 60, - "An ISO-8601 minute component, for use with ISO calendars. - -Must be within inclusive bounds `[0, 60]`. The value could be equal to 60 to -denote the end of an hour, with the writing 12:60:00. This example corresponds -to the same time as 13:00:00. This is an extension to ISO 8601." -); - -dt_unit!( - IsoSecond, - u8, - 61, - "An ISO-8601 second component, for use with ISO calendars. - -Must be within inclusive bounds `[0, 61]`. `60` accommodates for leap seconds. - -The value could also be equal to 60 or 61, to indicate the end of a leap second, -with the writing `23:59:61.000000000Z` or `23:59:60.000000000Z`. These examples, -if used with this goal, would correspond to the same time as the next day, at -time `00:00:00.000000000Z`. This is an extension to ISO 8601." -); - -dt_unit!( - NanoSecond, - u32, - 999_999_999, - "A fractional second component, stored as nanoseconds. - -Must be within inclusive bounds `[0, 999_999_999]`." -); - -#[test] -fn test_iso_hour_arithmetic() { - const HOUR_MAX: u8 = 24; - const HOUR_VALUE: u8 = 5; - let hour = IsoHour(HOUR_VALUE); - - // middle of bounds - assert_eq!( - hour.try_add(HOUR_VALUE - 1), - Some(IsoHour(HOUR_VALUE + (HOUR_VALUE - 1))) - ); - assert_eq!( - hour.try_sub(HOUR_VALUE - 1), - Some(IsoHour(HOUR_VALUE - (HOUR_VALUE - 1))) - ); - - // edge of bounds - assert_eq!(hour.try_add(HOUR_MAX - HOUR_VALUE), Some(IsoHour(HOUR_MAX))); - assert_eq!(hour.try_sub(HOUR_VALUE), Some(IsoHour(0))); - - // out of bounds - assert_eq!(hour.try_add(1 + HOUR_MAX - HOUR_VALUE), None); - assert_eq!(hour.try_sub(1 + HOUR_VALUE), None); -} - -#[test] -fn test_iso_minute_arithmetic() { - const MINUTE_MAX: u8 = 60; - const MINUTE_VALUE: u8 = 5; - let minute = IsoMinute(MINUTE_VALUE); - - // middle of bounds - assert_eq!( - minute.try_add(MINUTE_VALUE - 1), - Some(IsoMinute(MINUTE_VALUE + (MINUTE_VALUE - 1))) - ); - assert_eq!( - minute.try_sub(MINUTE_VALUE - 1), - Some(IsoMinute(MINUTE_VALUE - (MINUTE_VALUE - 1))) - ); - - // edge of bounds - assert_eq!( - minute.try_add(MINUTE_MAX - MINUTE_VALUE), - Some(IsoMinute(MINUTE_MAX)) - ); - assert_eq!(minute.try_sub(MINUTE_VALUE), Some(IsoMinute(0))); - - // out of bounds - assert_eq!(minute.try_add(1 + MINUTE_MAX - MINUTE_VALUE), None); - assert_eq!(minute.try_sub(1 + MINUTE_VALUE), None); -} - -#[test] -fn test_iso_second_arithmetic() { - const SECOND_MAX: u8 = 61; - const SECOND_VALUE: u8 = 5; - let second = IsoSecond(SECOND_VALUE); - - // middle of bounds - assert_eq!( - second.try_add(SECOND_VALUE - 1), - Some(IsoSecond(SECOND_VALUE + (SECOND_VALUE - 1))) - ); - assert_eq!( - second.try_sub(SECOND_VALUE - 1), - Some(IsoSecond(SECOND_VALUE - (SECOND_VALUE - 1))) - ); - - // edge of bounds - assert_eq!( - second.try_add(SECOND_MAX - SECOND_VALUE), - Some(IsoSecond(SECOND_MAX)) - ); - assert_eq!(second.try_sub(SECOND_VALUE), Some(IsoSecond(0))); - - // out of bounds - assert_eq!(second.try_add(1 + SECOND_MAX - SECOND_VALUE), None); - assert_eq!(second.try_sub(1 + SECOND_VALUE), None); -} - -#[test] -fn test_iso_nano_second_arithmetic() { - const NANO_SECOND_MAX: u32 = 999_999_999; - const NANO_SECOND_VALUE: u32 = 5; - let nano_second = NanoSecond(NANO_SECOND_VALUE); - - // middle of bounds - assert_eq!( - nano_second.try_add(NANO_SECOND_VALUE - 1), - Some(NanoSecond(NANO_SECOND_VALUE + (NANO_SECOND_VALUE - 1))) - ); - assert_eq!( - nano_second.try_sub(NANO_SECOND_VALUE - 1), - Some(NanoSecond(NANO_SECOND_VALUE - (NANO_SECOND_VALUE - 1))) - ); - - // edge of bounds - assert_eq!( - nano_second.try_add(NANO_SECOND_MAX - NANO_SECOND_VALUE), - Some(NanoSecond(NANO_SECOND_MAX)) - ); - assert_eq!(nano_second.try_sub(NANO_SECOND_VALUE), Some(NanoSecond(0))); - - // out of bounds - assert_eq!( - nano_second.try_add(1 + NANO_SECOND_MAX - NANO_SECOND_VALUE), - None - ); - assert_eq!(nano_second.try_sub(1 + NANO_SECOND_VALUE), None); -} - -/// A representation of a time in hours, minutes, seconds, and nanoseconds -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[allow(clippy::exhaustive_structs)] // this type is stable -pub struct Time { - /// 0-based hour. - pub hour: IsoHour, - - /// 0-based minute. - pub minute: IsoMinute, - - /// 0-based second. - pub second: IsoSecond, - - /// Fractional second - pub nanosecond: NanoSecond, -} - -impl Time { - /// Construct a new [`Time`], without validating that all components are in range - pub const fn new( - hour: IsoHour, - minute: IsoMinute, - second: IsoSecond, - nanosecond: NanoSecond, - ) -> Self { - Self { - hour, - minute, - second, - nanosecond, - } - } - - /// Construct a new [`Time`] representing midnight (00:00.000) - pub const fn midnight() -> Self { - Self { - hour: IsoHour::zero(), - minute: IsoMinute::zero(), - second: IsoSecond::zero(), - nanosecond: NanoSecond::zero(), - } - } - - /// Construct a new [`Time`], whilst validating that all components are in range - pub fn try_new(hour: u8, minute: u8, second: u8, nanosecond: u32) -> Result { - Ok(Self { - hour: hour.try_into()?, - minute: minute.try_into()?, - second: second.try_into()?, - nanosecond: nanosecond.try_into()?, - }) - } -} - /// A weekday in a 7-day week, according to ISO-8601. /// /// The discriminant values correspond to ISO-8601 weekday numbers (Monday = 1, Sunday = 7). diff --git a/components/datetime/README.md b/components/datetime/README.md index 4710bf253bd..7a59bd04ce6 100644 --- a/components/datetime/README.md +++ b/components/datetime/README.md @@ -25,8 +25,8 @@ The formatters accept input types from the [`calendar`](icu_calendar) and [`timezone`](icu_timezone) crates: 1. [`Date`](icu_calendar::Date) -2. [`DateTime`](icu_calendar::DateTime) -3. [`Time`](icu_calendar::Time) +2. [`DateTime`](icu_timezone::DateTime) +3. [`Time`](icu_timezone::Time) 4. [`UtcOffset`](icu_timezone::UtcOffset) 5. [`TimeZoneInfo`](icu_timezone::TimeZoneInfo) 6. [`ZonedDateTime`](icu_timezone::ZonedDateTime) @@ -49,10 +49,11 @@ If formatting times and time zones without dates, consider using [`TimeFormatter ## Examples ```rust -use icu::calendar::{Date, DateTime, Time}; +use icu::calendar::Date; use icu::datetime::fieldsets; use icu::datetime::DateTimeFormatter; use icu::locale::{locale, Locale}; +use icu::timezone::{DateTime, Time}; use writeable::assert_writeable_eq; // Field set for year, month, day, hour, and minute with a medium length: diff --git a/components/datetime/benches/datetime.rs b/components/datetime/benches/datetime.rs index 789378423de..7e5aba02366 100644 --- a/components/datetime/benches/datetime.rs +++ b/components/datetime/benches/datetime.rs @@ -7,9 +7,9 @@ mod fixtures; use criterion::{criterion_group, criterion_main, Criterion}; use icu_datetime::{fieldsets::enums::CompositeFieldSet, FixedCalendarDateTimeFormatter}; -use icu_calendar::{Date, DateTime, Gregorian, Time}; +use icu_calendar::{Date, Gregorian}; use icu_locale_core::Locale; -use icu_timezone::{TimeZoneInfo, ZoneVariant, ZonedDateTime}; +use icu_timezone::{DateTime, Time, TimeZoneInfo, ZoneVariant, ZonedDateTime}; use writeable::Writeable; #[path = "../tests/mock.rs"] diff --git a/components/datetime/examples/work_log.rs b/components/datetime/examples/work_log.rs index 85fd9d50646..5b9765bd0e4 100644 --- a/components/datetime/examples/work_log.rs +++ b/components/datetime/examples/work_log.rs @@ -9,9 +9,10 @@ icu_benchmark_macros::instrument!(); use icu_benchmark_macros::println; -use icu_calendar::{Date, DateTime, Time}; +use icu_calendar::Date; use icu_datetime::{fieldsets::YMDT, FixedCalendarDateTimeFormatter}; use icu_locale_core::locale; +use icu_timezone::{DateTime, Time}; const DATES_ISO: &[(i32, u8, u8, u8, u8, u8)] = &[ (2001, 9, 8, 18, 46, 40), diff --git a/components/datetime/src/combo.rs b/components/datetime/src/combo.rs index 4f1ad637f9e..1e60c6d33f0 100644 --- a/components/datetime/src/combo.rs +++ b/components/datetime/src/combo.rs @@ -52,7 +52,7 @@ use crate::{provider::neo::*, scaffold::*}; /// use icu::datetime::fieldsets::{Combo, ET, L}; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::locale::locale; -/// use icu::timezone::IxdtfParser; +/// use icu::timezone::{IxdtfParser, ZonedDateTime}; /// use writeable::assert_writeable_eq; /// /// // Note: Combo type can be elided, but it is shown here for demonstration @@ -106,7 +106,7 @@ use crate::{provider::neo::*, scaffold::*}; /// use icu::datetime::fieldsets::T; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::locale::locale; -/// use icu::timezone::IxdtfParser; +/// use icu::timezone::{IxdtfParser, ZonedDateTime}; /// use writeable::assert_writeable_eq; /// /// let formatter = FixedCalendarDateTimeFormatter::try_new( diff --git a/components/datetime/src/dynamic.rs b/components/datetime/src/dynamic.rs index 63ec1e5b667..de61947cdc3 100644 --- a/components/datetime/src/dynamic.rs +++ b/components/datetime/src/dynamic.rs @@ -28,11 +28,12 @@ //! Format with the time display depending on a runtime boolean: //! //! ``` -//! use icu::calendar::{Date, DateTime, Time}; +//! use icu::calendar::Date; //! use icu::datetime::fieldsets; //! use icu::datetime::fieldsets::enums::CompositeDateTimeFieldSet; //! use icu::datetime::DateTimeFormatter; //! use icu::locale::locale; +//! use icu::timezone::{DateTime, Time}; //! use writeable::Writeable; //! //! fn get_field_set(should_display_time: bool) -> CompositeDateTimeFieldSet { diff --git a/components/datetime/src/fieldsets.rs b/components/datetime/src/fieldsets.rs index 6d515868d51..70073fcf037 100644 --- a/components/datetime/src/fieldsets.rs +++ b/components/datetime/src/fieldsets.rs @@ -64,13 +64,14 @@ use crate::{ }; use enums::*; use icu_calendar::{ - types::{ - DayOfMonth, IsoHour, IsoMinute, IsoSecond, IsoWeekday, MonthInfo, NanoSecond, YearInfo, - }, - Date, Iso, Time, + types::{DayOfMonth, IsoWeekday, MonthInfo, YearInfo}, + Date, Iso, }; use icu_provider::marker::NeverMarker; -use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_timezone::{ + types::{IsoHour, IsoMinute, IsoSecond, NanoSecond}, + Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant, +}; /// 🚧 \[Experimental\] Types for dealing with serialization of semantic skeletons. /// @@ -559,10 +560,11 @@ macro_rules! impl_date_marker { /// In [`DateTimeFormatter`](crate::neo::DateTimeFormatter): /// /// ``` - /// use icu::calendar::{DateTime, Date, Time}; + /// use icu::calendar::Date; /// use icu::datetime::DateTimeFormatter; #[doc = concat!("use icu::datetime::fieldsets::", stringify!($type_time), ";")] /// use icu::locale::locale; + /// use icu::timezone::{DateTime, Time}; /// use writeable::assert_writeable_eq; /// #[doc = concat!("let fmt = DateTimeFormatter::try_new(")] @@ -581,11 +583,12 @@ macro_rules! impl_date_marker { /// In [`FixedCalendarDateTimeFormatter`](crate::neo::FixedCalendarDateTimeFormatter): /// /// ``` - /// use icu::calendar::{DateTime, Date, Time}; + /// use icu::calendar::Date; /// use icu::calendar::Gregorian; /// use icu::datetime::FixedCalendarDateTimeFormatter; #[doc = concat!("use icu::datetime::fieldsets::", stringify!($type_time), ";")] /// use icu::locale::locale; + /// use icu::timezone::{DateTime, Time}; /// use writeable::assert_writeable_eq; /// #[doc = concat!("let fmt = FixedCalendarDateTimeFormatter::try_new(")] @@ -750,7 +753,7 @@ macro_rules! impl_time_marker { /// # Examples /// /// ``` - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::TimeFormatter; #[doc = concat!("use icu::datetime::fieldsets::", stringify!($type), ";")] /// use icu::locale::locale; @@ -860,8 +863,8 @@ macro_rules! impl_zone_marker { /// # Examples /// /// ``` - /// use icu::calendar::{Date, Time}; - /// use icu::timezone::{TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; + /// use icu::calendar::Date; + /// use icu::timezone::{Time, TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; /// use icu::datetime::TimeFormatter; #[doc = concat!("use icu::datetime::fieldsets::", stringify!($type), ";")] /// use icu::locale::locale; @@ -1085,7 +1088,7 @@ impl_time_marker!( /// or [`DateTimeFormatterPreferences`]. /// /// ``` - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::fieldsets::T; /// use icu::datetime::TimeFormatter; /// use icu::locale::locale; @@ -1138,7 +1141,7 @@ impl_time_marker!( /// Hour cycles `h11` and `h24` are supported, too: /// /// ``` - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::fieldsets::T; /// use icu::datetime::TimeFormatter; /// use icu::locale::locale; @@ -1184,8 +1187,8 @@ impl_zone_marker!( /// to the location format for long lengths: /// /// ``` - /// use icu::calendar::{Date, Time}; - /// use icu::timezone::{IxdtfParser, TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; + /// use icu::calendar::Date; + /// use icu::timezone::{IxdtfParser, Time, TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; /// use icu::calendar::Gregorian; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::datetime::fieldsets::{Z, Zs}; @@ -1227,11 +1230,11 @@ impl_zone_marker!( /// For example, [`TimeZoneInfo`] cannot be formatted. /// /// ```compile_fail,E0271 - /// use icu::calendar::{DateTime, Date, Iso, Time}; + /// use icu::calendar::{Date, Iso}; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::datetime::fieldsets::Z; - /// use icu::timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; /// use icu::locale::locale; + /// use icu::timezone::{DateTime, Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; /// use tinystr::tinystr; /// use writeable::assert_writeable_eq; /// @@ -1269,11 +1272,11 @@ impl_zone_marker!( /// For example, [`TimeZoneInfo`] cannot be formatted. /// /// ```compile_fail,E0271 - /// use icu::calendar::{Date, DateTime, Iso, Time}; + /// use icu::calendar::{Date, Iso}; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::datetime::fieldsets::T; /// use icu::locale::locale; - /// use icu::timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; + /// use icu::timezone::{DateTime, Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; /// use tinystr::tinystr; /// use writeable::assert_writeable_eq; /// @@ -1308,10 +1311,10 @@ impl_zone_marker!( /// All shapes of time zones can be formatted with this style. /// /// ``` - /// use icu::calendar::{Date, Time}; + /// use icu::calendar::Date; /// use icu::datetime::TimeFormatter; /// use icu::datetime::fieldsets::O; - /// use icu::timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; + /// use icu::timezone::{Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; /// use tinystr::tinystr; /// use icu::locale::locale; /// use writeable::assert_writeable_eq; @@ -1374,8 +1377,8 @@ impl_zone_marker!( /// When a display name is unavailable, falls back to the location format: /// /// ``` - /// use icu::calendar::{Date, Time}; - /// use icu::timezone::{IxdtfParser, TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; + /// use icu::calendar::Date; + /// use icu::timezone::{IxdtfParser, Time, TimeZoneBcp47Id, TimeZoneInfo, UtcOffset, ZoneVariant}; /// use icu::calendar::Gregorian; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::datetime::fieldsets::Vs; @@ -1403,8 +1406,8 @@ impl_zone_marker!( /// Can also fall back to the UTC offset: /// /// ``` - /// use icu::calendar::{Date, Time}; - /// use icu::timezone::{TimeZoneInfo, UtcOffset, TimeZoneIdMapper, TimeZoneBcp47Id}; + /// use icu::calendar::Date; + /// use icu::timezone::{Time, TimeZoneInfo, UtcOffset, TimeZoneIdMapper, TimeZoneBcp47Id}; /// use icu::datetime::TimeFormatter; /// use icu::datetime::fieldsets::Vs; /// use icu::datetime::DateTimeWriteError; diff --git a/components/datetime/src/format/time_zone.rs b/components/datetime/src/format/time_zone.rs index fe88e716960..8979175601c 100644 --- a/components/datetime/src/format/time_zone.rs +++ b/components/datetime/src/format/time_zone.rs @@ -9,10 +9,10 @@ use crate::provider::time_zones::MetazoneId; use crate::{input::ExtractedInput, provider::fields::FieldLength}; use core::fmt; use fixed_decimal::SignedFixedDecimal; -use icu_calendar::{Date, Iso, Time}; +use icu_calendar::{Date, Iso}; use icu_decimal::FixedDecimalFormatter; use icu_timezone::provider::EPOCH; -use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_timezone::{Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; use writeable::Writeable; impl crate::provider::time_zones::MetazonePeriodV1<'_> { diff --git a/components/datetime/src/input.rs b/components/datetime/src/input.rs index 9f7c87a9707..330a12145cd 100644 --- a/components/datetime/src/input.rs +++ b/components/datetime/src/input.rs @@ -7,14 +7,15 @@ use crate::scaffold::{DateInputMarkers, GetField, TimeMarkers, ZoneMarkers}; use icu_calendar::types::DayOfYearInfo; -use icu_calendar::{Date, Iso, Time}; +use icu_calendar::{Date, Iso}; use icu_timezone::scaffold::IntoOption; -use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_timezone::{ + types::{IsoHour, IsoMinute, IsoSecond, NanoSecond}, + Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant, +}; // TODO(#2630) fix up imports to directly import from icu_calendar -pub(crate) use icu_calendar::types::{ - DayOfMonth, IsoHour, IsoMinute, IsoSecond, IsoWeekday, MonthInfo, NanoSecond, YearInfo, -}; +pub(crate) use icu_calendar::types::{DayOfMonth, IsoWeekday, MonthInfo, YearInfo}; #[derive(Debug, Copy, Clone)] pub(crate) struct ExtractedInput { diff --git a/components/datetime/src/lib.rs b/components/datetime/src/lib.rs index a5cc30bc9a2..8b226f3ebb0 100644 --- a/components/datetime/src/lib.rs +++ b/components/datetime/src/lib.rs @@ -25,8 +25,8 @@ //! [`timezone`](icu_timezone) crates: //! //! 1. [`Date`](icu_calendar::Date) -//! 2. [`DateTime`](icu_calendar::DateTime) -//! 3. [`Time`](icu_calendar::Time) +//! 2. [`DateTime`](icu_timezone::DateTime) +//! 3. [`Time`](icu_timezone::Time) //! 4. [`UtcOffset`](icu_timezone::UtcOffset) //! 5. [`TimeZoneInfo`](icu_timezone::TimeZoneInfo) //! 6. [`ZonedDateTime`](icu_timezone::ZonedDateTime) @@ -49,10 +49,11 @@ //! # Examples //! //! ``` -//! use icu::calendar::{Date, DateTime, Time}; +//! use icu::calendar::Date; //! use icu::datetime::fieldsets; //! use icu::datetime::DateTimeFormatter; //! use icu::locale::{locale, Locale}; +//! use icu::timezone::{DateTime, Time}; //! use writeable::assert_writeable_eq; //! //! // Field set for year, month, day, hour, and minute with a medium length: diff --git a/components/datetime/src/neo.rs b/components/datetime/src/neo.rs index fc390910461..f0cabb12364 100644 --- a/components/datetime/src/neo.rs +++ b/components/datetime/src/neo.rs @@ -344,7 +344,7 @@ where /// A time cannot be passed into the formatter when a date is expected: /// /// ```compile_fail - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::calendar::Gregorian; /// use icu::datetime::FixedCalendarDateTimeFormatter; /// use icu::datetime::fieldsets::YMD; @@ -358,7 +358,7 @@ where /// .unwrap(); /// /// // the trait `GetField` - /// // is not implemented for `icu::icu_calendar::Time` + /// // is not implemented for `icu::icu_timezone::Time` /// formatter.format(&Time::try_new(0, 0, 0, 0).unwrap()); /// ``` pub fn format(&self, input: &I) -> FormattedDateTime @@ -578,7 +578,7 @@ where /// A time cannot be passed into the formatter when a date is expected: /// /// ```compile_fail - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::DateTimeFormatter; /// use icu::datetime::fieldsets::YMD; /// use icu::locale::locale; @@ -590,7 +590,7 @@ where /// .unwrap(); /// /// // the trait `GetField` - /// // is not implemented for `icu::icu_calendar::Time` + /// // is not implemented for `icu::icu_timezone::Time` /// formatter.format_same_calendar(&Time::try_new(0, 0, 0, 0).unwrap()); /// ``` pub fn format_same_calendar( @@ -639,7 +639,7 @@ where /// A time cannot be passed into the formatter when a date is expected: /// /// ```compile_fail - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::DateTimeFormatter; /// use icu::datetime::fieldsets::YMD; /// use icu::locale::locale; @@ -651,7 +651,7 @@ where /// .unwrap(); /// /// // the trait `GetField` - /// // is not implemented for `icu::icu_calendar::Time` + /// // is not implemented for `icu::icu_timezone::Time` /// formatter.format_any_calendar(&Time::try_new(0, 0, 0, 0).unwrap()); /// ``` pub fn format_any_calendar<'a, I>(&'a self, datetime: &I) -> FormattedDateTime<'a> diff --git a/components/datetime/src/options/mod.rs b/components/datetime/src/options/mod.rs index c34796ffa64..b22d303de51 100644 --- a/components/datetime/src/options/mod.rs +++ b/components/datetime/src/options/mod.rs @@ -320,7 +320,7 @@ impl IntoOption for YearStyle { /// # Examples /// /// ``` -/// use icu::calendar::Time; +/// use icu::timezone::Time; /// use icu::datetime::fieldsets::T; /// use icu::datetime::options::FractionalSecondDigits; /// use icu::datetime::options::TimePrecision; @@ -459,7 +459,7 @@ impl IntoOption for TimePrecision { /// /// ``` /// use icu::calendar::Gregorian; -/// use icu::calendar::Time; +/// use icu::timezone::Time; /// use icu::datetime::fieldsets::T; /// use icu::datetime::options::FractionalSecondDigits; /// use icu::datetime::options::TimePrecision; diff --git a/components/datetime/src/parts.rs b/components/datetime/src/parts.rs index 831b657346f..d1832df2dd9 100644 --- a/components/datetime/src/parts.rs +++ b/components/datetime/src/parts.rs @@ -8,7 +8,7 @@ //! //! ``` //! use icu::calendar::Gregorian; -//! use icu::calendar::{Date, Time}; +//! use icu::calendar::Date; //! use icu::datetime::parts as datetime_parts; //! use icu::datetime::fieldsets; //! use icu::datetime::options::FractionalSecondDigits; @@ -16,7 +16,7 @@ //! use icu::datetime::DateTimeFormatter; //! use icu::decimal::parts as decimal_parts; //! use icu::locale::locale; -//! use icu::timezone::IxdtfParser; +//! use icu::timezone::{IxdtfParser, Time}; //! use writeable::assert_writeable_parts_eq; //! //! let dtf = DateTimeFormatter::try_new( diff --git a/components/datetime/src/pattern/formatter.rs b/components/datetime/src/pattern/formatter.rs index 1e62fe9db8f..80586b42130 100644 --- a/components/datetime/src/pattern/formatter.rs +++ b/components/datetime/src/pattern/formatter.rs @@ -107,7 +107,7 @@ where /// /// ``` /// use icu::calendar::Gregorian; - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::fieldsets::enums::TimeFieldSet; /// use icu::datetime::pattern::DateTimePattern; /// use icu::datetime::pattern::TypedDateTimeNames; @@ -235,8 +235,9 @@ impl TryWriteable for FormattedDateTimePattern<'_> { #[cfg(feature = "compiled_data")] mod tests { use super::super::*; - use icu_calendar::{Date, DateTime, Gregorian, Time}; + use icu_calendar::{Date, Gregorian}; use icu_locale_core::locale; + use icu_timezone::{DateTime, Time}; use writeable::assert_try_writeable_eq; #[test] diff --git a/components/datetime/src/pattern/names.rs b/components/datetime/src/pattern/names.rs index ad941191f3d..e3f2de57bd8 100644 --- a/components/datetime/src/pattern/names.rs +++ b/components/datetime/src/pattern/names.rs @@ -391,13 +391,14 @@ size_test!( /// /// ``` /// use icu::calendar::Gregorian; -/// use icu::calendar::{DateTime, Date, Time}; +/// use icu::calendar::Date; /// use icu::datetime::pattern::TypedDateTimeNames; /// use icu::datetime::pattern::DateTimePattern; /// use icu::datetime::pattern::MonthNameLength; /// use icu::datetime::pattern::WeekdayNameLength; /// use icu::datetime::pattern::DayPeriodNameLength; /// use icu::locale::locale; +/// use icu::timezone::{DateTime, Time}; /// use writeable::assert_try_writeable_eq; /// /// // Create an instance that can format abbreviated month, weekday, and day period names: @@ -424,14 +425,14 @@ size_test!( /// /// ``` /// use icu::calendar::Gregorian; -/// use icu::calendar::{Date, Time}; +/// use icu::calendar::Date; /// use icu::datetime::DateTimeWriteError; /// use icu::datetime::parts; /// use icu::datetime::pattern::TypedDateTimeNames; /// use icu::datetime::pattern::{DateTimePattern, PatternLoadError}; /// use icu::datetime::fieldsets::enums::CompositeFieldSet; /// use icu::locale::locale; -/// use icu::timezone::{TimeZoneInfo, IxdtfParser}; +/// use icu::timezone::{Time, TimeZoneInfo, IxdtfParser, ZonedDateTime}; /// use icu_provider_adapters::empty::EmptyDataProvider; /// use writeable::{Part, assert_try_writeable_parts_eq}; /// @@ -494,14 +495,13 @@ size_test!( /// /// ``` /// use icu::calendar::Gregorian; -/// use icu::calendar::DateTime; /// use icu::datetime::DateTimeWriteError; /// use icu::datetime::parts; /// use icu::datetime::pattern::TypedDateTimeNames; /// use icu::datetime::pattern::DateTimePattern; /// use icu::datetime::fieldsets::O; /// use icu::locale::locale; -/// use icu::timezone::TimeZoneInfo; +/// use icu::timezone::{DateTime, TimeZoneInfo}; /// use writeable::{Part, assert_try_writeable_parts_eq}; /// /// // Create an instance that can format abbreviated month, weekday, and day period names: @@ -1483,7 +1483,7 @@ impl TypedDateTimeNames { /// # Examples /// /// ``` - /// use icu::calendar::Time; + /// use icu::timezone::Time; /// use icu::datetime::fieldsets::enums::TimeFieldSet; /// use icu::datetime::pattern::DateTimePattern; /// use icu::datetime::pattern::TypedDateTimeNames; @@ -1581,10 +1581,11 @@ impl TypedDateTimeNames { /// # Examples /// /// ``` - /// use icu::calendar::{Date, DateTime, Gregorian, Time}; + /// use icu::calendar::{Date, Gregorian}; /// use icu::datetime::pattern::DateTimePattern; /// use icu::datetime::pattern::TypedDateTimeNames; /// use icu::locale::locale; + /// use icu::timezone::{DateTime, Time}; /// use writeable::assert_try_writeable_eq; /// /// let mut names = @@ -1653,12 +1654,13 @@ impl TypedDateTimeNames { /// /// ``` /// use icu::calendar::Gregorian; - /// use icu::calendar::{Date, DateTime, Time}; + /// use icu::calendar::Date; /// use icu::datetime::pattern::TypedDateTimeNames; /// use icu::datetime::pattern::MonthNameLength; /// use icu::datetime::fieldsets::enums::{DateFieldSet, CompositeDateTimeFieldSet}; /// use icu::datetime::pattern::DateTimePattern; /// use icu::locale::locale; + /// use icu::timezone::{DateTime, Time}; /// use writeable::assert_try_writeable_eq; /// /// // Create an instance that can format abbreviated month names: @@ -2405,7 +2407,7 @@ impl RawDateTimeNamesBorrowed<'_> { &self, field_symbol: fields::DayPeriod, field_length: FieldLength, - hour: input::IsoHour, + hour: icu_timezone::types::IsoHour, is_top_of_hour: bool, ) -> Result<&str, GetNameForDayPeriodError> { use fields::DayPeriod::NoonMidnight; diff --git a/components/datetime/src/pattern/pattern.rs b/components/datetime/src/pattern/pattern.rs index 3994507648a..acfdbec7c99 100644 --- a/components/datetime/src/pattern/pattern.rs +++ b/components/datetime/src/pattern/pattern.rs @@ -77,7 +77,7 @@ size_test!(DateTimePattern, date_time_pattern_size, 32); /// Check the hour cycle of a resolved pattern: /// /// ``` -/// use icu::calendar::Time; +/// use icu::timezone::Time; /// use icu::datetime::provider::fields::components; /// use icu::datetime::fieldsets::T; /// use icu::datetime::pattern::DateTimePattern; diff --git a/components/datetime/src/scaffold/calendar.rs b/components/datetime/src/scaffold/calendar.rs index 945ac7055b5..1bc52e12268 100644 --- a/components/datetime/src/scaffold/calendar.rs +++ b/components/datetime/src/scaffold/calendar.rs @@ -15,12 +15,10 @@ use icu_calendar::cal::{ Buddhist, Coptic, Dangi, Ethiopian, Gregorian, Hebrew, Indian, IslamicCivil, IslamicObservational, IslamicTabular, IslamicUmmAlQura, Japanese, JapaneseExtended, Persian, }; -use icu_calendar::{ - any_calendar::IntoAnyCalendar, AnyCalendar, AsCalendar, Calendar, Date, DateTime, Ref, Time, -}; +use icu_calendar::{any_calendar::IntoAnyCalendar, AnyCalendar, AsCalendar, Calendar, Date, Ref}; use icu_provider::marker::NeverMarker; use icu_provider::prelude::*; -use icu_timezone::{TimeZoneInfo, TimeZoneModel, UtcOffset, ZonedDateTime}; +use icu_timezone::{DateTime, Time, TimeZoneInfo, TimeZoneModel, UtcOffset, ZonedDateTime}; /// A calendar that can be found in CLDR. /// diff --git a/components/datetime/src/scaffold/dynamic_impls.rs b/components/datetime/src/scaffold/dynamic_impls.rs index eb86647bd4e..331d218251d 100644 --- a/components/datetime/src/scaffold/dynamic_impls.rs +++ b/components/datetime/src/scaffold/dynamic_impls.rs @@ -6,14 +6,14 @@ use super::*; use crate::fieldsets::enums::*; use crate::provider::{neo::*, time_zones::tz, *}; use icu_calendar::{ - types::{ - DayOfMonth, DayOfYearInfo, IsoHour, IsoMinute, IsoSecond, IsoWeekday, MonthInfo, - NanoSecond, YearInfo, - }, - Date, Iso, Time, + types::{DayOfMonth, DayOfYearInfo, IsoWeekday, MonthInfo, YearInfo}, + Date, Iso, }; use icu_provider::marker::NeverMarker; -use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_timezone::{ + types::{IsoHour, IsoMinute, IsoSecond, NanoSecond}, + Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant, +}; impl UnstableSealed for DateFieldSet {} diff --git a/components/datetime/src/scaffold/fieldset_traits.rs b/components/datetime/src/scaffold/fieldset_traits.rs index e59f20be48c..1e60d365fb4 100644 --- a/components/datetime/src/scaffold/fieldset_traits.rs +++ b/components/datetime/src/scaffold/fieldset_traits.rs @@ -11,16 +11,16 @@ use icu_calendar::{ ChineseCacheV1Marker, DangiCacheV1Marker, IslamicObservationalCacheV1Marker, IslamicUmmAlQuraCacheV1Marker, JapaneseErasV1Marker, JapaneseExtendedErasV1Marker, }, - types::{ - DayOfMonth, DayOfYearInfo, IsoHour, IsoMinute, IsoSecond, IsoWeekday, MonthInfo, - NanoSecond, YearInfo, - }, - Date, Iso, Time, + types::{DayOfMonth, DayOfYearInfo, IsoWeekday, MonthInfo, YearInfo}, + Date, Iso, }; use icu_decimal::provider::{DecimalDigitsV1Marker, DecimalSymbolsV2Marker}; use icu_provider::{marker::NeverMarker, prelude::*}; use icu_timezone::scaffold::IntoOption; -use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_timezone::{ + types::{IsoHour, IsoMinute, IsoSecond, NanoSecond}, + Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant, +}; // TODO: Add WeekCalculator and FixedDecimalFormatter optional bindings here @@ -149,8 +149,8 @@ pub trait DateTimeMarkers: UnstableSealed + DateTimeNamesMarker { /// The following types implement this trait: /// /// - [`Date`](icu_calendar::Date) -/// - [`Time`](icu_calendar::Time) -/// - [`DateTime`](icu_calendar::DateTime) +/// - [`Time`](icu_timezone::Time) +/// - [`DateTime`](icu_timezone::DateTime) /// - [`ZonedDateTime`](icu_timezone::ZonedDateTime) /// - [`UtcOffset`](icu_timezone::UtcOffset) /// - [`TimeZoneInfo`](icu_timezone::TimeZoneInfo) diff --git a/components/datetime/src/scaffold/get_field.rs b/components/datetime/src/scaffold/get_field.rs index 6c80bde36d6..77b72a33f9d 100644 --- a/components/datetime/src/scaffold/get_field.rs +++ b/components/datetime/src/scaffold/get_field.rs @@ -3,14 +3,13 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use icu_calendar::{ - types::{ - DayOfMonth, DayOfYearInfo, IsoHour, IsoMinute, IsoSecond, IsoWeekday, MonthInfo, - NanoSecond, YearInfo, - }, - AsCalendar, Calendar, Date, DateTime, Iso, Time, + types::{DayOfMonth, DayOfYearInfo, IsoWeekday, MonthInfo, YearInfo}, + AsCalendar, Calendar, Date, Iso, }; use icu_timezone::{ - TimeZoneBcp47Id, TimeZoneInfo, TimeZoneModel, UtcOffset, ZoneVariant, ZonedDateTime, + types::{IsoHour, IsoMinute, IsoSecond, NanoSecond}, + DateTime, Time, TimeZoneBcp47Id, TimeZoneInfo, TimeZoneModel, UtcOffset, ZoneVariant, + ZonedDateTime, }; use super::UnstableSealed; diff --git a/components/datetime/tests/datetime.rs b/components/datetime/tests/datetime.rs index 61c91d8b32e..9bea63010fd 100644 --- a/components/datetime/tests/datetime.rs +++ b/components/datetime/tests/datetime.rs @@ -13,7 +13,7 @@ use icu_calendar::cal::{ }; use icu_calendar::{ any_calendar::{AnyCalendarKind, IntoAnyCalendar}, - AsCalendar, Calendar, DateTime, + AsCalendar, Calendar, }; use icu_datetime::scaffold::CldrCalendar; use icu_datetime::{fieldsets::enums::*, DateTimeFormatterPreferences}; @@ -28,7 +28,7 @@ use icu_locale_core::{ Locale, }; use icu_provider::prelude::*; -use icu_timezone::{TimeZoneIdMapper, TimeZoneInfo, UtcOffset, ZonedDateTime}; +use icu_timezone::{DateTime, TimeZoneIdMapper, TimeZoneInfo, UtcOffset, ZonedDateTime}; use patterns::{ dayperiods::{DayPeriodExpectation, DayPeriodTests}, time_zones::TimeZoneTests, diff --git a/components/datetime/tests/resolved_components.rs b/components/datetime/tests/resolved_components.rs index 666267ba67b..62194ef8c89 100644 --- a/components/datetime/tests/resolved_components.rs +++ b/components/datetime/tests/resolved_components.rs @@ -2,7 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use icu_calendar::{Date, DateTime, Gregorian, Time}; +use icu_calendar::{Date, Gregorian}; use icu_datetime::{ fieldsets::{self, enums::*}, options::{Alignment, FractionalSecondDigits, TimePrecision, YearStyle}, @@ -11,6 +11,7 @@ use icu_datetime::{ }; use icu_locale_core::Locale; use icu_locale_core::{locale, preferences::extensions::unicode::keywords::HourCycle}; +use icu_timezone::{DateTime, Time}; fn assert_resolved_components( skeleton: CompositeDateTimeFieldSet, diff --git a/components/datetime/tests/simple_test.rs b/components/datetime/tests/simple_test.rs index 178c4c31449..ab30c30d71b 100644 --- a/components/datetime/tests/simple_test.rs +++ b/components/datetime/tests/simple_test.rs @@ -3,13 +3,14 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use icu_calendar::cal::Hebrew; -use icu_calendar::{Date, DateTime, Time}; +use icu_calendar::Date; use icu_datetime::fieldsets::enums::{ CompositeDateTimeFieldSet, DateAndTimeFieldSet, DateFieldSet, }; use icu_datetime::fieldsets::{self, YMD}; use icu_datetime::{DateTimeFormatterPreferences, FixedCalendarDateTimeFormatter}; use icu_locale_core::{locale, Locale}; +use icu_timezone::{DateTime, Time}; use writeable::assert_writeable_eq; const EXPECTED_DATETIME: &[&str] = &[ diff --git a/components/icu/examples/tui.rs b/components/icu/examples/tui.rs index c4f347a43fa..d83c697834f 100644 --- a/components/icu/examples/tui.rs +++ b/components/icu/examples/tui.rs @@ -5,14 +5,14 @@ // An example program making use of a number of ICU components // in a pseudo-real-world application of Textual User Interface. -use icu::calendar::{Date, Gregorian, Time}; +use icu::calendar::{Date, Gregorian}; use icu::locale::locale; use icu::plurals::{PluralCategory, PluralRules}; use icu::timezone::TimeZoneInfo; use icu_collections::codepointinvlist::CodePointInversionListBuilder; use icu_datetime::fieldsets::YMDT; use icu_datetime::FixedCalendarDateTimeFormatter; -use icu_timezone::ZonedDateTime; +use icu_timezone::{Time, ZonedDateTime}; use std::env; fn main() { diff --git a/components/timezone/Cargo.toml b/components/timezone/Cargo.toml index ad4fe0796d7..5cf3eb3e7ac 100644 --- a/components/timezone/Cargo.toml +++ b/components/timezone/Cargo.toml @@ -40,7 +40,7 @@ icu = { path = "../../components/icu", default-features = false } [features] default = ["compiled_data", "ixdtf"] -ixdtf = ["dep:ixdtf"] +ixdtf = ["dep:ixdtf", "icu_calendar/ixdtf"] serde = ["dep:serde", "zerovec/serde", "zerotrie/serde", "tinystr/serde", "icu_provider/serde"] datagen = ["serde", "dep:databake", "zerovec/databake", "zerotrie/databake", "tinystr/databake"] compiled_data = ["dep:icu_timezone_data", "icu_calendar/compiled_data"] diff --git a/components/timezone/README.md b/components/timezone/README.md index 924d840ccc4..7bf3ba6336f 100644 --- a/components/timezone/README.md +++ b/components/timezone/README.md @@ -58,7 +58,8 @@ formats may be unsupported. ## Examples ```rust -use icu::calendar::{Date, Time}; +use icu::calendar::Date; +use icu::timezone::Time; use icu::timezone::TimeZoneBcp47Id; use icu::timezone::TimeZoneIdMapper; use icu::timezone::ZoneVariant; diff --git a/components/timezone/src/ixdtf.rs b/components/timezone/src/ixdtf.rs index a1a4a3e9110..18da5fdf3a0 100644 --- a/components/timezone/src/ixdtf.rs +++ b/components/timezone/src/ixdtf.rs @@ -5,10 +5,12 @@ use crate::{ provider::{names::IanaToBcp47MapV3Marker, ZoneOffsetPeriodV1Marker}, time_zone::models, - InvalidOffsetError, TimeZoneBcp47Id, TimeZoneIdMapper, TimeZoneIdMapperBorrowed, TimeZoneInfo, - UtcOffset, ZoneOffsetCalculator, ZoneOffsets, ZoneVariant, ZonedDateTime, + DateTime, InvalidOffsetError, Time, TimeZoneBcp47Id, TimeZoneIdMapper, + TimeZoneIdMapperBorrowed, TimeZoneInfo, UtcOffset, ZoneOffsetCalculator, ZoneOffsets, + ZoneVariant, ZonedDateTime, }; -use icu_calendar::{AnyCalendarKind, AsCalendar, Calendar, Date, DateError, Iso, RangeError, Time}; +use core::str::FromStr; +use icu_calendar::{AnyCalendarKind, AsCalendar, Calendar, Date, DateError, Iso, RangeError}; use icu_provider::prelude::*; use ixdtf::{ parsers::records::{ @@ -95,6 +97,18 @@ impl From for ParseError { } } +impl From for ParseError { + fn from(value: icu_calendar::ParseError) -> Self { + match value { + icu_calendar::ParseError::MissingFields => Self::MissingFields, + icu_calendar::ParseError::Range(r) => Self::Range(r), + icu_calendar::ParseError::Syntax(s) => Self::Syntax(s), + icu_calendar::ParseError::UnknownCalendar => Self::UnknownCalendar, + _ => unreachable!(), + } + } +} + impl UtcOffset { fn try_from_utc_offset_record(record: UtcOffsetRecord) -> Result { let hour_seconds = i32::from(record.hour) * 3600; @@ -839,6 +853,169 @@ impl IxdtfParser { } } +impl DateTime { + /// Creates a [`DateTime`] in the ISO-8601 calendar from an IXDTF syntax string. + /// + /// Ignores any calendar annotations in the string. + /// + /// ✨ *Enabled with the `ixdtf` Cargo feature.* + /// + /// # Examples + /// + /// ``` + /// use icu::timezone::DateTime; + /// + /// let datetime = + /// DateTime::try_iso_from_str("2024-07-17T16:01:17.045").unwrap(); + /// + /// assert_eq!(datetime.date.year().era_year_or_extended(), 2024); + /// assert_eq!( + /// datetime.date.month().standard_code, + /// icu::calendar::types::MonthCode(tinystr::tinystr!(4, "M07")) + /// ); + /// assert_eq!(datetime.date.day_of_month().0, 17); + /// + /// assert_eq!(datetime.time.hour.number(), 16); + /// assert_eq!(datetime.time.minute.number(), 1); + /// assert_eq!(datetime.time.second.number(), 17); + /// assert_eq!(datetime.time.nanosecond.number(), 45000000); + /// ``` + pub fn try_iso_from_str(ixdtf_str: &str) -> Result { + Self::try_iso_from_utf8(ixdtf_str.as_bytes()) + } + + /// Creates a [`DateTime`] in the ISO-8601 calendar from an IXDTF syntax string. + /// + /// ✨ *Enabled with the `ixdtf` Cargo feature.* + /// + /// See [`Self::try_iso_from_str()`]. + pub fn try_iso_from_utf8(ixdtf_str: &[u8]) -> Result { + let ixdtf_record = ixdtf::parsers::IxdtfParser::from_utf8(ixdtf_str).parse()?; + Self::try_from_ixdtf_record(&ixdtf_record) + } + + fn try_from_ixdtf_record(ixdtf_record: &IxdtfParseRecord) -> Result { + let date_record = ixdtf_record.date.ok_or(ParseError::MissingFields)?; + let date = Date::try_new_iso(date_record.year, date_record.month, date_record.day)?; + let time = Time::try_from_ixdtf_record(ixdtf_record)?; + Ok(Self { date, time }) + } +} + +impl FromStr for DateTime { + type Err = ParseError; + fn from_str(ixdtf_str: &str) -> Result { + Self::try_iso_from_str(ixdtf_str) + } +} + +impl DateTime { + /// Creates a [`DateTime`] in any calendar from an IXDTF syntax string with compiled data. + /// + /// # Examples + /// + /// ``` + /// use icu::calendar::cal::Hebrew; + /// use icu::timezone::DateTime; + /// + /// let datetime = + /// DateTime::try_from_str("2024-07-17T16:01:17.045[u-ca=hebrew]", Hebrew).unwrap(); + /// + /// assert_eq!(datetime.date.year().era_year_or_extended(), 5784); + /// assert_eq!( + /// datetime.date.month().standard_code, + /// icu::calendar::types::MonthCode(tinystr::tinystr!(4, "M10")) + /// ); + /// assert_eq!(datetime.date.day_of_month().0, 11); + /// + /// assert_eq!(datetime.time.hour.number(), 16); + /// assert_eq!(datetime.time.minute.number(), 1); + /// assert_eq!(datetime.time.second.number(), 17); + /// assert_eq!(datetime.time.nanosecond.number(), 45000000); + /// ``` + pub fn try_from_str(ixdtf_str: &str, calendar: A) -> Result { + Self::try_from_utf8(ixdtf_str.as_bytes(), calendar) + } + + /// Creates a [`DateTime`] in any calendar from an IXDTF syntax string with compiled data. + /// + /// See [`Self::try_from_str()`]. + pub fn try_from_utf8(ixdtf_str: &[u8], calendar: A) -> Result { + let ixdtf_record = ixdtf::parsers::IxdtfParser::from_utf8(ixdtf_str).parse()?; + if let Some(ixdtf_calendar) = ixdtf_record.calendar { + let parsed_calendar = AnyCalendarKind::get_for_bcp47_bytes(ixdtf_calendar) + .ok_or(ParseError::UnknownCalendar)?; + let expected_calendar = calendar + .as_calendar() + .any_calendar_kind() + .ok_or(ParseError::UnknownCalendar)?; + if parsed_calendar != expected_calendar { + return Err(ParseError::MismatchedCalendar( + expected_calendar, + parsed_calendar, + )); + } + } + let DateTime { date, time } = DateTime::::try_from_ixdtf_record(&ixdtf_record)?; + Ok(DateTime { + date: date.to_calendar(calendar), + time, + }) + } +} + +impl Time { + /// Creates a [`Time`] from an IXDTF syntax string of a time. + /// + /// Does not support parsing an IXDTF string with a date and time; for that, use [`DateTime`]. + /// + /// ✨ *Enabled with the `ixdtf` Cargo feature.* + /// + /// # Examples + /// + /// ``` + /// use icu::timezone::Time; + /// + /// let time = Time::try_from_str("16:01:17.045").unwrap(); + /// + /// assert_eq!(time.hour.number(), 16); + /// assert_eq!(time.minute.number(), 1); + /// assert_eq!(time.second.number(), 17); + /// assert_eq!(time.nanosecond.number(), 45000000); + /// ``` + pub fn try_from_str(ixdtf_str: &str) -> Result { + Self::try_from_utf8(ixdtf_str.as_bytes()) + } + + /// Creates a [`Time`] in the ISO-8601 calendar from an IXDTF syntax string. + /// + /// ✨ *Enabled with the `ixdtf` Cargo feature.* + /// + /// See [`Self::try_from_str()`]. + pub fn try_from_utf8(ixdtf_str: &[u8]) -> Result { + let ixdtf_record = ixdtf::parsers::IxdtfParser::from_utf8(ixdtf_str).parse_time()?; + Self::try_from_ixdtf_record(&ixdtf_record) + } + + fn try_from_ixdtf_record(ixdtf_record: &IxdtfParseRecord) -> Result { + let time_record = ixdtf_record.time.ok_or(ParseError::MissingFields)?; + let time = Self::try_new( + time_record.hour, + time_record.minute, + time_record.second, + time_record.nanosecond, + )?; + Ok(time) + } +} + +impl FromStr for Time { + type Err = ParseError; + fn from_str(ixdtf_str: &str) -> Result { + Self::try_from_str(ixdtf_str) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/components/timezone/src/lib.rs b/components/timezone/src/lib.rs index bd28758696e..4bd3e3fbb50 100644 --- a/components/timezone/src/lib.rs +++ b/components/timezone/src/lib.rs @@ -58,7 +58,8 @@ //! # Examples //! //! ``` -//! use icu::calendar::{Date, Time}; +//! use icu::calendar::Date; +//! use icu::timezone::Time; //! use icu::timezone::TimeZoneBcp47Id; //! use icu::timezone::TimeZoneIdMapper; //! use icu::timezone::ZoneVariant; @@ -106,7 +107,8 @@ mod ids; pub mod provider; pub mod scaffold; mod time_zone; -mod types; +/// TODO +pub mod types; mod windows_tz; mod zone_offset; @@ -124,9 +126,9 @@ pub use provider::TimeZoneBcp47Id; pub use time_zone::models; pub use time_zone::TimeZoneInfo; pub use time_zone::TimeZoneModel; -pub use types::{UtcOffset, ZoneVariant, ZonedDateTime}; +pub use types::{DateTime, Time, UtcOffset, ZoneVariant, ZonedDateTime}; pub use windows_tz::{WindowsTimeZoneMapper, WindowsTimeZoneMapperBorrowed}; pub use zone_offset::{ZoneOffsetCalculator, ZoneOffsets}; -#[cfg(all(feature = "ixdtf", feature = "compiled_data"))] +#[cfg(feature = "ixdtf")] pub use crate::ixdtf::ParseError; diff --git a/components/timezone/src/scaffold/into_option.rs b/components/timezone/src/scaffold/into_option.rs index 139f53ff4fb..fe493804b39 100644 --- a/components/timezone/src/scaffold/into_option.rs +++ b/components/timezone/src/scaffold/into_option.rs @@ -2,7 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use crate::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use crate::{types::*, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; use icu_calendar::{types::*, AnyCalendarKind, Date, Iso}; /// Converts Self to an `Option`, either `Some(T)` if able or `None` diff --git a/components/timezone/src/time_zone.rs b/components/timezone/src/time_zone.rs index 1c85a8657c1..f9ef8efbcf2 100644 --- a/components/timezone/src/time_zone.rs +++ b/components/timezone/src/time_zone.rs @@ -4,8 +4,8 @@ use core::fmt; -use crate::{scaffold::IntoOption, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; -use icu_calendar::{Date, Iso, Time}; +use crate::{scaffold::IntoOption, Time, TimeZoneBcp47Id, UtcOffset, ZoneVariant}; +use icu_calendar::{Date, Iso}; mod private { pub trait Sealed {} diff --git a/components/timezone/src/types.rs b/components/timezone/src/types.rs index 6874088e514..8bac7790c35 100644 --- a/components/timezone/src/types.rs +++ b/components/timezone/src/types.rs @@ -4,7 +4,325 @@ use crate::error::InvalidOffsetError; use core::str::FromStr; -use icu_calendar::{AsCalendar, Date, Time}; +use icu_calendar::{AsCalendar, Date, RangeError}; + +/// This macro defines a struct for 0-based date fields: hours, minutes, seconds +/// and fractional seconds. Each unit is bounded by a range. The traits implemented +/// here will return a Result on whether or not the unit is in range from the given +/// input. +macro_rules! dt_unit { + ($name:ident, $storage:ident, $value:expr, $docs:expr) => { + #[doc=$docs] + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] + pub struct $name($storage); + + impl $name { + /// Gets the numeric value for this component. + pub const fn number(self) -> $storage { + self.0 + } + + /// Creates a new value at 0. + pub const fn zero() -> $name { + Self(0) + } + } + + impl TryFrom<$storage> for $name { + type Error = RangeError; + + fn try_from(input: $storage) -> Result { + if input > $value { + Err(RangeError { + field: "$name", + min: 0, + max: $value, + value: input as i32, + }) + } else { + Ok(Self(input)) + } + } + } + + impl TryFrom for $name { + type Error = RangeError; + + fn try_from(input: usize) -> Result { + if input > $value { + Err(RangeError { + field: "$name", + min: 0, + max: $value, + value: input as i32, + }) + } else { + Ok(Self(input as $storage)) + } + } + } + + impl From<$name> for $storage { + fn from(input: $name) -> Self { + input.0 + } + } + + impl From<$name> for usize { + fn from(input: $name) -> Self { + input.0 as Self + } + } + + impl $name { + /// Attempts to add two values. + /// Returns `Some` if the sum is within bounds. + /// Returns `None` if the sum is out of bounds. + pub fn try_add(self, other: $storage) -> Option { + let sum = self.0.saturating_add(other); + if sum > $value { + None + } else { + Some(Self(sum)) + } + } + + /// Attempts to subtract two values. + /// Returns `Some` if the difference is within bounds. + /// Returns `None` if the difference is out of bounds. + pub fn try_sub(self, other: $storage) -> Option { + self.0.checked_sub(other).map(Self) + } + + /// Returns whether the value is zero. + #[inline] + pub fn is_zero(self) -> bool { + self.0 == 0 + } + } + }; +} + +dt_unit!( + IsoHour, + u8, + 24, + "An ISO-8601 hour component, for use with ISO calendars. + +Must be within inclusive bounds `[0, 24]`. The value could be equal to 24 to +denote the end of a day, with the writing 24:00:00. It corresponds to the same +time as the next day at 00:00:00." +); + +dt_unit!( + IsoMinute, + u8, + 60, + "An ISO-8601 minute component, for use with ISO calendars. + +Must be within inclusive bounds `[0, 60]`. The value could be equal to 60 to +denote the end of an hour, with the writing 12:60:00. This example corresponds +to the same time as 13:00:00. This is an extension to ISO 8601." +); + +dt_unit!( + IsoSecond, + u8, + 61, + "An ISO-8601 second component, for use with ISO calendars. + +Must be within inclusive bounds `[0, 61]`. `60` accommodates for leap seconds. + +The value could also be equal to 60 or 61, to indicate the end of a leap second, +with the writing `23:59:61.000000000Z` or `23:59:60.000000000Z`. These examples, +if used with this goal, would correspond to the same time as the next day, at +time `00:00:00.000000000Z`. This is an extension to ISO 8601." +); + +dt_unit!( + NanoSecond, + u32, + 999_999_999, + "A fractional second component, stored as nanoseconds. + +Must be within inclusive bounds `[0, 999_999_999]`." +); + +#[test] +fn test_iso_hour_arithmetic() { + const HOUR_MAX: u8 = 24; + const HOUR_VALUE: u8 = 5; + let hour = IsoHour(HOUR_VALUE); + + // middle of bounds + assert_eq!( + hour.try_add(HOUR_VALUE - 1), + Some(IsoHour(HOUR_VALUE + (HOUR_VALUE - 1))) + ); + assert_eq!( + hour.try_sub(HOUR_VALUE - 1), + Some(IsoHour(HOUR_VALUE - (HOUR_VALUE - 1))) + ); + + // edge of bounds + assert_eq!(hour.try_add(HOUR_MAX - HOUR_VALUE), Some(IsoHour(HOUR_MAX))); + assert_eq!(hour.try_sub(HOUR_VALUE), Some(IsoHour(0))); + + // out of bounds + assert_eq!(hour.try_add(1 + HOUR_MAX - HOUR_VALUE), None); + assert_eq!(hour.try_sub(1 + HOUR_VALUE), None); +} + +#[test] +fn test_iso_minute_arithmetic() { + const MINUTE_MAX: u8 = 60; + const MINUTE_VALUE: u8 = 5; + let minute = IsoMinute(MINUTE_VALUE); + + // middle of bounds + assert_eq!( + minute.try_add(MINUTE_VALUE - 1), + Some(IsoMinute(MINUTE_VALUE + (MINUTE_VALUE - 1))) + ); + assert_eq!( + minute.try_sub(MINUTE_VALUE - 1), + Some(IsoMinute(MINUTE_VALUE - (MINUTE_VALUE - 1))) + ); + + // edge of bounds + assert_eq!( + minute.try_add(MINUTE_MAX - MINUTE_VALUE), + Some(IsoMinute(MINUTE_MAX)) + ); + assert_eq!(minute.try_sub(MINUTE_VALUE), Some(IsoMinute(0))); + + // out of bounds + assert_eq!(minute.try_add(1 + MINUTE_MAX - MINUTE_VALUE), None); + assert_eq!(minute.try_sub(1 + MINUTE_VALUE), None); +} + +#[test] +fn test_iso_second_arithmetic() { + const SECOND_MAX: u8 = 61; + const SECOND_VALUE: u8 = 5; + let second = IsoSecond(SECOND_VALUE); + + // middle of bounds + assert_eq!( + second.try_add(SECOND_VALUE - 1), + Some(IsoSecond(SECOND_VALUE + (SECOND_VALUE - 1))) + ); + assert_eq!( + second.try_sub(SECOND_VALUE - 1), + Some(IsoSecond(SECOND_VALUE - (SECOND_VALUE - 1))) + ); + + // edge of bounds + assert_eq!( + second.try_add(SECOND_MAX - SECOND_VALUE), + Some(IsoSecond(SECOND_MAX)) + ); + assert_eq!(second.try_sub(SECOND_VALUE), Some(IsoSecond(0))); + + // out of bounds + assert_eq!(second.try_add(1 + SECOND_MAX - SECOND_VALUE), None); + assert_eq!(second.try_sub(1 + SECOND_VALUE), None); +} + +#[test] +fn test_iso_nano_second_arithmetic() { + const NANO_SECOND_MAX: u32 = 999_999_999; + const NANO_SECOND_VALUE: u32 = 5; + let nano_second = NanoSecond(NANO_SECOND_VALUE); + + // middle of bounds + assert_eq!( + nano_second.try_add(NANO_SECOND_VALUE - 1), + Some(NanoSecond(NANO_SECOND_VALUE + (NANO_SECOND_VALUE - 1))) + ); + assert_eq!( + nano_second.try_sub(NANO_SECOND_VALUE - 1), + Some(NanoSecond(NANO_SECOND_VALUE - (NANO_SECOND_VALUE - 1))) + ); + + // edge of bounds + assert_eq!( + nano_second.try_add(NANO_SECOND_MAX - NANO_SECOND_VALUE), + Some(NanoSecond(NANO_SECOND_MAX)) + ); + assert_eq!(nano_second.try_sub(NANO_SECOND_VALUE), Some(NanoSecond(0))); + + // out of bounds + assert_eq!( + nano_second.try_add(1 + NANO_SECOND_MAX - NANO_SECOND_VALUE), + None + ); + assert_eq!(nano_second.try_sub(1 + NANO_SECOND_VALUE), None); +} + +/// A representation of a time in hours, minutes, seconds, and nanoseconds +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[allow(clippy::exhaustive_structs)] // this type is stable +pub struct Time { + /// 0-based hour. + pub hour: IsoHour, + + /// 0-based minute. + pub minute: IsoMinute, + + /// 0-based second. + pub second: IsoSecond, + + /// Fractional second + pub nanosecond: NanoSecond, +} + +impl Time { + /// Construct a new [`Time`], without validating that all components are in range + pub const fn new( + hour: IsoHour, + minute: IsoMinute, + second: IsoSecond, + nanosecond: NanoSecond, + ) -> Self { + Self { + hour, + minute, + second, + nanosecond, + } + } + + /// Construct a new [`Time`] representing midnight (00:00.000) + pub const fn midnight() -> Self { + Self { + hour: IsoHour::zero(), + minute: IsoMinute::zero(), + second: IsoSecond::zero(), + nanosecond: NanoSecond::zero(), + } + } + + /// Construct a new [`Time`], whilst validating that all components are in range + pub fn try_new(hour: u8, minute: u8, second: u8, nanosecond: u32) -> Result { + Ok(Self { + hour: hour.try_into()?, + minute: minute.try_into()?, + second: second.try_into()?, + nanosecond: nanosecond.try_into()?, + }) + } +} + +/// A date + time for a given calendar. +#[derive(Debug)] +#[allow(clippy::exhaustive_structs)] // this type is stable +pub struct DateTime { + /// The date + pub date: Date, + /// The time + pub time: Time, +} /// A date and time local to a specified custom time zone. #[derive(Debug)] diff --git a/components/timezone/src/zone_offset.rs b/components/timezone/src/zone_offset.rs index 521d721c2f6..9b6b8a8f48a 100644 --- a/components/timezone/src/zone_offset.rs +++ b/components/timezone/src/zone_offset.rs @@ -3,9 +3,9 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::provider::{ZoneOffsetPeriodV1Marker, EPOCH}; -use crate::{TimeZoneBcp47Id, UtcOffset}; +use crate::{Time, TimeZoneBcp47Id, UtcOffset}; +use icu_calendar::Date; use icu_calendar::Iso; -use icu_calendar::{Date, Time}; use icu_provider::prelude::*; /// [`ZoneOffsetCalculator`] uses data from the [data provider] to calculate time zone offsets. @@ -64,7 +64,8 @@ impl ZoneOffsetCalculator { /// # Examples /// /// ``` - /// use icu::calendar::{Date, Time}; + /// use icu::calendar::Date; + /// use icu::timezone::Time; /// use icu::timezone::TimeZoneBcp47Id; /// use icu::timezone::UtcOffset; /// use icu::timezone::ZoneOffsetCalculator; diff --git a/ffi/capi/Cargo.toml b/ffi/capi/Cargo.toml index c3c8504a865..b669d4f8f0a 100644 --- a/ffi/capi/Cargo.toml +++ b/ffi/capi/Cargo.toml @@ -77,7 +77,7 @@ default_components = [ "timezone" ] -calendar = ["dep:icu_calendar"] +calendar = ["dep:icu_calendar", "dep:icu_timezone"] casemap = ["dep:icu_casemap"] collator = ["dep:icu_collator"] # collections = ["dep:icu_collections"] # Not useful on its own: use properties diff --git a/ffi/capi/bindings/dart/DateTime.g.dart b/ffi/capi/bindings/dart/DateTime.g.dart index 7418b2fb420..1b1d82d4c91 100644 --- a/ffi/capi/bindings/dart/DateTime.g.dart +++ b/ffi/capi/bindings/dart/DateTime.g.dart @@ -4,7 +4,7 @@ part of 'lib.g.dart'; /// An ICU4X DateTime object capable of containing a date and time for any calendar. /// -/// See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +/// See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. final class DateTime implements ffi.Finalizable { final ffi.Pointer _ffi; @@ -42,7 +42,7 @@ final class DateTime implements ffi.Finalizable { /// /// An empty era code will treat the year as an extended year /// - /// See the [Rust documentation for `try_new_from_codes`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.try_new_from_codes) for more information. + /// See the [Rust documentation for `try_new_from_codes`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.try_new_from_codes) for more information. /// /// Throws [CalendarError] on failure. factory DateTime.fromCodesInCalendar(String eraCode, int year, String monthCode, int day, int hour, int minute, int second, int nanosecond, Calendar calendar) { @@ -56,7 +56,7 @@ final class DateTime implements ffi.Finalizable { /// Creates a new [`DateTime`] from an [`Date`] and [`Time`] object /// - /// See the [Rust documentation for `new`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.new) for more information. + /// See the [Rust documentation for `new`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.new) for more information. factory DateTime.fromDateAndTime(Date date, Time time) { final result = _icu4x_DateTime_from_date_and_time_mv1(date._ffi, time._ffi); return DateTime._fromFfi(result, []); @@ -64,7 +64,7 @@ final class DateTime implements ffi.Finalizable { /// Creates a new [`DateTime`] from an IXDTF string. /// - /// See the [Rust documentation for `try_from_str`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.try_from_str) for more information. + /// See the [Rust documentation for `try_from_str`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.try_from_str) for more information. /// /// Throws [CalendarParseError] on failure. factory DateTime.fromString(String v, Calendar calendar) { @@ -78,7 +78,7 @@ final class DateTime implements ffi.Finalizable { /// Gets a copy of the date contained in this object /// - /// See the [Rust documentation for `date`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#structfield.date) for more information. + /// See the [Rust documentation for `date`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#structfield.date) for more information. Date get date { final result = _icu4x_DateTime_date_mv1(_ffi); return Date._fromFfi(result, []); @@ -86,7 +86,7 @@ final class DateTime implements ffi.Finalizable { /// Gets the time contained in this object /// - /// See the [Rust documentation for `time`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#structfield.time) for more information. + /// See the [Rust documentation for `time`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#structfield.time) for more information. Time get time { final result = _icu4x_DateTime_time_mv1(_ffi); return Time._fromFfi(result, []); @@ -94,7 +94,7 @@ final class DateTime implements ffi.Finalizable { /// Converts this date to ISO /// - /// See the [Rust documentation for `to_iso`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.to_iso) for more information. + /// See the [Rust documentation for `to_iso`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.to_iso) for more information. IsoDateTime toIso() { final result = _icu4x_DateTime_to_iso_mv1(_ffi); return IsoDateTime._fromFfi(result, []); @@ -102,7 +102,7 @@ final class DateTime implements ffi.Finalizable { /// Convert this datetime to one in a different calendar /// - /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.to_calendar) for more information. + /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.to_calendar) for more information. DateTime toCalendar(Calendar calendar) { final result = _icu4x_DateTime_to_calendar_mv1(_ffi, calendar._ffi); return DateTime._fromFfi(result, []); @@ -110,7 +110,7 @@ final class DateTime implements ffi.Finalizable { /// Returns the hour in this time /// - /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.hour) for more information. + /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.hour) for more information. int get hour { final result = _icu4x_DateTime_hour_mv1(_ffi); return result; @@ -118,7 +118,7 @@ final class DateTime implements ffi.Finalizable { /// Returns the minute in this time /// - /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.minute) for more information. + /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.minute) for more information. int get minute { final result = _icu4x_DateTime_minute_mv1(_ffi); return result; @@ -126,7 +126,7 @@ final class DateTime implements ffi.Finalizable { /// Returns the second in this time /// - /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.second) for more information. + /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.second) for more information. int get second { final result = _icu4x_DateTime_second_mv1(_ffi); return result; @@ -134,7 +134,7 @@ final class DateTime implements ffi.Finalizable { /// Returns the nanosecond in this time /// - /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.nanosecond) for more information. + /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.nanosecond) for more information. int get nanosecond { final result = _icu4x_DateTime_nanosecond_mv1(_ffi); return result; diff --git a/ffi/capi/bindings/dart/IsoDateTime.g.dart b/ffi/capi/bindings/dart/IsoDateTime.g.dart index f7470207cf8..08e1c555a8d 100644 --- a/ffi/capi/bindings/dart/IsoDateTime.g.dart +++ b/ffi/capi/bindings/dart/IsoDateTime.g.dart @@ -4,7 +4,7 @@ part of 'lib.g.dart'; /// An ICU4X DateTime object capable of containing a ISO-8601 date and time. /// -/// See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +/// See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. final class IsoDateTime implements ffi.Finalizable { final ffi.Pointer _ffi; @@ -26,7 +26,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Creates a new [`IsoDateTime`] from the specified date and time. /// - /// See the [Rust documentation for `try_new_iso`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.try_new_iso) for more information. + /// See the [Rust documentation for `try_new_iso`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.try_new_iso) for more information. /// /// Throws [CalendarError] on failure. factory IsoDateTime(int year, int month, int day, int hour, int minute, int second, int nanosecond) { @@ -39,7 +39,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Creates a new [`IsoDateTime`] from an [`IsoDate`] and [`Time`] object /// - /// See the [Rust documentation for `new`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.new) for more information. + /// See the [Rust documentation for `new`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.new) for more information. factory IsoDateTime.fromDateAndTime(IsoDate date, Time time) { final result = _icu4x_IsoDateTime_from_date_and_time_mv1(date._ffi, time._ffi); return IsoDateTime._fromFfi(result, []); @@ -47,7 +47,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Creates a new [`IsoDateTime`] from an IXDTF string. /// - /// See the [Rust documentation for `try_iso_from_str`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.try_iso_from_str) for more information. + /// See the [Rust documentation for `try_iso_from_str`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.try_iso_from_str) for more information. /// /// Throws [CalendarParseError] on failure. factory IsoDateTime.fromString(String v) { @@ -61,7 +61,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Gets the date contained in this object /// - /// See the [Rust documentation for `date`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#structfield.date) for more information. + /// See the [Rust documentation for `date`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#structfield.date) for more information. IsoDate get date { final result = _icu4x_IsoDateTime_date_mv1(_ffi); return IsoDate._fromFfi(result, []); @@ -69,7 +69,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Gets the time contained in this object /// - /// See the [Rust documentation for `time`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#structfield.time) for more information. + /// See the [Rust documentation for `time`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#structfield.time) for more information. Time get time { final result = _icu4x_IsoDateTime_time_mv1(_ffi); return Time._fromFfi(result, []); @@ -78,7 +78,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Converts this to an [`DateTime`] capable of being mixed with dates of /// other calendars /// - /// See the [Rust documentation for `to_any`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.to_any) for more information. + /// See the [Rust documentation for `to_any`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.to_any) for more information. DateTime toAny() { final result = _icu4x_IsoDateTime_to_any_mv1(_ffi); return DateTime._fromFfi(result, []); @@ -86,7 +86,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Convert this datetime to one in a different calendar /// - /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.to_calendar) for more information. + /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html#method.to_calendar) for more information. DateTime toCalendar(Calendar calendar) { final result = _icu4x_IsoDateTime_to_calendar_mv1(_ffi, calendar._ffi); return DateTime._fromFfi(result, []); @@ -94,7 +94,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Returns the hour in this time /// - /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.hour) for more information. + /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.hour) for more information. int get hour { final result = _icu4x_IsoDateTime_hour_mv1(_ffi); return result; @@ -102,7 +102,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Returns the minute in this time /// - /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.minute) for more information. + /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.minute) for more information. int get minute { final result = _icu4x_IsoDateTime_minute_mv1(_ffi); return result; @@ -110,7 +110,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Returns the second in this time /// - /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.second) for more information. + /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.second) for more information. int get second { final result = _icu4x_IsoDateTime_second_mv1(_ffi); return result; @@ -118,7 +118,7 @@ final class IsoDateTime implements ffi.Finalizable { /// Returns the nanosecond in this time /// - /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.nanosecond) for more information. + /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.nanosecond) for more information. int get nanosecond { final result = _icu4x_IsoDateTime_nanosecond_mv1(_ffi); return result; diff --git a/ffi/capi/bindings/dart/Time.g.dart b/ffi/capi/bindings/dart/Time.g.dart index 0ca466bf034..8bb14a50408 100644 --- a/ffi/capi/bindings/dart/Time.g.dart +++ b/ffi/capi/bindings/dart/Time.g.dart @@ -4,7 +4,7 @@ part of 'lib.g.dart'; /// An ICU4X Time object representing a time in terms of hour, minute, second, nanosecond /// -/// See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html) for more information. +/// See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html) for more information. final class Time implements ffi.Finalizable { final ffi.Pointer _ffi; @@ -26,7 +26,7 @@ final class Time implements ffi.Finalizable { /// Creates a new [`Time`] given field values /// - /// See the [Rust documentation for `try_new`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#method.try_new) for more information. + /// See the [Rust documentation for `try_new`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#method.try_new) for more information. /// /// Throws [CalendarError] on failure. factory Time(int hour, int minute, int second, int nanosecond) { @@ -39,7 +39,7 @@ final class Time implements ffi.Finalizable { /// Creates a new [`Time`] from an IXDTF string. /// - /// See the [Rust documentation for `try_from_str`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#method.try_from_str) for more information. + /// See the [Rust documentation for `try_from_str`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#method.try_from_str) for more information. /// /// Throws [CalendarParseError] on failure. factory Time.fromString(String v) { @@ -53,7 +53,7 @@ final class Time implements ffi.Finalizable { /// Creates a new [`Time`] representing midnight (00:00.000). /// - /// See the [Rust documentation for `midnight`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#method.midnight) for more information. + /// See the [Rust documentation for `midnight`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#method.midnight) for more information. /// /// Throws [CalendarError] on failure. factory Time.midnight() { @@ -66,7 +66,7 @@ final class Time implements ffi.Finalizable { /// Returns the hour in this time /// - /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.hour) for more information. + /// See the [Rust documentation for `hour`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.hour) for more information. int get hour { final result = _icu4x_Time_hour_mv1(_ffi); return result; @@ -74,7 +74,7 @@ final class Time implements ffi.Finalizable { /// Returns the minute in this time /// - /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.minute) for more information. + /// See the [Rust documentation for `minute`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.minute) for more information. int get minute { final result = _icu4x_Time_minute_mv1(_ffi); return result; @@ -82,7 +82,7 @@ final class Time implements ffi.Finalizable { /// Returns the second in this time /// - /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.second) for more information. + /// See the [Rust documentation for `second`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.second) for more information. int get second { final result = _icu4x_Time_second_mv1(_ffi); return result; @@ -90,7 +90,7 @@ final class Time implements ffi.Finalizable { /// Returns the nanosecond in this time /// - /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html#structfield.nanosecond) for more information. + /// See the [Rust documentation for `nanosecond`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html#structfield.nanosecond) for more information. int get nanosecond { final result = _icu4x_Time_nanosecond_mv1(_ffi); return result; diff --git a/ffi/capi/bindings/js/DateTime.d.ts b/ffi/capi/bindings/js/DateTime.d.ts index acd841ef385..83d8f764741 100644 --- a/ffi/capi/bindings/js/DateTime.d.ts +++ b/ffi/capi/bindings/js/DateTime.d.ts @@ -13,7 +13,7 @@ import type { pointer, codepoint } from "./diplomat-runtime.d.ts"; /** An ICU4X DateTime object capable of containing a date and time for any calendar. * -*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. */ export class DateTime { diff --git a/ffi/capi/bindings/js/DateTime.mjs b/ffi/capi/bindings/js/DateTime.mjs index 758fabf3be1..c1508b31373 100644 --- a/ffi/capi/bindings/js/DateTime.mjs +++ b/ffi/capi/bindings/js/DateTime.mjs @@ -14,7 +14,7 @@ import * as diplomatRuntime from "./diplomat-runtime.mjs"; /** An ICU4X DateTime object capable of containing a date and time for any calendar. * -*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. */ const DateTime_box_destroy_registry = new FinalizationRegistry((ptr) => { wasm.icu4x_DateTime_destroy_mv1(ptr); diff --git a/ffi/capi/bindings/js/IsoDateTime.d.ts b/ffi/capi/bindings/js/IsoDateTime.d.ts index ffa3aa612bb..caef60ac501 100644 --- a/ffi/capi/bindings/js/IsoDateTime.d.ts +++ b/ffi/capi/bindings/js/IsoDateTime.d.ts @@ -13,7 +13,7 @@ import type { pointer, codepoint } from "./diplomat-runtime.d.ts"; /** An ICU4X DateTime object capable of containing a ISO-8601 date and time. * -*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. */ export class IsoDateTime { diff --git a/ffi/capi/bindings/js/IsoDateTime.mjs b/ffi/capi/bindings/js/IsoDateTime.mjs index 6797c4348fa..b7b191c5f77 100644 --- a/ffi/capi/bindings/js/IsoDateTime.mjs +++ b/ffi/capi/bindings/js/IsoDateTime.mjs @@ -14,7 +14,7 @@ import * as diplomatRuntime from "./diplomat-runtime.mjs"; /** An ICU4X DateTime object capable of containing a ISO-8601 date and time. * -*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html) for more information. +*See the [Rust documentation for `DateTime`](https://docs.rs/icu/latest/icu/timezone/struct.DateTime.html) for more information. */ const IsoDateTime_box_destroy_registry = new FinalizationRegistry((ptr) => { wasm.icu4x_IsoDateTime_destroy_mv1(ptr); diff --git a/ffi/capi/bindings/js/Time.d.ts b/ffi/capi/bindings/js/Time.d.ts index dffb17ddcb7..41facd96791 100644 --- a/ffi/capi/bindings/js/Time.d.ts +++ b/ffi/capi/bindings/js/Time.d.ts @@ -6,7 +6,7 @@ import type { pointer, codepoint } from "./diplomat-runtime.d.ts"; /** An ICU4X Time object representing a time in terms of hour, minute, second, nanosecond * -*See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html) for more information. +*See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html) for more information. */ export class Time { diff --git a/ffi/capi/bindings/js/Time.mjs b/ffi/capi/bindings/js/Time.mjs index 95cb3945671..f258af5aaa0 100644 --- a/ffi/capi/bindings/js/Time.mjs +++ b/ffi/capi/bindings/js/Time.mjs @@ -7,7 +7,7 @@ import * as diplomatRuntime from "./diplomat-runtime.mjs"; /** An ICU4X Time object representing a time in terms of hour, minute, second, nanosecond * -*See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/calendar/struct.Time.html) for more information. +*See the [Rust documentation for `Time`](https://docs.rs/icu/latest/icu/timezone/struct.Time.html) for more information. */ const Time_box_destroy_registry = new FinalizationRegistry((ptr) => { wasm.icu4x_Time_destroy_mv1(ptr); diff --git a/ffi/capi/src/datetime.rs b/ffi/capi/src/datetime.rs index da0adaaf967..66fd8f05494 100644 --- a/ffi/capi/src/datetime.rs +++ b/ffi/capi/src/datetime.rs @@ -22,12 +22,12 @@ pub mod ffi { #[diplomat::opaque] /// An ICU4X DateTime object capable of containing a ISO-8601 date and time. - #[diplomat::rust_link(icu::calendar::DateTime, Struct)] - pub struct IsoDateTime(pub icu_calendar::DateTime); + #[diplomat::rust_link(icu::timezone::DateTime, Struct)] + pub struct IsoDateTime(pub icu_timezone::DateTime); impl IsoDateTime { /// Creates a new [`IsoDateTime`] from the specified date and time. - #[diplomat::rust_link(icu::calendar::DateTime::try_new_iso, FnInStruct)] + #[diplomat::rust_link(icu::timezone::DateTime::try_new_iso, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, constructor)] pub fn create( year: i32, @@ -38,19 +38,19 @@ pub mod ffi { second: u8, nanosecond: u32, ) -> Result, CalendarError> { - let mut dt = icu_calendar::DateTime { + let mut dt = icu_timezone::DateTime { date: icu_calendar::Date::try_new_iso(year, month, day)?, - time: icu_calendar::Time::try_new(hour, minute, second, 0)?, + time: icu_timezone::Time::try_new(hour, minute, second, 0)?, }; dt.time.nanosecond = nanosecond.try_into()?; Ok(Box::new(IsoDateTime(dt))) } /// Creates a new [`IsoDateTime`] from an [`IsoDate`] and [`Time`] object - #[diplomat::rust_link(icu::calendar::DateTime::new, FnInStruct)] + #[diplomat::rust_link(icu::timezone::DateTime::new, FnInStruct)] #[diplomat::attr(supports = fallible_constructors, named_constructor)] pub fn from_date_and_time(date: &IsoDate, time: &Time) -> Box { - let dt = icu_calendar::DateTime { + let dt = icu_timezone::DateTime { date: date.0, time: time.0, }; @@ -58,25 +58,25 @@ pub mod ffi { } /// Creates a new [`IsoDateTime`] from an IXDTF string. - #[diplomat::rust_link(icu::calendar::DateTime::try_iso_from_str, FnInStruct)] - #[diplomat::rust_link(icu::calendar::DateTime::try_iso_from_utf8, FnInStruct, hidden)] - #[diplomat::rust_link(icu::calendar::DateTime::from_str, FnInStruct, hidden)] + #[diplomat::rust_link(icu::timezone::DateTime::try_iso_from_str, FnInStruct)] + #[diplomat::rust_link(icu::timezone::DateTime::try_iso_from_utf8, FnInStruct, hidden)] + #[diplomat::rust_link(icu::timezone::DateTime::from_str, FnInStruct, hidden)] #[diplomat::attr(supports = fallible_constructors, named_constructor)] pub fn from_string(v: &DiplomatStr) -> Result, CalendarParseError> { Ok(Box::new(IsoDateTime( - icu_calendar::DateTime::try_iso_from_utf8(v)?, + icu_timezone::DateTime::try_iso_from_utf8(v)?, ))) } /// Gets the date contained in this object - #[diplomat::rust_link(icu::calendar::DateTime::date, StructField)] + #[diplomat::rust_link(icu::timezone::DateTime::date, StructField)] #[diplomat::attr(auto, getter)] pub fn date(&self) -> Box { Box::new(IsoDate(self.0.date)) } /// Gets the time contained in this object - #[diplomat::rust_link(icu::calendar::DateTime::time, StructField)] + #[diplomat::rust_link(icu::timezone::DateTime::time, StructField)] #[diplomat::attr(auto, getter)] pub fn time(&self) -> Box