From 34858338755d9b69a1fc1c9244a36afafddfbc3a Mon Sep 17 00:00:00 2001 From: Tpt Date: Wed, 4 Jan 2023 20:47:16 +0100 Subject: [PATCH] Makes Datetime.checked_sub return DayTimeDuration Allows to be consistent with XPath and SPARQL 1.2 SEP 0002 This change is not replicated yet into the SPARQL evaluator to avoid a breaking change https://www.w3.org/TR/xpath-functions/#func-subtract-dateTimes https://github.com/w3c/sparql-12/blob/main/SEP/SEP-0002/sep-0002.md --- lib/oxsdatatypes/src/date_time.rs | 26 +++++++++++++------------- lib/src/sparql/eval.rs | 12 +++++++++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/oxsdatatypes/src/date_time.rs b/lib/oxsdatatypes/src/date_time.rs index 25914fce..ef3a3ce5 100644 --- a/lib/oxsdatatypes/src/date_time.rs +++ b/lib/oxsdatatypes/src/date_time.rs @@ -122,7 +122,7 @@ impl DateTime { /// [op:subtract-dateTimes](https://www.w3.org/TR/xpath-functions/#func-subtract-dateTimes) #[inline] - pub fn checked_sub(&self, rhs: impl Into) -> Option { + pub fn checked_sub(&self, rhs: impl Into) -> Option { self.timestamp.checked_sub(rhs.into().timestamp) } @@ -320,7 +320,7 @@ impl Time { /// [op:subtract-times](https://www.w3.org/TR/xpath-functions/#func-subtract-times) #[inline] - pub fn checked_sub(&self, rhs: impl Into) -> Option { + pub fn checked_sub(&self, rhs: impl Into) -> Option { self.timestamp.checked_sub(rhs.into().timestamp) } @@ -489,7 +489,7 @@ impl Date { /// [op:subtract-dates](https://www.w3.org/TR/xpath-functions/#func-subtract-dates) #[inline] - pub fn checked_sub(&self, rhs: impl Into) -> Option { + pub fn checked_sub(&self, rhs: impl Into) -> Option { self.timestamp.checked_sub(rhs.into().timestamp) } @@ -1459,10 +1459,10 @@ impl Timestamp { } #[inline] - fn checked_sub(&self, rhs: Self) -> Option { + fn checked_sub(&self, rhs: Self) -> Option { match (self.timezone_offset, rhs.timezone_offset) { (Some(_), Some(_)) | (None, None) => { - Some(Duration::new(0, self.value.checked_sub(rhs.value)?)) + Some(DayTimeDuration::new(self.value.checked_sub(rhs.value)?)) } _ => None, //TODO: implicit timezone } @@ -2232,7 +2232,7 @@ mod tests { .unwrap() .checked_sub(DateTime::from_str("1999-11-28T09:00:00Z").unwrap()) .unwrap(), - Duration::from_str("P337DT2H12M").unwrap() + DayTimeDuration::from_str("P337DT2H12M").unwrap() ); assert_eq!( @@ -2240,21 +2240,21 @@ mod tests { .unwrap() .checked_sub(Date::from_str("1999-11-28").unwrap()) .unwrap(), - Duration::from_str("P337D").unwrap() + DayTimeDuration::from_str("P337D").unwrap() ); assert_eq!( Date::from_str("2000-10-30+05:00") .unwrap() .checked_sub(Date::from_str("1999-11-28Z").unwrap()) .unwrap(), - Duration::from_str("P336DT19H").unwrap() + DayTimeDuration::from_str("P336DT19H").unwrap() ); assert_eq!( Date::from_str("2000-10-15-05:00") .unwrap() .checked_sub(Date::from_str("2000-10-10+02:00").unwrap()) .unwrap(), - Duration::from_str("P5DT7H").unwrap() + DayTimeDuration::from_str("P5DT7H").unwrap() ); assert_eq!( @@ -2262,28 +2262,28 @@ mod tests { .unwrap() .checked_sub(Time::from_str("04:00:00-05:00").unwrap()) .unwrap(), - Duration::from_str("PT2H12M").unwrap() + DayTimeDuration::from_str("PT2H12M").unwrap() ); assert_eq!( Time::from_str("11:00:00-05:00") .unwrap() .checked_sub(Time::from_str("21:30:00+05:30").unwrap()) .unwrap(), - Duration::from_str("PT0S").unwrap() + DayTimeDuration::from_str("PT0S").unwrap() ); assert_eq!( Time::from_str("17:00:00-06:00") .unwrap() .checked_sub(Time::from_str("08:00:00+09:00").unwrap()) .unwrap(), - Duration::from_str("P1D").unwrap() + DayTimeDuration::from_str("P1D").unwrap() ); assert_eq!( Time::from_str("24:00:00") .unwrap() .checked_sub(Time::from_str("23:59:59").unwrap()) .unwrap(), - Duration::from_str("-PT23H59M59S").unwrap() + DayTimeDuration::from_str("-PT23H59M59S").unwrap() ); } diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index 48cc10aa..bfe6cb9e 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -1002,9 +1002,15 @@ impl SimpleEvaluator { NumericBinaryOperands::Double(v1, v2) => (v1 - v2).into(), NumericBinaryOperands::Integer(v1, v2) => v1.checked_sub(v2)?.into(), NumericBinaryOperands::Decimal(v1, v2) => v1.checked_sub(v2)?.into(), - NumericBinaryOperands::DateTime(v1, v2) => v1.checked_sub(v2)?.into(), - NumericBinaryOperands::Date(v1, v2) => v1.checked_sub(v2)?.into(), - NumericBinaryOperands::Time(v1, v2) => v1.checked_sub(v2)?.into(), + NumericBinaryOperands::DateTime(v1, v2) => { + Duration::from(v1.checked_sub(v2)?).into() + } + NumericBinaryOperands::Date(v1, v2) => { + Duration::from(v1.checked_sub(v2)?).into() + } + NumericBinaryOperands::Time(v1, v2) => { + Duration::from(v1.checked_sub(v2)?).into() + } NumericBinaryOperands::Duration(v1, v2) => v1.checked_sub(v2)?.into(), NumericBinaryOperands::YearMonthDuration(v1, v2) => { v1.checked_sub(v2)?.into()