diff --git a/src/builtins/core/plain_date.rs b/src/builtins/core/plain_date.rs index 9647b1a0d..d5610f616 100644 --- a/src/builtins/core/plain_date.rs +++ b/src/builtins/core/plain_date.rs @@ -17,6 +17,7 @@ use crate::{ }, parsers::IxdtfStringBuilder, provider::{NeverProvider, TimeZoneProvider}, + unix_time::EpochNanoseconds, MonthCode, TemporalError, TemporalResult, TimeZone, }; use alloc::string::String; @@ -685,6 +686,23 @@ impl PlainDate { epoch_ns.offset, ) } + + /// Gets the epochMilliseconds represented by this PlainDate in the given timezone + /// (at noon time) + /// + // Useful for implementing HandleDateTimeTemporalDate + pub fn epoch_ns_for_with_provider( + &self, + time_zone: TimeZone, + provider: &(impl TimeZoneProvider + ?Sized), + ) -> TemporalResult { + // 2. Let isoDateTime be CombineISODateAndTimeRecord(temporalDate.[[ISODate]], NoonTimeRecord()). + let iso = IsoDateTime::new(self.iso, IsoTime::noon())?; + // 3. Let epochNs be ? GetEpochNanosecondsFor(dateTimeFormat.[[TimeZone]], isoDateTime, compatible). + Ok(time_zone + .get_epoch_nanoseconds_for(iso, Disambiguation::Compatible, provider)? + .ns) + } } // ==== Trait impls ==== diff --git a/src/builtins/core/plain_date_time.rs b/src/builtins/core/plain_date_time.rs index 502ebd1cf..1d559cbd7 100644 --- a/src/builtins/core/plain_date_time.rs +++ b/src/builtins/core/plain_date_time.rs @@ -19,6 +19,7 @@ use crate::{ parsers::IxdtfStringBuilder, primitive::FiniteF64, provider::{NeverProvider, TimeZoneProvider}, + unix_time::EpochNanoseconds, MonthCode, TemporalError, TemporalResult, TimeZone, }; use alloc::string::String; @@ -907,6 +908,21 @@ impl PlainDateTime { )) } + /// Gets the epochMilliseconds represented by this PlainDateTime in the given timezone + /// + // Useful for implementing HandleDateTimeTemporalDateTime + pub fn epoch_ns_for_with_provider( + &self, + time_zone: TimeZone, + provider: &(impl TimeZoneProvider + ?Sized), + ) -> TemporalResult { + // Let epochNs be ? GetEpochNanosecondsFor(dateTimeFormat.[[TimeZone]], + // isoDateTime, compatible). + Ok(time_zone + .get_epoch_nanoseconds_for(self.iso, Disambiguation::Compatible, provider)? + .ns) + } + /// Create a [`PlainDate`] from the current `PlainDateTime`. #[inline] pub fn to_plain_date(&self) -> PlainDate { diff --git a/src/builtins/core/plain_time.rs b/src/builtins/core/plain_time.rs index 68c27c8d6..8878aba43 100644 --- a/src/builtins/core/plain_time.rs +++ b/src/builtins/core/plain_time.rs @@ -7,12 +7,15 @@ use crate::{ }, error::ErrorMessage, iso::IsoTime, + iso::{IsoDate, IsoDateTime}, options::{ - DifferenceOperation, DifferenceSettings, Overflow, ResolvedRoundingOptions, + DifferenceOperation, DifferenceSettings, Disambiguation, Overflow, ResolvedRoundingOptions, RoundingOptions, ToStringRoundingOptions, Unit, UnitGroup, }, parsers::{parse_time, IxdtfStringBuilder}, - TemporalError, TemporalResult, + provider::TimeZoneProvider, + unix_time::EpochNanoseconds, + TemporalError, TemporalResult, TimeZone, }; use alloc::string::String; use core::str::FromStr; @@ -541,6 +544,22 @@ impl PlainTime { let builder = IxdtfStringBuilder::default().with_time(result, resolved.precision); Ok(builder) } + /// Gets the epochMilliseconds represented by this PlainTime in the given timezone + /// (on Jan 1 1970) + /// + // Useful for implementing HandleDateTimeTemporalTime + pub fn epoch_ns_for_with_provider( + &self, + time_zone: TimeZone, + provider: &(impl TimeZoneProvider + ?Sized), + ) -> TemporalResult { + // 2. Let isoDateTime be CombineISODateAndTimeRecord(temporalDate.[[ISODate]], NoonTimeRecord()). + let iso = IsoDateTime::new(IsoDate::UNIX_EPOCH, self.iso)?; + // 3. Let epochNs be ? GetEpochNanosecondsFor(dateTimeFormat.[[TimeZone]], isoDateTime, compatible). + Ok(time_zone + .get_epoch_nanoseconds_for(iso, Disambiguation::Compatible, provider)? + .ns) + } } impl From for PlainTime { diff --git a/src/iso.rs b/src/iso.rs index 2abf72098..217a94377 100644 --- a/src/iso.rs +++ b/src/iso.rs @@ -264,6 +264,7 @@ pub struct IsoDate { } impl IsoDate { + pub(crate) const UNIX_EPOCH: Self = Self::new_unchecked(1970, 1, 1); /// Creates a new `IsoDate` without determining the validity. pub(crate) const fn new_unchecked(year: i32, month: u8, day: u8) -> Self { Self { year, month, day } diff --git a/temporal_capi/bindings/c/PlainDate.h b/temporal_capi/bindings/c/PlainDate.h index d196dc30a..5a04dcacb 100644 --- a/temporal_capi/bindings/c/PlainDate.h +++ b/temporal_capi/bindings/c/PlainDate.h @@ -138,6 +138,12 @@ temporal_rs_PlainDate_to_zoned_date_time_result temporal_rs_PlainDate_to_zoned_d typedef struct temporal_rs_PlainDate_to_zoned_date_time_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_with_provider_result; temporal_rs_PlainDate_to_zoned_date_time_with_provider_result temporal_rs_PlainDate_to_zoned_date_time_with_provider(const PlainDate* self, TimeZone time_zone, const PlainTime* time, const Provider* p); +typedef struct temporal_rs_PlainDate_epoch_ms_for_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_epoch_ms_for_result; +temporal_rs_PlainDate_epoch_ms_for_result temporal_rs_PlainDate_epoch_ms_for(const PlainDate* self, TimeZone time_zone); + +typedef struct temporal_rs_PlainDate_epoch_ms_for_with_provider_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_epoch_ms_for_with_provider_result; +temporal_rs_PlainDate_epoch_ms_for_with_provider_result temporal_rs_PlainDate_epoch_ms_for_with_provider(const PlainDate* self, TimeZone time_zone, const Provider* p); + void temporal_rs_PlainDate_to_ixdtf_string(const PlainDate* self, DisplayCalendar display_calendar, DiplomatWrite* write); PlainDate* temporal_rs_PlainDate_clone(const PlainDate* self); diff --git a/temporal_capi/bindings/c/PlainDateTime.h b/temporal_capi/bindings/c/PlainDateTime.h index 32b5e35b8..fb6223239 100644 --- a/temporal_capi/bindings/c/PlainDateTime.h +++ b/temporal_capi/bindings/c/PlainDateTime.h @@ -147,6 +147,12 @@ temporal_rs_PlainDateTime_to_zoned_date_time_result temporal_rs_PlainDateTime_to typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result; temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result temporal_rs_PlainDateTime_to_zoned_date_time_with_provider(const PlainDateTime* self, TimeZone time_zone, Disambiguation disambiguation, const Provider* p); +typedef struct temporal_rs_PlainDateTime_epoch_ms_for_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_epoch_ms_for_result; +temporal_rs_PlainDateTime_epoch_ms_for_result temporal_rs_PlainDateTime_epoch_ms_for(const PlainDateTime* self, TimeZone time_zone); + +typedef struct temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result; +temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result temporal_rs_PlainDateTime_epoch_ms_for_with_provider(const PlainDateTime* self, TimeZone time_zone, const Provider* p); + typedef struct temporal_rs_PlainDateTime_to_ixdtf_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_ixdtf_string_result; temporal_rs_PlainDateTime_to_ixdtf_string_result temporal_rs_PlainDateTime_to_ixdtf_string(const PlainDateTime* self, ToStringRoundingOptions options, DisplayCalendar display_calendar, DiplomatWrite* write); diff --git a/temporal_capi/bindings/c/PlainTime.h b/temporal_capi/bindings/c/PlainTime.h index 0d897da90..673c10828 100644 --- a/temporal_capi/bindings/c/PlainTime.h +++ b/temporal_capi/bindings/c/PlainTime.h @@ -46,6 +46,12 @@ temporal_rs_PlainTime_from_epoch_nanoseconds_result temporal_rs_PlainTime_from_e typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result; temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider(I128Nanoseconds ns, TimeZone tz, const Provider* p); +typedef struct temporal_rs_PlainTime_epoch_ms_for_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_epoch_ms_for_result; +temporal_rs_PlainTime_epoch_ms_for_result temporal_rs_PlainTime_epoch_ms_for(const PlainTime* self, TimeZone time_zone); + +typedef struct temporal_rs_PlainTime_epoch_ms_for_with_provider_result {union {int64_t ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_epoch_ms_for_with_provider_result; +temporal_rs_PlainTime_epoch_ms_for_with_provider_result temporal_rs_PlainTime_epoch_ms_for_with_provider(const PlainTime* self, TimeZone time_zone, const Provider* p); + typedef struct temporal_rs_PlainTime_with_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_with_result; temporal_rs_PlainTime_with_result temporal_rs_PlainTime_with(const PlainTime* self, PartialTime partial, ArithmeticOverflow_option overflow); diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp index e586d7ceb..1164ede79 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainDate.d.hpp @@ -139,6 +139,10 @@ class PlainDate { inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::PlainTime* time, const temporal_rs::Provider& p) const; + inline temporal_rs::diplomat::result epoch_ms_for(temporal_rs::TimeZone time_zone) const; + + inline temporal_rs::diplomat::result epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const; + inline std::string to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const; template inline void to_ixdtf_string_write(temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp index 10673ade8..897ac2c40 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainDate.hpp @@ -141,6 +141,12 @@ namespace capi { typedef struct temporal_rs_PlainDate_to_zoned_date_time_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_to_zoned_date_time_with_provider_result; temporal_rs_PlainDate_to_zoned_date_time_with_provider_result temporal_rs_PlainDate_to_zoned_date_time_with_provider(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::PlainTime* time, const temporal_rs::capi::Provider* p); + typedef struct temporal_rs_PlainDate_epoch_ms_for_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_epoch_ms_for_result; + temporal_rs_PlainDate_epoch_ms_for_result temporal_rs_PlainDate_epoch_ms_for(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_PlainDate_epoch_ms_for_with_provider_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDate_epoch_ms_for_with_provider_result; + temporal_rs_PlainDate_epoch_ms_for_with_provider_result temporal_rs_PlainDate_epoch_ms_for_with_provider(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + void temporal_rs_PlainDate_to_ixdtf_string(const temporal_rs::capi::PlainDate* self, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); temporal_rs::capi::PlainDate* temporal_rs_PlainDate_clone(const temporal_rs::capi::PlainDate* self); @@ -410,6 +416,19 @@ inline temporal_rs::diplomat::result return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); } +inline temporal_rs::diplomat::result temporal_rs::PlainDate::epoch_ms_for(temporal_rs::TimeZone time_zone) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_epoch_ms_for(this->AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainDate::epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainDate_epoch_ms_for_with_provider(this->AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + inline std::string temporal_rs::PlainDate::to_ixdtf_string(temporal_rs::DisplayCalendar display_calendar) const { std::string output; temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp index f5052625f..ad17cb680 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.d.hpp @@ -148,6 +148,10 @@ class PlainDateTime { inline temporal_rs::diplomat::result, temporal_rs::TemporalError> to_zoned_date_time_with_provider(temporal_rs::TimeZone time_zone, temporal_rs::Disambiguation disambiguation, const temporal_rs::Provider& p) const; + inline temporal_rs::diplomat::result epoch_ms_for(temporal_rs::TimeZone time_zone) const; + + inline temporal_rs::diplomat::result epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const; + inline temporal_rs::diplomat::result to_ixdtf_string(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar) const; template inline temporal_rs::diplomat::result to_ixdtf_string_write(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar, W& writeable_output) const; diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp index 2513e06d7..a62afff7f 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainDateTime.hpp @@ -150,6 +150,12 @@ namespace capi { typedef struct temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result; temporal_rs_PlainDateTime_to_zoned_date_time_with_provider_result temporal_rs_PlainDateTime_to_zoned_date_time_with_provider(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::TimeZone time_zone, temporal_rs::capi::Disambiguation disambiguation, const temporal_rs::capi::Provider* p); + typedef struct temporal_rs_PlainDateTime_epoch_ms_for_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_epoch_ms_for_result; + temporal_rs_PlainDateTime_epoch_ms_for_result temporal_rs_PlainDateTime_epoch_ms_for(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result; + temporal_rs_PlainDateTime_epoch_ms_for_with_provider_result temporal_rs_PlainDateTime_epoch_ms_for_with_provider(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + typedef struct temporal_rs_PlainDateTime_to_ixdtf_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainDateTime_to_ixdtf_string_result; temporal_rs_PlainDateTime_to_ixdtf_string_result temporal_rs_PlainDateTime_to_ixdtf_string(const temporal_rs::capi::PlainDateTime* self, temporal_rs::capi::ToStringRoundingOptions options, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::diplomat::capi::DiplomatWrite* write); @@ -454,6 +460,19 @@ inline temporal_rs::diplomat::result return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); } +inline temporal_rs::diplomat::result temporal_rs::PlainDateTime::epoch_ms_for(temporal_rs::TimeZone time_zone) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_epoch_ms_for(this->AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainDateTime::epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainDateTime_epoch_ms_for_with_provider(this->AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + inline temporal_rs::diplomat::result temporal_rs::PlainDateTime::to_ixdtf_string(temporal_rs::ToStringRoundingOptions options, temporal_rs::DisplayCalendar display_calendar) const { std::string output; temporal_rs::diplomat::capi::DiplomatWrite write = temporal_rs::diplomat::WriteFromString(output); diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp index b4f01054e..1d4df5f93 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainTime.d.hpp @@ -53,6 +53,10 @@ class PlainTime { inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_epoch_nanoseconds_with_provider(temporal_rs::I128Nanoseconds ns, temporal_rs::TimeZone tz, const temporal_rs::Provider& p); + inline temporal_rs::diplomat::result epoch_ms_for(temporal_rs::TimeZone time_zone) const; + + inline temporal_rs::diplomat::result epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const; + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialTime partial, std::optional overflow) const; inline static temporal_rs::diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s); diff --git a/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp b/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp index b15878bcb..14390c22d 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/PlainTime.hpp @@ -49,6 +49,12 @@ namespace capi { typedef struct temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result; temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider_result temporal_rs_PlainTime_from_epoch_nanoseconds_with_provider(temporal_rs::capi::I128Nanoseconds ns, temporal_rs::capi::TimeZone tz, const temporal_rs::capi::Provider* p); + typedef struct temporal_rs_PlainTime_epoch_ms_for_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_epoch_ms_for_result; + temporal_rs_PlainTime_epoch_ms_for_result temporal_rs_PlainTime_epoch_ms_for(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::TimeZone time_zone); + + typedef struct temporal_rs_PlainTime_epoch_ms_for_with_provider_result {union {int64_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_epoch_ms_for_with_provider_result; + temporal_rs_PlainTime_epoch_ms_for_with_provider_result temporal_rs_PlainTime_epoch_ms_for_with_provider(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::TimeZone time_zone, const temporal_rs::capi::Provider* p); + typedef struct temporal_rs_PlainTime_with_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_PlainTime_with_result; temporal_rs_PlainTime_with_result temporal_rs_PlainTime_with(const temporal_rs::capi::PlainTime* self, temporal_rs::capi::PartialTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow); @@ -152,6 +158,19 @@ inline temporal_rs::diplomat::result, te return result.is_ok ? temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : temporal_rs::diplomat::result, temporal_rs::TemporalError>(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); } +inline temporal_rs::diplomat::result temporal_rs::PlainTime::epoch_ms_for(temporal_rs::TimeZone time_zone) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_epoch_ms_for(this->AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline temporal_rs::diplomat::result temporal_rs::PlainTime::epoch_ms_for_with_provider(temporal_rs::TimeZone time_zone, const temporal_rs::Provider& p) const { + auto result = temporal_rs::capi::temporal_rs_PlainTime_epoch_ms_for_with_provider(this->AsFFI(), + time_zone.AsFFI(), + p.AsFFI()); + return result.is_ok ? temporal_rs::diplomat::result(temporal_rs::diplomat::Ok(result.ok)) : temporal_rs::diplomat::result(temporal_rs::diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + inline temporal_rs::diplomat::result, temporal_rs::TemporalError> temporal_rs::PlainTime::with(temporal_rs::PartialTime partial, std::optional overflow) const { auto result = temporal_rs::capi::temporal_rs_PlainTime_with(this->AsFFI(), partial.AsFFI(), diff --git a/temporal_capi/src/plain_date.rs b/temporal_capi/src/plain_date.rs index 7752e3bd6..3d1e7796b 100644 --- a/temporal_capi/src/plain_date.rs +++ b/temporal_capi/src/plain_date.rs @@ -367,6 +367,30 @@ pub mod ffi { .map(|x| Box::new(ZonedDateTime(x))) .map_err(Into::into) } + + #[cfg(feature = "compiled_data")] + pub fn epoch_ms_for(&self, time_zone: TimeZone) -> Result { + self.epoch_ms_for_with_provider(time_zone, &Provider::compiled()) + } + pub fn epoch_ms_for_with_provider<'p>( + &self, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result { + let ns = with_provider!(p, |p| self + .0 + .epoch_ns_for_with_provider(time_zone.into(), p)) + .map_err(TemporalError::from)?; + + let ns_i128 = ns.as_i128(); + let ms = ns_i128 / 1_000_000; + if let Ok(ms) = i64::try_from(ms) { + Ok(ms) + } else { + Err(TemporalError::assert("Found an out-of-range PlainDate")) + } + } + pub fn to_ixdtf_string( &self, display_calendar: DisplayCalendar, diff --git a/temporal_capi/src/plain_date_time.rs b/temporal_capi/src/plain_date_time.rs index b0800afdc..d9e3c0598 100644 --- a/temporal_capi/src/plain_date_time.rs +++ b/temporal_capi/src/plain_date_time.rs @@ -354,7 +354,28 @@ pub mod ffi { .map(|x| Box::new(ZonedDateTime(x))) .map_err(Into::into) } - + #[cfg(feature = "compiled_data")] + pub fn epoch_ms_for(&self, time_zone: TimeZone) -> Result { + self.epoch_ms_for_with_provider(time_zone, &Provider::compiled()) + } + pub fn epoch_ms_for_with_provider<'p>( + &self, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result { + let ns = with_provider!(p, |p| self + .0 + .epoch_ns_for_with_provider(time_zone.into(), p)) + .map_err(TemporalError::from)?; + + let ns_i128 = ns.as_i128(); + let ms = ns_i128 / 1_000_000; + if let Ok(ms) = i64::try_from(ms) { + Ok(ms) + } else { + Err(TemporalError::assert("Found an out-of-range PlainDateTime")) + } + } pub fn to_ixdtf_string( &self, options: ToStringRoundingOptions, diff --git a/temporal_capi/src/plain_time.rs b/temporal_capi/src/plain_time.rs index 3320d4513..9773178c7 100644 --- a/temporal_capi/src/plain_time.rs +++ b/temporal_capi/src/plain_time.rs @@ -100,6 +100,29 @@ pub mod ffi { Ok(Box::new(Self(zdt.to_plain_time()))) } + #[cfg(feature = "compiled_data")] + pub fn epoch_ms_for(&self, time_zone: TimeZone) -> Result { + self.epoch_ms_for_with_provider(time_zone, &Provider::compiled()) + } + pub fn epoch_ms_for_with_provider<'p>( + &self, + time_zone: TimeZone, + p: &Provider<'p>, + ) -> Result { + let ns = with_provider!(p, |p| self + .0 + .epoch_ns_for_with_provider(time_zone.into(), p)) + .map_err(TemporalError::from)?; + + let ns_i128 = ns.as_i128(); + let ms = ns_i128 / 1_000_000; + if let Ok(ms) = i64::try_from(ms) { + Ok(ms) + } else { + Err(TemporalError::assert("Found an out-of-range YearMonth")) + } + } + pub fn with( &self, partial: PartialTime,