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
pull/348/head
Tpt 2 years ago committed by Thomas Tanon
parent 78c4e750ae
commit 3485833875
  1. 26
      lib/oxsdatatypes/src/date_time.rs
  2. 12
      lib/src/sparql/eval.rs

@ -122,7 +122,7 @@ impl DateTime {
/// [op:subtract-dateTimes](https://www.w3.org/TR/xpath-functions/#func-subtract-dateTimes) /// [op:subtract-dateTimes](https://www.w3.org/TR/xpath-functions/#func-subtract-dateTimes)
#[inline] #[inline]
pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<Duration> { pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<DayTimeDuration> {
self.timestamp.checked_sub(rhs.into().timestamp) 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) /// [op:subtract-times](https://www.w3.org/TR/xpath-functions/#func-subtract-times)
#[inline] #[inline]
pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<Duration> { pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<DayTimeDuration> {
self.timestamp.checked_sub(rhs.into().timestamp) 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) /// [op:subtract-dates](https://www.w3.org/TR/xpath-functions/#func-subtract-dates)
#[inline] #[inline]
pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<Duration> { pub fn checked_sub(&self, rhs: impl Into<Self>) -> Option<DayTimeDuration> {
self.timestamp.checked_sub(rhs.into().timestamp) self.timestamp.checked_sub(rhs.into().timestamp)
} }
@ -1459,10 +1459,10 @@ impl Timestamp {
} }
#[inline] #[inline]
fn checked_sub(&self, rhs: Self) -> Option<Duration> { fn checked_sub(&self, rhs: Self) -> Option<DayTimeDuration> {
match (self.timezone_offset, rhs.timezone_offset) { match (self.timezone_offset, rhs.timezone_offset) {
(Some(_), Some(_)) | (None, None) => { (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 _ => None, //TODO: implicit timezone
} }
@ -2232,7 +2232,7 @@ mod tests {
.unwrap() .unwrap()
.checked_sub(DateTime::from_str("1999-11-28T09:00:00Z").unwrap()) .checked_sub(DateTime::from_str("1999-11-28T09:00:00Z").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("P337DT2H12M").unwrap() DayTimeDuration::from_str("P337DT2H12M").unwrap()
); );
assert_eq!( assert_eq!(
@ -2240,21 +2240,21 @@ mod tests {
.unwrap() .unwrap()
.checked_sub(Date::from_str("1999-11-28").unwrap()) .checked_sub(Date::from_str("1999-11-28").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("P337D").unwrap() DayTimeDuration::from_str("P337D").unwrap()
); );
assert_eq!( assert_eq!(
Date::from_str("2000-10-30+05:00") Date::from_str("2000-10-30+05:00")
.unwrap() .unwrap()
.checked_sub(Date::from_str("1999-11-28Z").unwrap()) .checked_sub(Date::from_str("1999-11-28Z").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("P336DT19H").unwrap() DayTimeDuration::from_str("P336DT19H").unwrap()
); );
assert_eq!( assert_eq!(
Date::from_str("2000-10-15-05:00") Date::from_str("2000-10-15-05:00")
.unwrap() .unwrap()
.checked_sub(Date::from_str("2000-10-10+02:00").unwrap()) .checked_sub(Date::from_str("2000-10-10+02:00").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("P5DT7H").unwrap() DayTimeDuration::from_str("P5DT7H").unwrap()
); );
assert_eq!( assert_eq!(
@ -2262,28 +2262,28 @@ mod tests {
.unwrap() .unwrap()
.checked_sub(Time::from_str("04:00:00-05:00").unwrap()) .checked_sub(Time::from_str("04:00:00-05:00").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("PT2H12M").unwrap() DayTimeDuration::from_str("PT2H12M").unwrap()
); );
assert_eq!( assert_eq!(
Time::from_str("11:00:00-05:00") Time::from_str("11:00:00-05:00")
.unwrap() .unwrap()
.checked_sub(Time::from_str("21:30:00+05:30").unwrap()) .checked_sub(Time::from_str("21:30:00+05:30").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("PT0S").unwrap() DayTimeDuration::from_str("PT0S").unwrap()
); );
assert_eq!( assert_eq!(
Time::from_str("17:00:00-06:00") Time::from_str("17:00:00-06:00")
.unwrap() .unwrap()
.checked_sub(Time::from_str("08:00:00+09:00").unwrap()) .checked_sub(Time::from_str("08:00:00+09:00").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("P1D").unwrap() DayTimeDuration::from_str("P1D").unwrap()
); );
assert_eq!( assert_eq!(
Time::from_str("24:00:00") Time::from_str("24:00:00")
.unwrap() .unwrap()
.checked_sub(Time::from_str("23:59:59").unwrap()) .checked_sub(Time::from_str("23:59:59").unwrap())
.unwrap(), .unwrap(),
Duration::from_str("-PT23H59M59S").unwrap() DayTimeDuration::from_str("-PT23H59M59S").unwrap()
); );
} }

@ -1002,9 +1002,15 @@ impl SimpleEvaluator {
NumericBinaryOperands::Double(v1, v2) => (v1 - v2).into(), NumericBinaryOperands::Double(v1, v2) => (v1 - v2).into(),
NumericBinaryOperands::Integer(v1, v2) => v1.checked_sub(v2)?.into(), NumericBinaryOperands::Integer(v1, v2) => v1.checked_sub(v2)?.into(),
NumericBinaryOperands::Decimal(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::DateTime(v1, v2) => {
NumericBinaryOperands::Date(v1, v2) => v1.checked_sub(v2)?.into(), Duration::from(v1.checked_sub(v2)?).into()
NumericBinaryOperands::Time(v1, v2) => 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::Duration(v1, v2) => v1.checked_sub(v2)?.into(),
NumericBinaryOperands::YearMonthDuration(v1, v2) => { NumericBinaryOperands::YearMonthDuration(v1, v2) => {
v1.checked_sub(v2)?.into() v1.checked_sub(v2)?.into()

Loading…
Cancel
Save