diff --git a/src/components/calendar.rs b/src/components/calendar.rs index b8c82203e..66f453f49 100644 --- a/src/components/calendar.rs +++ b/src/components/calendar.rs @@ -35,6 +35,8 @@ use icu_calendar::{ }; use tinystr::TinyAsciiStr; +use super::ZonedDateTime; + /// The ECMAScript defined protocol methods pub const CALENDAR_PROTOCOL_METHODS: [&str; 21] = [ "dateAdd", @@ -618,6 +620,36 @@ impl Calendar { } } +impl From for Calendar { + fn from(value: Date) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: DateTime) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: ZonedDateTime) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: MonthDay) -> Self { + value.calendar().clone() + } +} + +impl From for Calendar { + fn from(value: YearMonth) -> Self { + value.calendar().clone() + } +} + #[cfg(all(test, feature = "compiled_data"))] mod tests { use super::*; diff --git a/src/components/date.rs b/src/components/date.rs index f6c62c5b5..51802103a 100644 --- a/src/components/date.rs +++ b/src/components/date.rs @@ -193,13 +193,15 @@ impl Date { Ok(Self::new_unchecked(iso, calendar)) } - #[must_use] - /// Creates a `Date` from a `DateTime`. - pub fn from_datetime(dt: &DateTime) -> Self { - Self { - iso: dt.iso_date(), - calendar: dt.calendar().clone(), - } + /// Creates a new `Date` from the current `Date` and the provided calendar. + pub fn with_calendar(&self, calendar: Calendar) -> TemporalResult { + Self::new( + self.iso_year(), + self.iso_month().into(), + self.iso_day().into(), + calendar, + ArithmeticOverflow::Reject, + ) } #[inline] diff --git a/src/components/datetime.rs b/src/components/datetime.rs index aa7caca9a..2d5b21e6b 100644 --- a/src/components/datetime.rs +++ b/src/components/datetime.rs @@ -14,7 +14,7 @@ use tinystr::TinyAsciiStr; use super::{ calendar::{CalendarDateLike, GetTemporalCalendar}, duration::normalized::{NormalizedTimeDuration, RelativeRoundResult}, - Date, Duration, + Date, Duration, Time, }; /// The native Rust implementation of `Temporal.PlainDateTime` @@ -191,6 +191,38 @@ impl DateTime { )) } + /// Creates a new `DateTime` from the current `DateTime` and the provided `Time`. + pub fn with_time(&self, time: Time) -> TemporalResult { + Self::new( + self.iso_year(), + self.iso_month().into(), + self.iso_day().into(), + time.hour().into(), + time.minute().into(), + time.second().into(), + time.millisecond().into(), + time.microsecond().into(), + time.nanosecond().into(), + self.calendar.clone(), + ) + } + + /// Creates a new `DateTime` from the current `DateTime` and a provided `Calendar`. + pub fn with_calendar(&self, calendar: Calendar) -> TemporalResult { + Self::new( + self.iso_year(), + self.iso_month().into(), + self.iso_day().into(), + self.hour().into(), + self.minute().into(), + self.second().into(), + self.millisecond().into(), + self.microsecond().into(), + self.nanosecond().into(), + calendar, + ) + } + /// Validates whether ISO date slots are within iso limits at noon. #[inline] pub fn validate(target: &T) -> bool {