diff --git a/src/builtins/compiled/duration/tests.rs b/src/builtins/compiled/duration/tests.rs index 8de6fe3b5..7a3ed2e79 100644 --- a/src/builtins/compiled/duration/tests.rs +++ b/src/builtins/compiled/duration/tests.rs @@ -488,8 +488,8 @@ fn round_relative_to_zoned_datetime() { let duration = Duration::from_hours(25); let zdt = ZonedDateTime::try_new( 1_000_000_000_000_000_000, - Calendar::default(), TimeZone::try_from_str("+04:30").unwrap(), + Calendar::default(), ) .unwrap(); let options = RoundingOptions { @@ -803,8 +803,8 @@ fn nudge_past_end() { let duration = Duration::default(); let relative_to = ZonedDateTime::try_new( 86_40000_00000_00000_00000, - Default::default(), TimeZone::try_from_str("UTC").unwrap(), + Default::default(), ) .unwrap(); let options = RoundingOptions { diff --git a/src/builtins/compiled/zoned_date_time.rs b/src/builtins/compiled/zoned_date_time.rs index 4eb3bf4b3..4a8e4dd19 100644 --- a/src/builtins/compiled/zoned_date_time.rs +++ b/src/builtins/compiled/zoned_date_time.rs @@ -2,7 +2,6 @@ use crate::builtins::zoned_date_time::ZonedDateTimeFields; use crate::builtins::TZ_PROVIDER; use crate::partial::PartialZonedDateTime; use crate::provider::TransitionDirection; -use crate::ZonedDateTime; use crate::{ options::{ DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, DisplayTimeZone, @@ -10,6 +9,7 @@ use crate::{ }, Calendar, Duration, PlainTime, TemporalResult, TimeZone, }; +use crate::{Instant, ZonedDateTime}; use alloc::string::String; impl core::fmt::Display for ZonedDateTime { @@ -63,9 +63,32 @@ impl ZonedDateTime { impl ZonedDateTime { /// Creates a new valid `ZonedDateTime`. #[inline] - pub fn try_new(nanos: i128, calendar: Calendar, time_zone: TimeZone) -> TemporalResult { - Self::try_new_with_provider(nanos, calendar, time_zone, &*TZ_PROVIDER) + pub fn try_new(nanos: i128, time_zone: TimeZone, calendar: Calendar) -> TemporalResult { + Self::try_new_with_provider(nanos, time_zone, calendar, &*TZ_PROVIDER) } + + /// Creates a new valid `ZonedDateTime` with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso(nanos: i128, time_zone: TimeZone) -> TemporalResult { + Self::try_new_iso_with_provider(nanos, time_zone, &*TZ_PROVIDER) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`]. + #[inline] + pub fn try_new_from_instant( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + ) -> TemporalResult { + Self::try_new_from_instant_with_provider(instant, time_zone, calendar, &*TZ_PROVIDER) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`] with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso_from_instant(instant: Instant, time_zone: TimeZone) -> TemporalResult { + Self::try_new_iso_from_instant_with_provider(instant, time_zone, &*TZ_PROVIDER) + } + #[inline] pub fn from_partial( partial: PartialZonedDateTime, diff --git a/src/builtins/core/instant.rs b/src/builtins/core/instant.rs index c018b4b9b..33a8dc3db 100644 --- a/src/builtins/core/instant.rs +++ b/src/builtins/core/instant.rs @@ -393,7 +393,7 @@ impl Instant { time_zone: TimeZone, provider: &impl TimeZoneProvider, ) -> TemporalResult { - ZonedDateTime::new_unchecked_with_provider(*self, Calendar::default(), time_zone, provider) + ZonedDateTime::new_unchecked_with_provider(*self, time_zone, Calendar::ISO, provider) } } diff --git a/src/builtins/core/now.rs b/src/builtins/core/now.rs index 013906142..0eddd77a0 100644 --- a/src/builtins/core/now.rs +++ b/src/builtins/core/now.rs @@ -55,7 +55,7 @@ impl Now { let system_nanoseconds = self.host_hooks.get_system_epoch_nanoseconds()?; let time_zone = time_zone.unwrap_or(self.host_hooks.get_system_time_zone(provider)?); let instant = Instant::from(system_nanoseconds); - ZonedDateTime::new_unchecked_with_provider(instant, Calendar::ISO, time_zone, provider) + ZonedDateTime::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) } } diff --git a/src/builtins/core/plain_date.rs b/src/builtins/core/plain_date.rs index 965199c99..121920d68 100644 --- a/src/builtins/core/plain_date.rs +++ b/src/builtins/core/plain_date.rs @@ -676,8 +676,8 @@ impl PlainDate { // 7. Return ! CreateTemporalZonedDateTime(epochNs, timeZone, temporalDate.[[Calendar]]). ZonedDateTime::try_new_with_cached_offset( epoch_ns.ns.0, - self.calendar.clone(), tz, + self.calendar.clone(), epoch_ns.offset, ) } diff --git a/src/builtins/core/plain_date_time.rs b/src/builtins/core/plain_date_time.rs index dbc619708..61ae846a4 100644 --- a/src/builtins/core/plain_date_time.rs +++ b/src/builtins/core/plain_date_time.rs @@ -899,8 +899,8 @@ impl PlainDateTime { // 7. Return ! CreateTemporalZonedDateTime(epochNs, timeZone, dateTime.[[Calendar]]). Ok(ZonedDateTime::new_unchecked( Instant::from(epoch_ns.ns), - self.calendar.clone(), time_zone, + self.calendar.clone(), epoch_ns.offset, )) } diff --git a/src/builtins/core/zoned_date_time.rs b/src/builtins/core/zoned_date_time.rs index 485ba2fd0..2bd8ae5b9 100644 --- a/src/builtins/core/zoned_date_time.rs +++ b/src/builtins/core/zoned_date_time.rs @@ -142,8 +142,8 @@ impl ZonedDateTimeFields { /// // Create from epoch nanoseconds /// let zdt = ZonedDateTime::try_new( /// 0, // epoch nanoseconds (Unix epoch) -/// Calendar::default(), // ISO 8601 calendar /// TimeZone::utc(), // UTC timezone +/// Calendar::default(), // ISO 8601 calendar /// ).unwrap(); /// /// assert_eq!(zdt.epoch_milliseconds(), 0); @@ -162,8 +162,8 @@ impl ZonedDateTimeFields { /// let time_zone = TimeZone::try_from_str("America/New_York").unwrap(); /// let zoned_date_time = ZonedDateTime::try_new( /// 1609459200000000000, // 2021-01-01T00:00:00Z -/// Calendar::default(), /// time_zone, +/// Calendar::default(), /// ).unwrap(); /// /// // Note: This would be December 31, 2020 19:00 in New York (EST) @@ -184,8 +184,8 @@ impl ZonedDateTimeFields { /// let time_zone = TimeZone::try_from_str("Europe/London").unwrap(); /// let zdt = ZonedDateTime::try_new( /// 1609459200000000000, // 2021-01-01T00:00:00Z -/// Calendar::default(), /// time_zone, +/// Calendar::default(), /// ).unwrap(); /// /// // Add 6 months @@ -227,8 +227,8 @@ impl ZonedDateTimeFields { /// /// let zdt = ZonedDateTime::try_new( /// 1609459200000000000, -/// Calendar::default(), /// TimeZone::try_from_str("Asia/Tokyo").unwrap(), +/// Calendar::default(), /// ).unwrap(); /// /// let iso_string = zdt.to_ixdtf_string( @@ -267,8 +267,8 @@ impl ZonedDateTime { #[must_use] pub(crate) fn new_unchecked( instant: Instant, - calendar: Calendar, time_zone: TimeZone, + calendar: Calendar, cached_offset: UtcOffsetSeconds, ) -> Self { Self { @@ -281,8 +281,8 @@ impl ZonedDateTime { pub(crate) fn new_unchecked_with_provider( instant: Instant, - calendar: Calendar, time_zone: TimeZone, + calendar: Calendar, provider: &impl TimeZoneProvider, ) -> TemporalResult { let offset = time_zone @@ -364,8 +364,8 @@ impl ZonedDateTime { // 9. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). Self::new_unchecked_with_provider( epoch_ns, - self.calendar().clone(), *self.time_zone(), + self.calendar().clone(), provider, ) } @@ -588,27 +588,27 @@ impl ZonedDateTime { #[inline] pub fn try_new_with_provider( nanos: i128, - calendar: Calendar, time_zone: TimeZone, + calendar: Calendar, provider: &impl TimeZoneProvider, ) -> TemporalResult { let instant = Instant::try_new(nanos)?; - Self::new_unchecked_with_provider(instant, calendar, time_zone, provider) + Self::new_unchecked_with_provider(instant, time_zone, calendar, provider) } /// Creates a new valid `ZonedDateTime`. #[inline] pub(crate) fn try_new_with_cached_offset( nanos: i128, - calendar: Calendar, time_zone: TimeZone, + calendar: Calendar, cached_offset: UtcOffsetSeconds, ) -> TemporalResult { let instant = Instant::try_new(nanos)?; Ok(Self::new_unchecked( instant, - calendar, time_zone, + calendar, cached_offset, )) } @@ -621,7 +621,28 @@ impl ZonedDateTime { provider: &impl TimeZoneProvider, ) -> TemporalResult { let instant = Instant::try_new(nanos)?; - Self::new_unchecked_with_provider(instant, Calendar::default(), time_zone, provider) + Self::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`]. + #[inline] + pub fn try_new_from_instant_with_provider( + instant: Instant, + time_zone: TimeZone, + calendar: Calendar, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Self::new_unchecked_with_provider(instant, time_zone, calendar, provider) + } + + /// Creates a new valid `ZonedDateTime` from an [`Instant`] with an ISO 8601 calendar. + #[inline] + pub fn try_new_iso_from_instant_with_provider( + instant: Instant, + time_zone: TimeZone, + provider: &impl TimeZoneProvider, + ) -> TemporalResult { + Self::new_unchecked_with_provider(instant, time_zone, Calendar::ISO, provider) } /// Returns `ZonedDateTime`'s Calendar. @@ -678,8 +699,8 @@ impl ZonedDateTime { Ok(Self::new_unchecked( Instant::from(epoch_nanos.ns), - partial.calendar, timezone, + partial.calendar, epoch_nanos.offset, )) } @@ -755,8 +776,8 @@ impl ZonedDateTime { // 26. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). Ok(Self::new_unchecked( Instant::from(epoch_nanos.ns), - self.calendar.clone(), self.time_zone, + self.calendar.clone(), epoch_nanos.offset, )) } @@ -770,8 +791,8 @@ impl ZonedDateTime { ) -> TemporalResult { Self::try_new_with_provider( self.epoch_nanoseconds().as_i128(), - self.calendar.clone(), time_zone, + self.calendar.clone(), provider, ) } @@ -783,8 +804,8 @@ impl ZonedDateTime { pub fn with_calendar(&self, calendar: Calendar) -> Self { Self::new_unchecked( self.instant, - calendar, self.time_zone, + calendar, self.cached_offset.into(), ) } @@ -842,8 +863,8 @@ impl ZonedDateTime { Ok(Some( ZonedDateTime::try_new_with_provider( transition.0, - self.calendar().clone(), self.time_zone, + self.calendar().clone(), provider, ) .ok() @@ -1091,8 +1112,8 @@ impl ZonedDateTime { }; Self::try_new_with_cached_offset( epoch_ns.ns.0, - self.calendar.clone(), self.time_zone, + self.calendar.clone(), epoch_ns.offset, ) } @@ -1173,8 +1194,8 @@ impl ZonedDateTime { let epoch_nanos = self.time_zone.get_start_of_day(&iso.date, provider)?; Self::try_new_with_cached_offset( epoch_nanos.ns.0, - self.calendar.clone(), self.time_zone, + self.calendar.clone(), epoch_nanos.offset, ) } @@ -1297,8 +1318,8 @@ impl ZonedDateTime { // 20. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar). ZonedDateTime::try_new_with_cached_offset( candidate, - self.calendar.clone(), self.time_zone, + self.calendar.clone(), offset, ) } else { @@ -1328,8 +1349,8 @@ impl ZonedDateTime { ZonedDateTime::try_new_with_cached_offset( epoch_ns.ns.0, - self.calendar.clone(), self.time_zone, + self.calendar.clone(), epoch_ns.offset, ) } @@ -1409,8 +1430,8 @@ impl ZonedDateTime { )?; Ok(Self::new_unchecked( Instant::from(epoch_nanos.ns), - Calendar::new(parsed.date.calendar), parsed.timezone, + Calendar::new(parsed.date.calendar), epoch_nanos.offset, )) } diff --git a/src/builtins/core/zoned_date_time/tests.rs b/src/builtins/core/zoned_date_time/tests.rs index 2c1e5a0e5..dcb8a3768 100644 --- a/src/builtins/core/zoned_date_time/tests.rs +++ b/src/builtins/core/zoned_date_time/tests.rs @@ -11,7 +11,6 @@ use crate::{ Calendar, Duration, MonthCode, TemporalResult, TimeZone, UtcOffset, }; use alloc::string::ToString; -use core::str::FromStr; use timezone_provider::zoneinfo64::ZONEINFO64_RES_FOR_TESTING; use tinystr::tinystr; @@ -52,8 +51,8 @@ fn basic_zdt_test() { let zdt = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("UTC", provider).unwrap(), + Calendar::ISO, provider, ) .unwrap(); @@ -67,8 +66,8 @@ fn basic_zdt_test() { let zdt_minus_five = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("America/New_York", provider).unwrap(), + Calendar::ISO, provider, ) .unwrap(); @@ -82,8 +81,8 @@ fn basic_zdt_test() { let zdt_plus_eleven = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("Australia/Sydney", provider).unwrap(), + Calendar::ISO, provider, ) .unwrap(); @@ -325,8 +324,8 @@ fn overflow_reject_throws() { test_all_providers!(provider: { let zdt = ZonedDateTime::try_new_with_provider( 217178610123456789, - Calendar::default(), TimeZone::utc_with_provider(provider), + Calendar::default(), provider, ) .unwrap(); @@ -404,8 +403,8 @@ fn static_tzdb_zdt_test() { let zdt = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("UTC", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), provider, ) .unwrap(); @@ -419,8 +418,8 @@ fn static_tzdb_zdt_test() { let zdt_minus_five = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("America/New_York", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), provider, ) .unwrap(); @@ -434,8 +433,8 @@ fn static_tzdb_zdt_test() { let zdt_plus_eleven = ZonedDateTime::try_new_with_provider( nov_30_2023_utc, - Calendar::from_str("iso8601").unwrap(), TimeZone::try_from_str_with_provider("Australia/Sydney", provider).unwrap(), + Calendar::from_str("iso8601").unwrap(), provider, ) .unwrap(); @@ -455,8 +454,8 @@ fn basic_zdt_add() { test_all_providers!(#[cfg_for_fs(not(target_os = "windows"))] provider: { let zdt = ZonedDateTime::try_new_with_provider( -560174321098766, - Calendar::default(), TimeZone::utc_with_provider(provider), + Calendar::default(), provider, ) .unwrap(); @@ -476,8 +475,8 @@ fn basic_zdt_add() { // "1970-01-04T12:23:45.678902034+00:00[UTC]" let expected = ZonedDateTime::try_new_with_provider( 303825678902034, - Calendar::default(), TimeZone::utc_with_provider(provider), + Calendar::default(), provider, ) .unwrap(); @@ -991,8 +990,9 @@ fn test_london() { // Test that they correctly compute from nanoseconds let zdt = ZonedDateTime::try_new_with_provider( 1_553_993_999_999_999_999, + TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), Calendar::ISO, - TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), provider, + provider, ) .unwrap(); assert_eq!( @@ -1001,8 +1001,9 @@ fn test_london() { ); let zdt = ZonedDateTime::try_new_with_provider( 1_553_994_000_000_000_000, + TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), Calendar::ISO, - TimeZone::try_from_str_with_provider("Europe/London", provider).unwrap(), provider, + provider, ) .unwrap(); assert_eq!(zdt.to_string_with_provider(provider).unwrap(), LONDON_POSIX_TRANSITION_2019_03_31,); @@ -1052,8 +1053,8 @@ fn test_troll() { // Antarctica/Troll started DST in 2005, but had no other transitions before that let zdt = ZonedDateTime::try_new_with_provider( 0, - Calendar::ISO, TimeZone::try_from_str_with_provider("Antarctica/Troll", provider).unwrap(), + Calendar::ISO, provider, ) .unwrap(); diff --git a/src/options/relative_to.rs b/src/options/relative_to.rs index a5af86aa2..3ae5989b3 100644 --- a/src/options/relative_to.rs +++ b/src/options/relative_to.rs @@ -120,8 +120,8 @@ impl RelativeTo { Ok(ZonedDateTime::try_new_with_cached_offset( epoch_ns.ns.0, - calendar, timezone, + calendar, epoch_ns.offset, )? .into()) diff --git a/temporal_capi/src/zoned_date_time.rs b/temporal_capi/src/zoned_date_time.rs index 7d98267cd..813648b42 100644 --- a/temporal_capi/src/zoned_date_time.rs +++ b/temporal_capi/src/zoned_date_time.rs @@ -157,8 +157,8 @@ pub mod ffi { ) -> Result, TemporalError> { with_provider!(p, |p| temporal_rs::ZonedDateTime::try_new_with_provider( nanosecond.into(), - temporal_rs::Calendar::new(calendar.into()), time_zone.0, + temporal_rs::Calendar::new(calendar.into()), p )) .map(|x| Box::new(ZonedDateTime(x))) diff --git a/tools/tzif-inspect/src/main.rs b/tools/tzif-inspect/src/main.rs index 5391b124c..c05854a3e 100644 --- a/tools/tzif-inspect/src/main.rs +++ b/tools/tzif-inspect/src/main.rs @@ -25,7 +25,7 @@ macro_rules! format_line( ); fn seconds_to_zdt_string(s: Seconds, time_zone: TimeZone) -> String { - ZonedDateTime::try_new(s.0 as i128 * 1_000_000_000, Default::default(), time_zone) + ZonedDateTime::try_new_iso(s.0 as i128 * 1_000_000_000, time_zone) .unwrap() .to_string() }