# Date filter fails for (?today \<= xsd:date(NOW()))

**URL:** <https://community.stardog.com/t/date-filter-fails-for-today-xsd-date-now/1922>\
**Category:** Bug\
**Created:** [September 20, 2019, 9:36am UTC](https://community.stardog.com/t/date-filter-fails-for-today-xsd-date-now/1922 "2019-09-20T09:36:35Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![evren](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.stardog.com/evren/32/1515_2.png) [@evren](https://community.stardog.com/u/evren)\
**Post date:** [September 21, 2019, 1:29am UTC](https://community.stardog.com/t/date-filter-fails-for-today-xsd-date-now/1922/3 "2019-09-21T01:29:55Z")

</div>

Kathrin, Zachary,

Welcome to the confusing world of dates and times! Let's start with the `xsd:date()` function which actually returns an `xsd:date` value as expected. That is the lexical representation of an `xsd:date` value that contains a time zone (yes, that's a thing). The `xsd:date` casting function is not defined in the SPARQL spec (which only defines the [`xsd:dateTime()`](https://www.w3.org/TR/sparql11-query/#FunctionMapping) cast) but Stardog supports `xsd:date()` cast based on the [`XPath definition`](https://www.w3.org/TR/xpath-functions-30/#casting-to-datetimes).

So `xsd:date(NOW())` works fine but there are two other problems with the query:

1. The filter with `?today` is inside an OPTIONAL that has no BGPs. Based on the bottom-up semantics of SPARQL the variable `?today` is not bound inside that optional and the filter will always return false. Instead of using an OPTIONAL and two BINDs we can simply use `BIND (?today <= xsd:date(NOW()) AS ?works)` but...

2. The string functions used at the beginning are stripping the time zone away. Then we end up comparing a date with a timezone and a date without a timezone. The XSD spec defines a partial order on date and time values due to the ambiguity introduced by missing timezones. These comparisons might return an "indeterminate" result unless the difference between dates is larger than the max timezone difference possible. Indeterminate result is equivalent to raising an error and it would cause filters to fail or variables in bind expressions to be left unbound. The following illustrates how some comparisons might not bind a value:

```auto
select * {
    bind("2019-09-20-04:00"^^xsd:date AS ?today)
    bind("2019-09-19"^^xsd:date <= ?today as ?x)
    bind("2019-09-20"^^xsd:date <= ?today as ?y)
    bind("2019-09-20-04:00"^^xsd:date <= ?today as ?z)
}

+------------------------------+-------+-------+-------+
| today | x | y | z |
+------------------------------+-------+-------+-------+
| "2019-09-20-04:00"^^xsd:date | true | | true |
+------------------------------+-------+-------+-------+

```

You should always try to compare date/time values that are in the same timezone or no date/time should have a timezone. A single timezone is totally ordered within itself and would not have these problems. For this specific query this would mean either not stripping the timezone using the string functions at the beginning or doing the same thing every time. Stardog's [stored functions](https://www.stardog.com/docs/#_managing_stored_functions) can be useful if you'll repeatedly use the same function patterns.

There are even more issues related to mixing timezones if you are not confused enough:

- Stardog uses Java's built-in [`XMLGregorianCalendar`](https://docs.oracle.com/javase/7/docs/api/javax/xml/datatype/XMLGregorianCalendar.html) implementation which seems to behave strangely with missing timezones and comparing dates from different timezones. It also follows the older XSD 1.0 spec and not the latest XSD 1.1 spec. We are looking into moving to a new implementation that conforms to the XSD 1.1 spec.

- Things get even more complicated when date subtraction comes into play because subtraction results might be inconsistent with comparison results when there are missing timezones. This is due to the fact that [XPath `subtract-dates`](https://www.w3.org/TR/xpath-functions-30/#func-subtract-dates) function that Stardog uses. XPath says every date/time missing a timezone should be automatically added an implicit timezone from a [dynamic context](https://www.w3.org/TR/xpath-30/#id-xp-evaluation-context-components) for subtraction. Stardog initializes the dynamic context with the timezone of the server. This means even though two date/time values are incomparable you can subtract them and get a result but the result will depend on the locale.

I think it is appropriate to end this message with the following XKCD reference:

> **[Supervillain Plan](https://xkcd.com/1883/)**
>
> Someday, some big historical event will happen during the DST changeover, and all the tick-tock articles chronicling how it unfolded will have to include a really annoying explanation next to their timelines.

Have a good weekend,  
Evren

---

_[View the full topic](https://community.stardog.com/t/date-filter-fails-for-today-xsd-date-now/1922)._
