diff --git a/src/builtins/core/date.rs b/src/builtins/core/date.rs index f9a6a53b9..8819c3a34 100644 --- a/src/builtins/core/date.rs +++ b/src/builtins/core/date.rs @@ -7,7 +7,7 @@ use crate::{ iso::{IsoDate, IsoDateTime, IsoTime}, options::{ ArithmeticOverflow, DifferenceOperation, DifferenceSettings, DisplayCalendar, - ResolvedRoundingOptions, TemporalUnit, + ResolvedRoundingOptions, TemporalUnit, UnitGroup, }, parsers::{parse_date_time, IxdtfStringBuilder}, primitive::FiniteF64, @@ -253,6 +253,7 @@ impl PlainDate { let resolved = ResolvedRoundingOptions::from_diff_settings( settings, op, + UnitGroup::Date, TemporalUnit::Day, TemporalUnit::Day, )?; diff --git a/src/builtins/core/datetime.rs b/src/builtins/core/datetime.rs index 62709afbf..6073b5a7f 100644 --- a/src/builtins/core/datetime.rs +++ b/src/builtins/core/datetime.rs @@ -9,7 +9,7 @@ use crate::{ iso::{IsoDate, IsoDateTime, IsoTime}, options::{ ArithmeticOverflow, DifferenceOperation, DifferenceSettings, DisplayCalendar, - ResolvedRoundingOptions, RoundingOptions, TemporalUnit, ToStringRoundingOptions, + ResolvedRoundingOptions, RoundingOptions, TemporalUnit, ToStringRoundingOptions, UnitGroup, }, parsers::{parse_date_time, IxdtfStringBuilder}, provider::NeverProvider, @@ -121,6 +121,7 @@ impl PlainDateTime { let options = ResolvedRoundingOptions::from_diff_settings( settings, op, + UnitGroup::DateTime, TemporalUnit::Day, TemporalUnit::Nanosecond, )?; diff --git a/src/builtins/core/instant.rs b/src/builtins/core/instant.rs index 7726358ae..548fd50d8 100644 --- a/src/builtins/core/instant.rs +++ b/src/builtins/core/instant.rs @@ -10,7 +10,7 @@ use crate::{ iso::IsoDateTime, options::{ DifferenceOperation, DifferenceSettings, DisplayOffset, ResolvedRoundingOptions, - RoundingOptions, TemporalUnit, ToStringRoundingOptions, + RoundingOptions, TemporalUnit, ToStringRoundingOptions, UnitGroup, }, parsers::{parse_instant, IxdtfStringBuilder}, primitive::FiniteF64, @@ -88,6 +88,7 @@ impl Instant { let resolved_options = ResolvedRoundingOptions::from_diff_settings( options, op, + UnitGroup::Time, TemporalUnit::Second, TemporalUnit::Nanosecond, )?; diff --git a/src/builtins/core/time.rs b/src/builtins/core/time.rs index 349b2d2fa..ee8ae3c71 100644 --- a/src/builtins/core/time.rs +++ b/src/builtins/core/time.rs @@ -5,7 +5,7 @@ use crate::{ iso::IsoTime, options::{ ArithmeticOverflow, DifferenceOperation, DifferenceSettings, ResolvedRoundingOptions, - RoundingIncrement, TemporalRoundingMode, TemporalUnit, ToStringRoundingOptions, + RoundingIncrement, TemporalRoundingMode, TemporalUnit, ToStringRoundingOptions, UnitGroup, }, parsers::{parse_time, IxdtfStringBuilder}, primitive::FiniteF64, @@ -127,6 +127,7 @@ impl PlainTime { let resolved = ResolvedRoundingOptions::from_diff_settings( settings, op, + UnitGroup::Time, TemporalUnit::Hour, TemporalUnit::Nanosecond, )?; diff --git a/src/builtins/core/zoneddatetime.rs b/src/builtins/core/zoneddatetime.rs index c2ad3eb31..a7b32fb5b 100644 --- a/src/builtins/core/zoneddatetime.rs +++ b/src/builtins/core/zoneddatetime.rs @@ -17,7 +17,7 @@ use crate::{ ArithmeticOverflow, DifferenceOperation, DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, DisplayTimeZone, OffsetDisambiguation, ResolvedRoundingOptions, RoundingIncrement, TemporalRoundingMode, TemporalUnit, - ToStringRoundingOptions, + ToStringRoundingOptions, UnitGroup, }, parsers::{self, FormattableOffset, FormattableTime, IxdtfStringBuilder, Precision}, partial::{PartialDate, PartialTime}, @@ -259,6 +259,7 @@ impl ZonedDateTime { let resolved_options = ResolvedRoundingOptions::from_diff_settings( options, op, + UnitGroup::DateTime, TemporalUnit::Hour, TemporalUnit::Nanosecond, )?; diff --git a/src/options.rs b/src/options.rs index 6b21468e5..09c793d84 100644 --- a/src/options.rs +++ b/src/options.rs @@ -177,11 +177,13 @@ impl ResolvedRoundingOptions { pub(crate) fn from_diff_settings( options: DifferenceSettings, operation: DifferenceOperation, + unit_group: UnitGroup, fallback_largest: TemporalUnit, fallback_smallest: TemporalUnit, ) -> TemporalResult { // 4. Let resolvedOptions be ? SnapshotOwnProperties(? GetOptionsObject(options), null). // 5. Let settings be ? GetDifferenceSettings(operation, resolvedOptions, DATE, « », "day", "day"). + unit_group.validate_unit(options.largest_unit)?; let increment = options.increment.unwrap_or_default(); let rounding_mode = match operation { DifferenceOperation::Since => options @@ -341,6 +343,33 @@ impl ResolvedRoundingOptions { // ==== Options enums and methods ==== +pub enum UnitGroup { + Date, + Time, + DateTime, +} + +impl UnitGroup { + pub fn validate_unit(self, unit: Option) -> TemporalResult<()> { + // TODO: Determine proper handling of Auto. + match self { + UnitGroup::Date => match unit { + Some(unit) if !unit.is_time_unit() => Ok(()), + None => Ok(()), + _ => Err(TemporalError::range() + .with_message("Unit was not part of the date unit group.")), + }, + UnitGroup::Time => match unit { + Some(unit) if unit.is_time_unit() => Ok(()), + None => Ok(()), + _ => Err(TemporalError::range() + .with_message("Unit was not part of the time unit group.")), + }, + UnitGroup::DateTime => Ok(()), + } + } +} + /// The relevant unit that should be used for the operation that /// this option is provided as a value. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]