From dd2501164ece3892a056514366d384da9545eb82 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Tue, 31 Mar 2026 18:21:41 +0200 Subject: [PATCH 01/10] First documentation for Date Time --- docs/datetime.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/datetime.md diff --git a/docs/datetime.md b/docs/datetime.md new file mode 100644 index 0000000..6a16498 --- /dev/null +++ b/docs/datetime.md @@ -0,0 +1,72 @@ +# Date and Time Support in QLever + +This page describes which features from the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md) are supported in QLever, and how to use them. + +## Datatypes +QLever supports the following `xsd` Date/Time datatypes: + +| Type | Example | Description | +|--|--|--| +|`xsd:time`|`"09:30:10Z"^^xsd:time`|A time containing hour, minute, and second.| +|`xsd:date`|`"2025-12-24"^^xsd:date`|Simple date containing year, month and day. | +|`xsd:dateTime`|`"2025-12-24T18:11:00Z"^^xsd:dateTime`|Date combined with time (hour, minute, second, and timezone).| +|`xsd:duration`|`"P1Y2M1D"^^xsd:duration`|A time interval that may contain years, months, days and time components (hours, minutes, seconds).| +|`xsd:dayTimeDuration`|`"P2DT4H5M6S"^^xsd:dayTimeDuration`|A time interval consisting of days and time components (hours, minutes, seconds).| +|`xsd:yearMonthDuration`|`"P12Y2M"^^xsd:yearMonthDuration`|A time interval consisting of years and months.| +|`xsd:gYear`|`"12000"^^xsd:gYear`|A (potentially large) year.| + +TODO: time und yearMonthDuration supported? + +## Arithmetics + +### == + +### != + +### < + +### > + +### Subtraction + +`xsd:date - xsd:date`: +Returns the `xsd:dayTimeDuration` between the two dates. The arguments need to be valid dates (e.g. `"2025-02-30"^^xsd:date` is not allowed). + +??? note "Example query for `xsd:date - xsd:date`" + + There are 73 days between the two dates. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 + ((?date1 - ?date2) AS ?differenceInDays) + WHERE { + BIND("2020-03-13"^^xsd:date AS ?date1) + BIND("2019-12-31"^^xsd:date AS ?date2) + } + ``` + +`xsd:date - xsd:dayTimeDuration`: +Returns the `xsd:dateTime` that is the amount of days and the time of the duration earlier than the given date. The first argument needs to be a valid date. + +??? note "Example query for `xsd:date - dayTimeDuration`" + + The date X is Y earlier than date Z. + + ```sparql {data-demo-engine="osm-planet"} + + ``` + +`xsd:date - xsd:yearMonthDuration`: TODO: supported? + +`xsd:time - xsd:time`: TODO: supported? +`xsd:time - xsd:dayTimeDuration`: TODO: supported? + +`xsd:dateTime - xsd:dateTime`: + +`xsd:dateTime - xsd:dayTimeDuration`: + +`xsd:dateTime - xsd:yearMonthDuration`: TODO: supported? + + +### Addition \ No newline at end of file From 334fb47eb400a937e6c2060b9fc1eb2640feeac1 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Wed, 1 Apr 2026 20:35:39 +0200 Subject: [PATCH 02/10] Addition and Subtraction with examples --- docs/datetime.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 6a16498..5bb147e 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -51,10 +51,14 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati ??? note "Example query for `xsd:date - dayTimeDuration`" - The date X is Y earlier than date Z. + The date 2025-05-05 at 23:10:30 is 10 days, 49 minutes and 30 seconds earlier than the start date. ```sparql {data-demo-engine="osm-planet"} - + PREFIX xsd: + SELECT ?date ?duration ((?date - ?duration) AS ?difference) WHERE { + BIND("2025-05-16"^^xsd:date AS ?date) + BIND("P10DT0H49M30S"^^xsd:dayTimeDuration AS ?duration) + } ``` `xsd:date - xsd:yearMonthDuration`: TODO: supported? @@ -63,10 +67,74 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati `xsd:time - xsd:dayTimeDuration`: TODO: supported? `xsd:dateTime - xsd:dateTime`: +Returns the `xsd:dayTimeDuration` between the two date and their times. The arguments need to be valid dates. + +??? note "Example query for `xsd:dateTime - xsd:dateTime`" + + There are 23 days, 6 hours, 14 minutes, and 30 seconds between the two dates and their times. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 + ((?date1 - ?date2) AS ?difference) WHERE { + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-01T12:00:30Z"^^xsd:dateTime AS ?date2) + } + ``` `xsd:dateTime - xsd:dayTimeDuration`: +Returns the `xsd:dateTime` that is the amount of days and the time of the duration earlier than the given date and time. The first argument needs to be a valid date. + +??? note "Example query for `xsd:dateTime - dayTimeDuration`" + + The date 2000-01-01 is 2 days, 12 hours, 12 minutes and 12 seconds earlier than the start date and time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?dateTime ?duration ((?dateTime - ?duration) AS ?difference) WHERE { + BIND("2000-01-03T12:12:12Z"^^xsd:dateTime AS ?dateTime) + BIND("P2DT12H12M12S"^^xsd:dayTimeDuration AS ?duration) + } + + ``` `xsd:dateTime - xsd:yearMonthDuration`: TODO: supported? -### Addition \ No newline at end of file +### Addition + +`xsd:date + xsd:dayTimeDuration`: +Returns the `xsd:dateTime` that is the amount of days and the time of the duration later than the given date and time. The first argument needs to be a valid date. + +??? note "Example query for `xsd:date + dayTimeDuration`" + + The date 2025-05-26 at 00:49:30 is 10 days, 49 minutes and 30 seconds later than the start date. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date ?duration ((?date + ?duration) AS ?difference) WHERE { + BIND("2025-05-16"^^xsd:date AS ?date) + BIND("P10DT0H49M30S"^^xsd:dayTimeDuration AS ?duration) + } + ``` + +`xsd:date + xsd:yearMonthDuration`: TODO: supported? + +`xsd:time + xsd:dayTimeDuration`: TODO: supported? + +`xsd:dateTime + xsd:dayTimeDuration`: +Returns the `xsd:dateTime` that is the amount of days and the time of the duration later than the given date and time. The first argument needs to be a valid date. + +??? note "Example query for `xsd:dateTime - dayTimeDuration`" + + The date 2000-01-01 is 7 days, 3 hours, 44 minutes and 30 seconds later than the start date and time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?dateTime ?duration ((?dateTime + ?duration) AS ?difference) WHERE { + BIND("1999-12-24T20:15:30Z"^^xsd:dateTime AS ?dateTime) + BIND("P7DT3H44M30S"^^xsd:dayTimeDuration AS ?duration) + } + ``` + +`xsd:dateTime + xsd:yearMonthDuration`: TODO: supported? From 0a90bb2f1eef12017a7c886ae1440186ad62cbc2 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Fri, 3 Apr 2026 16:57:58 +0200 Subject: [PATCH 03/10] Adding all operators from SEP0002 --- docs/datetime.md | 122 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 6 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 5bb147e..e5b3813 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -9,24 +9,134 @@ QLever supports the following `xsd` Date/Time datatypes: |--|--|--| |`xsd:time`|`"09:30:10Z"^^xsd:time`|A time containing hour, minute, and second.| |`xsd:date`|`"2025-12-24"^^xsd:date`|Simple date containing year, month and day. | -|`xsd:dateTime`|`"2025-12-24T18:11:00Z"^^xsd:dateTime`|Date combined with time (hour, minute, second, and timezone).| +|`xsd:dateTime`|`"2025-12-24T18:11:00Z"^^xsd:dateTime`|Date combined with time (hour, minute, second, and optional timezone).| |`xsd:duration`|`"P1Y2M1D"^^xsd:duration`|A time interval that may contain years, months, days and time components (hours, minutes, seconds).| |`xsd:dayTimeDuration`|`"P2DT4H5M6S"^^xsd:dayTimeDuration`|A time interval consisting of days and time components (hours, minutes, seconds).| |`xsd:yearMonthDuration`|`"P12Y2M"^^xsd:yearMonthDuration`|A time interval consisting of years and months.| -|`xsd:gYear`|`"12000"^^xsd:gYear`|A (potentially large) year.| +|`xsd:gYear`|`"12000"^^xsd:gYear`|A (potentially large) year. Negative years are also allowed.| TODO: time und yearMonthDuration supported? ## Arithmetics -### == +### = -### != +`xsd:duration = xsd:duration`: +??? note "Example query for `xsd:duration = xsd:duration`" + + The first two durations are equal. The third duration has an additional year. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?duration1 ?duration2 ?duration3 ?eq ?neq + WHERE { + BIND("P1Y2M1D"^^xsd:duration AS ?duration1) + BIND("P1Y2M1D"^^xsd:duration AS ?duration2) + BIND("P2Y2M1D"^^xsd:duration AS ?duration3) + BIND(?duration1 = ?duration2 AS ?eq) + BIND(?duration1 = ?duration3 AS ?neq) + } + ``` + +`xsd:date = xsd:date`: +??? note "Example query for `xsd:date = xsd:date`" + + The first two dates are equal. The third date is from another year. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?date3 ?eq ?neq + WHERE { + BIND("2025-12-24"^^xsd:date AS ?date1) + BIND("2025-12-24"^^xsd:date AS ?date2) + BIND("1925-12-24"^^xsd:date AS ?date3) + BIND(?date1 = ?date2 AS ?eq) + BIND(?date1 = ?date3 AS ?neq) + } + ``` + +`xsd:time = xsd:time`: TODO: supported? ### < +`xsd:yearMonthDuration < xsd:yearMonthDuration`: TODO: supported? + +`xsd:dayTimeDuration < xsd:dayTimeDuration`: +??? note "Example query for `xsd:dayTimeDuration < xsd:dayTimeDuration`" + + The first duration is smaller than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?duration1 ?duration2 ?lt1 ?lt2 + WHERE { + BIND("P2DT4H5M6S"^^xsd:dayTimeDuration AS ?duration1) + BIND("P4DT4H5M6S"^^xsd:dayTimeDuration AS ?duration2) + + BIND(?duration1 < ?duration2 AS ?lt1) + BIND(?duration2 < ?duration1 AS ?lt2) + } + ``` + +`xsd:date < xsd:date`: +??? note "Example query for `xsd:date < xsd:date`" + + The first date is earlier than the second date. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?lt1 ?lt2 + WHERE { + BIND("2019-12-31"^^xsd:date AS ?date1) + BIND("2020-03-13"^^xsd:date AS ?date2) + + BIND(?date1 < ?date2 AS ?lt1) + BIND(?date2 < ?date1 AS ?lt2) + } + ``` + +`xsd:time < xsd:time`: TODO: supported? + ### > +`xsd:yearMonthDuration > xsd:yearMonthDuration`: TODO: supported? + +`xsd:dayTimeDuration > xsd:dayTimeDuration`: +??? note "Example query for `xsd:dayTimeDuration > xsd:dayTimeDuration`" + + The first duration is larger than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?duration1 ?duration2 ?gt1 ?gt2 + WHERE { + BIND("P4DT4H5M6S"^^xsd:dayTimeDuration AS ?duration1) + BIND("P2DT4H5M6S"^^xsd:dayTimeDuration AS ?duration2) + + BIND(?duration1 > ?duration2 AS ?gt1) + BIND(?duration2 > ?duration1 AS ?gt2) + } + ``` + +`xsd:date > xsd:date`: +??? note "Example query for `xsd:date > xsd:date`" + + The first date is later than the second date. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?gt1 ?gt2 + WHERE { + BIND("2020-03-13"^^xsd:date AS ?date1) + BIND("2019-12-31"^^xsd:date AS ?date2) + + BIND(?date1 > ?date2 AS ?gt1) + BIND(?date2 > ?date1 AS ?gt2) + } + ``` + +`xsd:time > xsd:time`: TODO: supported? + ### Subtraction `xsd:date - xsd:date`: @@ -47,7 +157,7 @@ Returns the `xsd:dayTimeDuration` between the two dates. The arguments need to b ``` `xsd:date - xsd:dayTimeDuration`: -Returns the `xsd:dateTime` that is the amount of days and the time of the duration earlier than the given date. The first argument needs to be a valid date. +Returns the `xsd:dateTime` that is the amount of days and the time of the duration earlier than the given date. The first argument needs to be a valid date. If the duration only specifies days the time of the result date is set to `00:00:00`. ??? note "Example query for `xsd:date - dayTimeDuration`" @@ -125,7 +235,7 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati `xsd:dateTime + xsd:dayTimeDuration`: Returns the `xsd:dateTime` that is the amount of days and the time of the duration later than the given date and time. The first argument needs to be a valid date. -??? note "Example query for `xsd:dateTime - dayTimeDuration`" +??? note "Example query for `xsd:dateTime + dayTimeDuration`" The date 2000-01-01 is 7 days, 3 hours, 44 minutes and 30 seconds later than the start date and time. From 0ac4c66f0dddc257138b401509cd167ada5fbab2 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Sat, 4 Apr 2026 13:51:26 +0200 Subject: [PATCH 04/10] Added datetime to nav. Added some more examples --- docs/datetime.md | 53 +++++++++++++++++++++++++++++++++++++++++++++--- mkdocs.yml | 1 + 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index e5b3813..1475bd4 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -17,6 +17,8 @@ QLever supports the following `xsd` Date/Time datatypes: TODO: time und yearMonthDuration supported? +TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mit TimeZone). + ## Arithmetics ### = @@ -55,11 +57,41 @@ TODO: time und yearMonthDuration supported? } ``` -`xsd:time = xsd:time`: TODO: supported? +`xsd:time = xsd:time`: TODO: does only work if the string representations are equal, not if the timezones are different. +??? note "Example query for `xsd:time = xsd:time`" + + The first two times are equal. The third time is two hours earlier. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?time1 ?time2 ?time3 ?eq ?neq + WHERE { + BIND("09:30:10Z"^^xsd:time AS ?time1) + BIND("09:30:10Z"^^xsd:time AS ?time2) + BIND("07:30:10Z"^^xsd:time AS ?time3) + BIND(?time1 = ?time2 AS ?eq) + BIND(?time1 = ?time3 AS ?neq) + } + ``` ### < -`xsd:yearMonthDuration < xsd:yearMonthDuration`: TODO: supported? +`xsd:yearMonthDuration < xsd:yearMonthDuration`: +??? note "Example query for `xsd:yearMonthDuration < xsd:yearMonthDuration`" + + The first duration is smaller than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?duration1 ?duration2 ?lt1 ?lt2 + WHERE { + BIND("P12Y2M"^^xsd:yearMonthDuration AS ?duration1) + BIND("P14Y2M"^^xsd:yearMonthDuration AS ?duration2) + + BIND(?duration1 < ?duration2 AS ?lt1) + BIND(?duration2 < ?duration1 AS ?lt2) + } + ``` `xsd:dayTimeDuration < xsd:dayTimeDuration`: ??? note "Example query for `xsd:dayTimeDuration < xsd:dayTimeDuration`" @@ -95,7 +127,22 @@ TODO: time und yearMonthDuration supported? } ``` -`xsd:time < xsd:time`: TODO: supported? +`xsd:time < xsd:time`: TODO: does not work correctly with timezones; same time UTC - 6 < UTC + 4 is not correct. +??? note "Example query for `xsd:time < xsd:time`" + + The first time is two hours and one minute earlier than the second time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?time1 ?time2 ?lt1 ?lt2 + WHERE { + BIND("09:30:10Z"^^xsd:time AS ?time1) + BIND("11:31:10Z"^^xsd:time AS ?time2) + + BIND(?time1 < ?time2 AS ?lt1) + BIND(?time2 < ?time1 AS ?lt2) + } + ``` ### > diff --git a/mkdocs.yml b/mkdocs.yml index 2013b74..b9f3d1b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -17,6 +17,7 @@ nav: - Reference: - Qleverfile settings: qleverfile.md - GeoSPARQL support: geosparql.md + - Date and Time operations: datetime.md - Update: update.md - Materialized Views: materialized-views.md - Rebuild index: rebuild-index.md From 2744f6efe5b1d0cbedb96fe80b5d2ef9afc677f1 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Wed, 8 Apr 2026 13:36:33 +0200 Subject: [PATCH 05/10] Added examples for all valid operations from SEP --- docs/datetime.md | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 1475bd4..3938fa9 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -76,7 +76,7 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi ### < -`xsd:yearMonthDuration < xsd:yearMonthDuration`: +`xsd:yearMonthDuration < xsd:yearMonthDuration`: TODO: this only works with same digits -> P2Y2M < P14Y2M does not work correctly ??? note "Example query for `xsd:yearMonthDuration < xsd:yearMonthDuration`" The first duration is smaller than the second. @@ -146,7 +146,22 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi ### > -`xsd:yearMonthDuration > xsd:yearMonthDuration`: TODO: supported? +`xsd:yearMonthDuration > xsd:yearMonthDuration`: TODO: this only works with same digits -> P12Y2M > P9Y2M does not work correctly +??? note "Example query for `xsd:yearMonthDuration > xsd:yearMonthDuration`" + + The first duration is larger than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?duration1 ?duration2 ?gt1 ?gt2 + WHERE { + BIND("P12Y2M"^^xsd:yearMonthDuration AS ?duration1) + BIND("P10Y2M"^^xsd:yearMonthDuration AS ?duration2) + + BIND(?duration1 > ?duration2 AS ?gt1) + BIND(?duration2 > ?duration1 AS ?gt2) + } + ``` `xsd:dayTimeDuration > xsd:dayTimeDuration`: ??? note "Example query for `xsd:dayTimeDuration > xsd:dayTimeDuration`" @@ -182,7 +197,22 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:time > xsd:time`: TODO: supported? +`xsd:time > xsd:time`: TODO: does not work correctly with timezones +??? note "Example query for `xsd:time > xsd:time`" + + The first time is four hours, one minute, and two seconds later than the second time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?time1 ?time2 ?gt1 ?gt2 + WHERE { + BIND("14:31:12Z"^^xsd:time AS ?time1) + BIND("10:30:10Z"^^xsd:time AS ?time2) + + BIND(?time1 > ?time2 AS ?gt1) + BIND(?time2 > ?time1 AS ?gt2) + } + ``` ### Subtraction From 322e11796670ca1d53c705fc60acdfba6559f0a2 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Wed, 8 Apr 2026 13:55:35 +0200 Subject: [PATCH 06/10] DateTime Operations that are not in SEP but supported --- docs/datetime.md | 55 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 3938fa9..9f9da29 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -21,7 +21,7 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi ## Arithmetics -### = +### Equality = `xsd:duration = xsd:duration`: ??? note "Example query for `xsd:duration = xsd:duration`" @@ -74,7 +74,24 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -### < +`xsd:dateTime = xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +??? note "Example query for `xsd:dateTime = xsd:dateTime`" + + The first two dates and times are equal. The third date has another time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?date3 ?eq ?neq + WHERE { + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date2) + BIND("2025-12-24T18:20:30Z"^^xsd:dateTime AS ?date3) + BIND(?date1 = ?date2 AS ?eq) + BIND(?date1 = ?date3 AS ?neq) + } + ``` + +### Less Than < `xsd:yearMonthDuration < xsd:yearMonthDuration`: TODO: this only works with same digits -> P2Y2M < P14Y2M does not work correctly ??? note "Example query for `xsd:yearMonthDuration < xsd:yearMonthDuration`" @@ -144,7 +161,23 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -### > +`xsd:dateTime < xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +??? note "Example query for `xsd:dateTime < xsd:dateTime`" + + The dates are equal, but the first time is earlier than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?lt1 ?lt2 + WHERE { + BIND("2025-12-24T14:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date2) + BIND(?date1 < ?date2 AS ?lt1) + BIND(?date2 < ?date1 AS ?lt2) + } + ``` + +### Greater Than > `xsd:yearMonthDuration > xsd:yearMonthDuration`: TODO: this only works with same digits -> P12Y2M > P9Y2M does not work correctly ??? note "Example query for `xsd:yearMonthDuration > xsd:yearMonthDuration`" @@ -214,6 +247,22 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` +`xsd:dateTime > xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +??? note "Example query for `xsd:dateTime > xsd:dateTime`" + + The dates are equal, but the first time is later than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?gt1 ?gt2 + WHERE { + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T14:15:00Z"^^xsd:dateTime AS ?date2) + BIND(?date1 > ?date2 AS ?gt1) + BIND(?date2 > ?date1 AS ?gt2) + } + ``` + ### Subtraction `xsd:date - xsd:date`: From fac72cd7ac508039cdba13edffa75a9e4e3105af Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Wed, 15 Apr 2026 14:29:18 +0200 Subject: [PATCH 07/10] Added note for timezone problem --- docs/datetime.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 9f9da29..ff94f46 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -57,7 +57,8 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:time = xsd:time`: TODO: does only work if the string representations are equal, not if the timezones are different. +`xsd:time = xsd:time`: +This operation does not handle different timezones correctly yet. For example `09:30:10Z` (UTC) and `08:30:10-01:00` (UTC - 1) will not be seen as equal. ??? note "Example query for `xsd:time = xsd:time`" The first two times are equal. The third time is two hours earlier. @@ -74,7 +75,9 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:dateTime = xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +`xsd:dateTime = xsd:dateTime`: +This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +This operation does not handle different timezones correctly yet. For example `2025-12-24T18:15:00Z` (UTC) and `2025-12-24T17:15:00-01:00` (UTC - 1) will not be seen as equal. ??? note "Example query for `xsd:dateTime = xsd:dateTime`" The first two dates and times are equal. The third date has another time. @@ -144,7 +147,8 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:time < xsd:time`: TODO: does not work correctly with timezones; same time UTC - 6 < UTC + 4 is not correct. +`xsd:time < xsd:time`: +This operation does not handle different timezones correctly yet. For example `09:30:10Z` (UTC) will not be seen as earlier than `08:30:10-02:00` (UTC - 2). ??? note "Example query for `xsd:time < xsd:time`" The first time is two hours and one minute earlier than the second time. @@ -161,7 +165,9 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:dateTime < xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +`xsd:dateTime < xsd:dateTime`: +This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +This operation does not handle different timezones correctly yet. For example `2025-12-24T14:15:00Z` (UTC) will not be seen as earlier than `2025-12-24T13:15:00-02:00` (UTC - 2). ??? note "Example query for `xsd:dateTime < xsd:dateTime`" The dates are equal, but the first time is earlier than the second. @@ -230,7 +236,8 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:time > xsd:time`: TODO: does not work correctly with timezones +`xsd:time > xsd:time`: +This operation does not handle different timezones correctly yet. For example `10:30:10Z` (UTC) will not be seen as later than `12:30:10+04:00` (UTC + 4). ??? note "Example query for `xsd:time > xsd:time`" The first time is four hours, one minute, and two seconds later than the second time. @@ -247,7 +254,9 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:dateTime > xsd:dateTime`: TODO: NOT IN SEP; Timezone Problem +`xsd:dateTime > xsd:dateTime`: +This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +This operation does not handle different timezones correctly yet. For example `2025-12-24T10:30:10Z` (UTC) will not be seen as later than `2025-12-24T12:30:10+04:00` (UTC + 4). ??? note "Example query for `xsd:dateTime > xsd:dateTime`" The dates are equal, but the first time is later than the second. From 0e17f972e59f373e48e0d00a3df4bf2cf3acde60 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Fri, 17 Apr 2026 15:42:00 +0200 Subject: [PATCH 08/10] Further documentation --- docs/datetime.md | 76 ++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 60 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index ff94f46..38b471f 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -7,23 +7,20 @@ QLever supports the following `xsd` Date/Time datatypes: | Type | Example | Description | |--|--|--| -|`xsd:time`|`"09:30:10Z"^^xsd:time`|A time containing hour, minute, and second.| |`xsd:date`|`"2025-12-24"^^xsd:date`|Simple date containing year, month and day. | |`xsd:dateTime`|`"2025-12-24T18:11:00Z"^^xsd:dateTime`|Date combined with time (hour, minute, second, and optional timezone).| |`xsd:duration`|`"P1Y2M1D"^^xsd:duration`|A time interval that may contain years, months, days and time components (hours, minutes, seconds).| |`xsd:dayTimeDuration`|`"P2DT4H5M6S"^^xsd:dayTimeDuration`|A time interval consisting of days and time components (hours, minutes, seconds).| -|`xsd:yearMonthDuration`|`"P12Y2M"^^xsd:yearMonthDuration`|A time interval consisting of years and months.| |`xsd:gYear`|`"12000"^^xsd:gYear`|A (potentially large) year. Negative years are also allowed.| -TODO: time und yearMonthDuration supported? - -TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mit TimeZone). +The datatypes `xsd:time` and `xsd:yearMonthDuration` are not supported. ## Arithmetics ### Equality = +The following datatypes can be tested for equality: -`xsd:duration = xsd:duration`: +`xsd:duration = xsd:duration`: Two durations are equal if all their components (years, months, days, hours, minutes, seconds) are identical. ??? note "Example query for `xsd:duration = xsd:duration`" The first two durations are equal. The third duration has an additional year. @@ -40,7 +37,7 @@ TODO: dateTime = < > ist auch supported aber nicht im SEP (auch hier Probleme mi } ``` -`xsd:date = xsd:date`: +`xsd:date = xsd:date`: Two dates are equal if they represent the same year, month, and day. ??? note "Example query for `xsd:date = xsd:date`" The first two dates are equal. The third date is from another year. @@ -77,6 +74,7 @@ This operation does not handle different timezones correctly yet. For example `0 `xsd:dateTime = xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +Two `dateTime` objects are equal if the date parts are equal and the time parts are equal. This operation does not handle different timezones correctly yet. For example `2025-12-24T18:15:00Z` (UTC) and `2025-12-24T17:15:00-01:00` (UTC - 1) will not be seen as equal. ??? note "Example query for `xsd:dateTime = xsd:dateTime`" @@ -95,25 +93,9 @@ This operation does not handle different timezones correctly yet. For example `2 ``` ### Less Than < +The following datatypes can be compared to each other using the less than: -`xsd:yearMonthDuration < xsd:yearMonthDuration`: TODO: this only works with same digits -> P2Y2M < P14Y2M does not work correctly -??? note "Example query for `xsd:yearMonthDuration < xsd:yearMonthDuration`" - - The first duration is smaller than the second. - - ```sparql {data-demo-engine="osm-planet"} - PREFIX xsd: - SELECT ?duration1 ?duration2 ?lt1 ?lt2 - WHERE { - BIND("P12Y2M"^^xsd:yearMonthDuration AS ?duration1) - BIND("P14Y2M"^^xsd:yearMonthDuration AS ?duration2) - - BIND(?duration1 < ?duration2 AS ?lt1) - BIND(?duration2 < ?duration1 AS ?lt2) - } - ``` - -`xsd:dayTimeDuration < xsd:dayTimeDuration`: +`xsd:dayTimeDuration < xsd:dayTimeDuration`: Returns `true` if the first duration is smaller than the second (first checking for days and then time). ??? note "Example query for `xsd:dayTimeDuration < xsd:dayTimeDuration`" The first duration is smaller than the second. @@ -130,7 +112,7 @@ This operation does not handle different timezones correctly yet. For example `2 } ``` -`xsd:date < xsd:date`: +`xsd:date < xsd:date`: Returns `true` if the first date is earlier in time than the second date. ??? note "Example query for `xsd:date < xsd:date`" The first date is earlier than the second date. @@ -166,7 +148,8 @@ This operation does not handle different timezones correctly yet. For example `0 ``` `xsd:dateTime < xsd:dateTime`: -This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +Returns `true` if the first date is earlier in time than the second date or if the dates are equal and the first time is earlier than the second time. This operation does not handle different timezones correctly yet. For example `2025-12-24T14:15:00Z` (UTC) will not be seen as earlier than `2025-12-24T13:15:00-02:00` (UTC - 2). ??? note "Example query for `xsd:dateTime < xsd:dateTime`" @@ -184,25 +167,9 @@ This operation does not handle different timezones correctly yet. For example `2 ``` ### Greater Than > +The following datatypes can be compared to each other using the greater than: -`xsd:yearMonthDuration > xsd:yearMonthDuration`: TODO: this only works with same digits -> P12Y2M > P9Y2M does not work correctly -??? note "Example query for `xsd:yearMonthDuration > xsd:yearMonthDuration`" - - The first duration is larger than the second. - - ```sparql {data-demo-engine="osm-planet"} - PREFIX xsd: - SELECT ?duration1 ?duration2 ?gt1 ?gt2 - WHERE { - BIND("P12Y2M"^^xsd:yearMonthDuration AS ?duration1) - BIND("P10Y2M"^^xsd:yearMonthDuration AS ?duration2) - - BIND(?duration1 > ?duration2 AS ?gt1) - BIND(?duration2 > ?duration1 AS ?gt2) - } - ``` - -`xsd:dayTimeDuration > xsd:dayTimeDuration`: +`xsd:dayTimeDuration > xsd:dayTimeDuration`: Returns `true` if the first duration is larger than the second (first checking for days and then time). ??? note "Example query for `xsd:dayTimeDuration > xsd:dayTimeDuration`" The first duration is larger than the second. @@ -219,7 +186,7 @@ This operation does not handle different timezones correctly yet. For example `2 } ``` -`xsd:date > xsd:date`: +`xsd:date > xsd:date`: Returns `true` if the first date is later in time than the second date. ??? note "Example query for `xsd:date > xsd:date`" The first date is later than the second date. @@ -256,6 +223,7 @@ This operation does not handle different timezones correctly yet. For example `1 `xsd:dateTime > xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. +Returns `true` if the first date is later in time than the second date or if the dates are equal and the first time is later than the second time. This operation does not handle different timezones correctly yet. For example `2025-12-24T10:30:10Z` (UTC) will not be seen as later than `2025-12-24T12:30:10+04:00` (UTC + 4). ??? note "Example query for `xsd:dateTime > xsd:dateTime`" @@ -273,6 +241,7 @@ This operation does not handle different timezones correctly yet. For example `2 ``` ### Subtraction +The following combinations of datatypes can be used in subtractions: `xsd:date - xsd:date`: Returns the `xsd:dayTimeDuration` between the two dates. The arguments need to be valid dates (e.g. `"2025-02-30"^^xsd:date` is not allowed). @@ -306,11 +275,6 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati } ``` -`xsd:date - xsd:yearMonthDuration`: TODO: supported? - -`xsd:time - xsd:time`: TODO: supported? -`xsd:time - xsd:dayTimeDuration`: TODO: supported? - `xsd:dateTime - xsd:dateTime`: Returns the `xsd:dayTimeDuration` between the two date and their times. The arguments need to be valid dates. @@ -343,10 +307,8 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati ``` -`xsd:dateTime - xsd:yearMonthDuration`: TODO: supported? - - ### Addition +The following combinations of datatypes can be used in additions: `xsd:date + xsd:dayTimeDuration`: Returns the `xsd:dateTime` that is the amount of days and the time of the duration later than the given date and time. The first argument needs to be a valid date. @@ -363,10 +325,6 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati } ``` -`xsd:date + xsd:yearMonthDuration`: TODO: supported? - -`xsd:time + xsd:dayTimeDuration`: TODO: supported? - `xsd:dateTime + xsd:dayTimeDuration`: Returns the `xsd:dateTime` that is the amount of days and the time of the duration later than the given date and time. The first argument needs to be a valid date. @@ -381,5 +339,3 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati BIND("P7DT3H44M30S"^^xsd:dayTimeDuration AS ?duration) } ``` - -`xsd:dateTime + xsd:yearMonthDuration`: TODO: supported? From 66af4ec403f38e9a1e5383e25ec32cbf300d74b6 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Thu, 23 Apr 2026 15:17:14 +0200 Subject: [PATCH 09/10] Added examples to use ql:toEpoch --- docs/datetime.md | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index 38b471f..f90e2d1 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -75,7 +75,6 @@ This operation does not handle different timezones correctly yet. For example `0 `xsd:dateTime = xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. Two `dateTime` objects are equal if the date parts are equal and the time parts are equal. -This operation does not handle different timezones correctly yet. For example `2025-12-24T18:15:00Z` (UTC) and `2025-12-24T17:15:00-01:00` (UTC - 1) will not be seen as equal. ??? note "Example query for `xsd:dateTime = xsd:dateTime`" The first two dates and times are equal. The third date has another time. @@ -91,6 +90,21 @@ This operation does not handle different timezones correctly yet. For example `2 BIND(?date1 = ?date3 AS ?neq) } ``` +Different timezones can be handled correctly by first converting the date and time into an Epoch time. +??? note "Example query for `xsd:dateTime = xsd:dateTime` using `ql:toEpoch()`" + + The first two dates are equal. The times differ, but the represent the same point in time. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?neqWithoutEpoch ?eqWithEpoch + WHERE { + BIND("2025-12-24T18:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T17:15:00-01:00"^^xsd:dateTime AS ?date2) + BIND(?date1 = ?date2 AS ?neqWithoutEpoch) + BIND(ql:toEpoch(?date1) = ql:toEpoch(?date2) AS ?eqWithEpoch) + } + ``` ### Less Than < The following datatypes can be compared to each other using the less than: @@ -150,7 +164,6 @@ This operation does not handle different timezones correctly yet. For example `0 `xsd:dateTime < xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. Returns `true` if the first date is earlier in time than the second date or if the dates are equal and the first time is earlier than the second time. -This operation does not handle different timezones correctly yet. For example `2025-12-24T14:15:00Z` (UTC) will not be seen as earlier than `2025-12-24T13:15:00-02:00` (UTC - 2). ??? note "Example query for `xsd:dateTime < xsd:dateTime`" The dates are equal, but the first time is earlier than the second. @@ -165,6 +178,21 @@ This operation does not handle different timezones correctly yet. For example `2 BIND(?date2 < ?date1 AS ?lt2) } ``` +Different timezones can be handled correctly by first converting the date and time into an Epoch time. +??? note "Example query for `xsd:dateTime < xsd:dateTime` using `ql:toEpoch()`" + + The dates are equal, but the first time is earlier than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?lt1 ?lt2 + WHERE { + BIND("2025-12-24T14:15:00Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T13:15:00-02:00"^^xsd:dateTime AS ?date2) + BIND(ql:toEpoch(?date1) < ql:toEpoch(?date2) AS ?lt1) + BIND(ql:toEpoch(?date2) < ql:toEpoch(?date1) AS ?lt2) + } + ``` ### Greater Than > The following datatypes can be compared to each other using the greater than: @@ -224,7 +252,6 @@ This operation does not handle different timezones correctly yet. For example `1 `xsd:dateTime > xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. Returns `true` if the first date is later in time than the second date or if the dates are equal and the first time is later than the second time. -This operation does not handle different timezones correctly yet. For example `2025-12-24T10:30:10Z` (UTC) will not be seen as later than `2025-12-24T12:30:10+04:00` (UTC + 4). ??? note "Example query for `xsd:dateTime > xsd:dateTime`" The dates are equal, but the first time is later than the second. @@ -239,6 +266,21 @@ This operation does not handle different timezones correctly yet. For example `2 BIND(?date2 > ?date1 AS ?gt2) } ``` +Different timezones can be handled correctly by first converting the date and time into an Epoch time. +??? note "Example query for `xsd:dateTime > xsd:dateTime` using `ql:toEpoch()`" + + The dates are equal, but the first time is later than the second. + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?date1 ?date2 ?gt1 ?gt2 + WHERE { + BIND("2025-12-24T10:30:10Z"^^xsd:dateTime AS ?date1) + BIND("2025-12-24T12:30:10+04:00"^^xsd:dateTime AS ?date2) + BIND(ql:toEpoch(?date1) > ql:toEpoch(?date2) AS ?gt1) + BIND(ql:toEpoch(?date2) > ql:toEpoch(?date1) AS ?gt2) + } + ``` ### Subtraction The following combinations of datatypes can be used in subtractions: From 52a0e4209db3b09cf583196260e709d4cc3b0523 Mon Sep 17 00:00:00 2001 From: Yannik Schnell Date: Mon, 4 May 2026 18:04:55 +0200 Subject: [PATCH 10/10] Added sections (SPARQL standard, toEpoch, limitations) --- docs/datetime.md | 66 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/docs/datetime.md b/docs/datetime.md index f90e2d1..56d1420 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -2,6 +2,22 @@ This page describes which features from the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md) are supported in QLever, and how to use them. +## Standard SPARQL functions +The following date or time functions are standard in SPARQL and therefore supported in QLever: + +| Function | Type of output | Description | +|--|--|--| +| `NOW ()` | `xsd:dateTime` | Returns the current date and time. | +| `YEAR (xsd:dateTime arg)` | `xsd:integer` | Returns the year part of the `arg`. | +| `MONTH (xsd:dateTime arg)` | `xsd:integer` | Returns the month part of the `arg`. | +| `DAY (xsd:dateTime arg)` | `xsd:integer` | Returns the day part of the `arg`. | +| `HOURS (xsd:dateTime arg)` | `xsd:integer` | Returns the hours of the time specified in `arg`. | +| `MINUTES (xsd:dateTime arg)` | `xsd:integer` | Returns the minutes of the time specified in `arg`. | +| `SECONDS (xsd:dateTime arg)` | `xsd:decimal` | Returns the seconds of the time specified in `arg`. | +| `TIMEZONE (xsd:dateTime arg)` | `xsd:dayTimeDuration` | Returns the timezone specified in `arg` as part of a duration. | +| `TZ (xsd:dateTime arg)` | `literal` | Returns the timezone specified in `arg`. | + + ## Datatypes QLever supports the following `xsd` Date/Time datatypes: @@ -54,8 +70,8 @@ The following datatypes can be tested for equality: } ``` -`xsd:time = xsd:time`: -This operation does not handle different timezones correctly yet. For example `09:30:10Z` (UTC) and `08:30:10-01:00` (UTC - 1) will not be seen as equal. +`xsd:time = xsd:time`: +Two times are equal if they describe the same timepoint. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:time = xsd:time`" The first two times are equal. The third time is two hours earlier. @@ -74,7 +90,7 @@ This operation does not handle different timezones correctly yet. For example `0 `xsd:dateTime = xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. -Two `dateTime` objects are equal if the date parts are equal and the time parts are equal. +Two `dateTime` objects are equal if the date parts are equal and the time parts are equal. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:dateTime = xsd:dateTime`" The first two dates and times are equal. The third date has another time. @@ -90,7 +106,7 @@ Two `dateTime` objects are equal if the date parts are equal and the time parts BIND(?date1 = ?date3 AS ?neq) } ``` -Different timezones can be handled correctly by first converting the date and time into an Epoch time. +Different timezones can be handled correctly by first converting the date and time into an Epoch time. (See [`ql:toEpoch`](#toepoch)) ??? note "Example query for `xsd:dateTime = xsd:dateTime` using `ql:toEpoch()`" The first two dates are equal. The times differ, but the represent the same point in time. @@ -144,7 +160,7 @@ The following datatypes can be compared to each other using the less than: ``` `xsd:time < xsd:time`: -This operation does not handle different timezones correctly yet. For example `09:30:10Z` (UTC) will not be seen as earlier than `08:30:10-02:00` (UTC - 2). +Returns `true`if the first time is earlier than the second time. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:time < xsd:time`" The first time is two hours and one minute earlier than the second time. @@ -163,7 +179,7 @@ This operation does not handle different timezones correctly yet. For example `0 `xsd:dateTime < xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. -Returns `true` if the first date is earlier in time than the second date or if the dates are equal and the first time is earlier than the second time. +Returns `true` if the first date is earlier in time than the second date or if the dates are equal and the first time is earlier than the second time. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:dateTime < xsd:dateTime`" The dates are equal, but the first time is earlier than the second. @@ -178,7 +194,7 @@ Returns `true` if the first date is earlier in time than the second date or if t BIND(?date2 < ?date1 AS ?lt2) } ``` -Different timezones can be handled correctly by first converting the date and time into an Epoch time. +Different timezones can be handled correctly by first converting the date and time into an Epoch time. (See [`ql:toEpoch`](#toepoch)) ??? note "Example query for `xsd:dateTime < xsd:dateTime` using `ql:toEpoch()`" The dates are equal, but the first time is earlier than the second. @@ -232,7 +248,7 @@ The following datatypes can be compared to each other using the greater than: ``` `xsd:time > xsd:time`: -This operation does not handle different timezones correctly yet. For example `10:30:10Z` (UTC) will not be seen as later than `12:30:10+04:00` (UTC + 4). +Returns `true` if the first date is later than the second time. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:time > xsd:time`" The first time is four hours, one minute, and two seconds later than the second time. @@ -251,7 +267,7 @@ This operation does not handle different timezones correctly yet. For example `1 `xsd:dateTime > xsd:dateTime`: This is **not part of the [SEP-0002](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md)**, but still supported. -Returns `true` if the first date is later in time than the second date or if the dates are equal and the first time is later than the second time. +Returns `true` if the first date is later in time than the second date or if the dates are equal and the first time is later than the second time. (See also [current limitations](#current-limitations)) ??? note "Example query for `xsd:dateTime > xsd:dateTime`" The dates are equal, but the first time is later than the second. @@ -266,7 +282,7 @@ Returns `true` if the first date is later in time than the second date or if the BIND(?date2 > ?date1 AS ?gt2) } ``` -Different timezones can be handled correctly by first converting the date and time into an Epoch time. +Different timezones can be handled correctly by first converting the date and time into an Epoch time. (See [`ql:toEpoch`](#toepoch)) ??? note "Example query for `xsd:dateTime > xsd:dateTime` using `ql:toEpoch()`" The dates are equal, but the first time is later than the second. @@ -381,3 +397,33 @@ Returns the `xsd:dateTime` that is the amount of days and the time of the durati BIND("P7DT3H44M30S"^^xsd:dayTimeDuration AS ?duration) } ``` + +## Additional Functionality + +### toEpoch +The built-in function `ql:toEpoch (xsd:dateTime)` / `ql:toEpoch (xsd:date)` can be used to extract the UTC Epoch time as a `xsd:integer`. This enables accurate comparisions between different dates as seen above. The function returns the amount of seconds passed since `"1970-01-01T00:00:00Z"^^xsd:dateTime` (UTC). + +??? note "Example query for `ql:toEpoch`" + + The first date is exactly the start of the epoch time. The second is 120 seconds after and the third 120 seconds before + + ```sparql {data-demo-engine="osm-planet"} + PREFIX xsd: + SELECT ?epoch1 ?epoch2 ?epoch3 WHERE { + BIND("1970-01-01T00:00:00Z"^^xsd:dateTime AS ?dateTime1) + BIND("1970-01-01T00:02:00Z"^^xsd:dateTime AS ?dateTime2) + BIND("1969-12-31T23:58:00Z"^^xsd:dateTime AS ?dateTime3) + BIND(ql:toEpoch(?dateTime1) AS ?epoch1) + BIND(ql:toEpoch(?dateTime2) AS ?epoch2) + BIND(ql:toEpoch(?dateTime3) AS ?epoch3) + } + ``` + +## Current Limitations +For many operations (`=`, `<`, `>`) with `xsd:time`, `xsd:dateTime` timezones are not handled correctly yet. Here are some examples: +- `09:30:10Z` (UTC) and `08:30:10-01:00` (UTC - 1) will not be seen as equal (`xsd:time`). +- `09:30:10Z` (UTC) will not be seen as earlier than `08:30:10-02:00` (UTC - 2) (`xsd:time`). +- `2025-12-24T14:15:00Z` (UTC) will not be seen as earlier than `2025-12-24T13:15:00-02:00` (UTC - 2) (without using [`ql:toEpoch`](#toepoch)) (`xsd:dateTime`). +- `10:30:10Z` (UTC) will not be seen as later than `12:30:10+04:00` (UTC + 4) (`xsd:time`). + +