Reputation:
I am writing a query in SPARQL
and I want to compare the date value without the time. Currently, I am getting a datetime value such as 2014-08-14T13:00:00Z
. However, I want to do a filter on the date such as
FILTER (?date = "2014-08-15"^^xsd:dateTime)
I am new to SPARQL, so I need some help. Thanks.
EDITED
Thanks for the response guys. My apologies for the xsd:dateTime
FILTER (?date = "2014-08-15"^^xsd:date)
I have decided to try the following although I wanted a much 'prettier' solution.
FILTER (?date >= "2014-08-15T00:00:00Z"^^xsd:dateTime && ?date <= "2014-08-15T24:00:00Z"^^xsd:dateTime)
Upvotes: 3
Views: 1395
Reputation: 85813
You can do this, but not exactly the way your question asks. The literal forms for dateTimes have to have all the fields (except the timezone), so "2014-08-15"^^xsd:dateTime isn't actually a legal dateTime. See the definition for more about the date time format.
That said, it's easy enough to pull out the year, month, and day from a datetime and put them back together into a date that you can compare with other dates:
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?dt ?date where {
values ?dt { "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime }
bind(xsd:date(concat(str(year(?dt)),"-",
str(month(?dt)),"-",
str(day(?dt))))
as ?date)
}
--------------------------------------------------------------------------
| dt | date |
==========================================================================
| "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime | "2011-01-10"^^xsd:date |
--------------------------------------------------------------------------
If you want to include the timezone, you can do that too; they're permitted in xsd:dates.
If you wanted to filter without creating the new date, you could also do something like
filter (year(?dt) = 2015 &&
month(?dt) = 01 &&
day(?dt) = 10)
That might be a fairly clean solution.
A note about your filter, though. You can filter the value of a variable against a constant like you did, but that often (but not always) suggests an easier way. For instance, instead of:
select ?s where {
?s a ?o .
filter ( ?o = <something> )
}
you'd usually just use the value in place, or use values to specify the value of a variable:
select ?s where {
?s a <something> .
}
select ?s where {
values ?o { <something> }
?s a ?o .
}
Upvotes: 3
Reputation: 4001
You could try a simple cast to xsd:date
, but the SPARQL engine will likely retain the time. So it becomes a matter of parsing. One way is to just use SUBSTR
, as the number of characters is known:
FILTER (xsd:date(SUBSTR(str(?date), 0, 11)) = "2014-08-15"^^xsd:date)
Another is to build the date from datetime format:
FILTER (xsd:date(CONCAT(str(YEAR(?date)), "-", str(MONTH(?date)), "-", str(DAY(?date)))) = "2014-08-15"^^xsd:date)
Perhaps not as convenient given that CONCAT
requires string conversion, but the general idea is to build the string from the datetime value and cast to xsd:date
.
Upvotes: 1