Search code examples
sparqldbpedia

How to convert xsd:Date into xsd:DateTime in SPARQL (dbpedia)?


I want to get data about people including their birthdate and their deathdate from DBpedia, but for dates, the type returned is xsd:Date when I need the date in xsd:DateTime format.

Can we convert the result (xsd:Date) to xsd:DateTime in the query? If yes, how?

  • xsd:Date --> "1940-01-01"
  • xsd:DateTime --> "1940-01-01T00:00:00"

I tried the query below, but it's not working ...

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 

SELECT ?person ?name ?birthDate ?deathDate
WHERE { 
    ?person rdf:type <http://dbpedia.org/ontology/Person> 
    ?person rdfs:label ?name.
    ?person dbo:birthDate ?birthDate.
    ?person dbo:deathDate ?deathDate.   
    strdt(concat(substr(?birthDate, 7, 4), '-', substr(?birthDate, 1, 2), '-', substr(?birthDate, 4, 2), 'T00:00:00'), xsd:dateTime).
    strdt(concat(substr(?deathDate, 7, 4), '-', substr(?deathDate, 1, 2), '-', substr(?deathDate, 4, 2), 'T00:00:00'), xsd:dateTime). 
    } 

Thank you!


Solution

  • (As an answer, since the comment isn't very readable)

    As AKSW says, the data is slightly broken (e.g. '1800-1-1') and virtuoso complains if you try to cast xsd:dateTime(?birthDate). Because of a virtuoso quirk you can't use the more pleasant coalesce(xsd:dateTime(?birthDate), ?birthDate) which should return the first non-empty, non-error value.

    So we have to protect ourselves with a regex:

    if(
        regex(str(?birthDate), '\\d{4}-\\d\\d-\\d\\d'),
        xsd:dateTime(?birthDate),
        ?birthDate)
    

    That is: if the string value of ?birthDate is of the right form (4 digits - 2 digits - 2 digits) then cast, otherwise use the original value.

    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX dbo: <http://dbpedia.org/ontology/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
    
    SELECT ?person ?name 
        (if(regex(str(?birthDate), '\\d{4}-\\d\\d-\\d\\d'), xsd:dateTime(?birthDate), ?birthDate) as ?birthDateDT)
        (if(regex(str(?deathDate), '\\d{4}-\\d\\d-\\d\\d'), xsd:dateTime(?deathDate), ?deathDate) as ?deathDateDT)
    WHERE { 
        ?person rdf:type <http://dbpedia.org/ontology/Person> .
        ?person rdfs:label ?name.
        ?person dbo:birthDate ?birthDate.
        ?person dbo:deathDate ?deathDate.   
    }
    

    Try this in dbpedia