Re: time arithmatic in SPARQL

Jon,

A dateTime might look like: "2008-10-09T14:15:32+0100"

"1215-03-21" isn't the right form for a dateTime and so in the cast in 
the FILTER

xsd:dateTime("1215-10-15")

it should throw an error because the cast is of a lexical form that is 
not legal for a dateTime.  Errors will cause the current row to be rejected.

Just  xsd:date("1215-02-01")  should work if the cast is supported 
(rdflib supports xsd:date IIRC)

It can also be written:  "1215-02-01"^^xsd:date


 > EXCEPT in the case of a duration that starts 1215-10-14 and ends 
1215-11-01.

This query explicitly tests for specific start and finish:

PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX  loc:  <http://simile.mit.edu/2005/05/ontologies/location#>
PREFIX  crm:  <http://cidoc.ics.forth.gr/rdfs/cidoc_v4.2.rdfs#>
PREFIX  place: <http://jjcrump.itinerary.king.john/place#>

SELECT DISTINCT *
WHERE
{
    ?event  crm:P116F.starts  ?start .
    ?event  crm:P115F.finishes  ?finish .
     FILTER ( ?start = "1208-01-05"^^xsd:date &&
              ?finish  = "1208-01-06"^^xsd:date)
     }

This pattern grabs ?start and ?finish for the event.

You can negate the filter

     FILTER (  ! ( ?start = "1208-01-05"^^xsd:date &&
                  ?finish  = "1208-01-06"^^xsd:date) )

operators < <= etc should work.

 >       {?event crm:P117F.occurs_during ?date .}
 > UNION {?event crm:P116F.starts ?date .}
 > UNION {?event crm:P115F.finishes ?date .}

This pattern will not make the start and finish available to a filter in 
the same row.  It create a table of 2 columns, "event"  and "date" and 
puts the "starts" date in a different row to "finishes" date and the 
FILTER sees rows one at a time (no cross row comparison).

Did you mean something like:

         {?event crm:P117F.occurs_during ?date .}
   UNION { ?event crm:P116F.starts ?start ;
                  crm:P115F.finishes ?finish .
         }
(maybe decide which of start or finish you might use as "the" date and 
place ?date in one of the positions. )

The filter can then go inside the


         {?event crm:P117F.occurs_during ?date .}
   UNION { ?event crm:P116F.starts ?start ;
                  crm:P115F.finishes ?finish .
           FILTER (  ! ( ?start = "1208-01-05"^^xsd:date &&
                  ?finish  = "1208-01-06"^^xsd:date) )
         }

as it only applies to the start/finish case.

Hope that helps and I haven't mangled your question too badly,

	Andy



Jon Crump wrote:
> All,
> 
> With limited programming experience, I've been using the python module 
> rdflib to familiarize myself with SPARQL and have what is probably a 
> naive question, I hope you'll bear with me.
> 
> I have an RDF graph that looks, in part, like this:
> 
> <E5.Event 
> rdf:about="http://jjcrump.itinerary.king.john/Event#75599bf70a3a036ef0b6c8b1ef331c2704fe648e">
>   <P117F.occurs_during 
> rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1215-03-21</P117F.occurs_during>
>   <P11F.had_participant 
> rdf:resource="http://jjcrump.itinerary.king.john/person/king_john"/>
>   <P7F.took_place_at 
> rdf:resource="http://jjcrump.itinerary.king.john/place#geddington_northamptonshire"/>
> </E5.Event>
> 
> <E5.Event 
> rdf:about="http://jjcrump.itinerary.king.john/Event#7577d039daff5397bc5c4d8c671432fa0cdedaa1">
>   <P115F.finishes 
> rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1208-01-06</P115F.finishes>
>   <P116F.starts 
> rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1208-01-05</P116F.starts>
>   <P11F.had_participant 
> rdf:resource="http://jjcrump.itinerary.king.john/person/king_john"/>
>   <P7F.took_place_at 
> rdf:resource="http://jjcrump.itinerary.king.john/place#burbage_wiltshire"/>
> </E5.Event>
> 
> ie. Instants have a single property for date, durations have start/end 
> properties. I'm trying to construct a query that returns all events that 
> fall within, or intersect with a date range.
> 
> This, for example, works:
> 
> PREFIX loc: <http://simile.mit.edu/2005/05/ontologies/location#>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX place: <http://jjcrump.itinerary.king.john/place#>
> PREFIX crm: <http://cidoc.ics.forth.gr/rdfs/cidoc_v4.2.rdfs#>
> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
> 
> SELECT DISTINCT ?event ?place
> WHERE {{?event crm:P117F.occurs_during ?date .} 
> UNION {?event crm:P116F.starts ?date .}
> UNION {?event crm:P115F.finishes ?date .}
> OPTIONAL { ?event crm:P7F.took_place_at ?place .}
> FILTER (xsd:dateTime(?date) >= xsd:dateTime("1215-10-15")
> && xsd:dateTime(?date) <= xsd:dateTime("1215-10-31") )}
> 
> EXCEPT in the case of a duration that starts 1215-10-14 and ends 1215-11-01.
> 
> Is there any kind of arithmetic that can be done in the filter clause 
> that will catch this case as well?
> 
> Many thanks for your patience,
> Jon

-- 
Hewlett-Packard Limited
Registered Office: Cain Road, Bracknell, Berks RG12 1HN
Registered No: 690597 England

Received on Thursday, 9 October 2008 19:12:33 UTC