Luca
Luca

Reputation: 71

SPARQL query for average of time duration

How is it possible to compute in SPARQL the average of time durations? I am using durations expressed in xsd:duration e.g., "PT4H15M53S"^^xsd:duration The following query does not return anything:

SELECT (AVG(?Duration) AS ?avg)
    WHERE {
        ?Time        rdf:type       tl:Interval ;
                     tl:duration    ?Duration .
}

Upvotes: 0

Views: 355

Answers (1)

IS4
IS4

Reputation: 13197

It may not be very clean, but it is nonetheless compatible with standard SPARQL, if you use regular expressions to extract the components of the duration:

SELECT * WHERE {
  BIND("P20DT14H15M53S" AS ?duration)
  BIND(IF(STRSTARTS(?duration, "-"), -1, 1) AS ?coef)
  BIND(COALESCE(xsd:integer(REPLACE(?duration, "^.*[A-Z](\\d+)D.*$", "$1")), 0) AS ?d)
  BIND(COALESCE(xsd:integer(REPLACE(?duration, "^.*T(\\d+)H.*$", "$1")), 0) AS ?h)
  BIND(COALESCE(xsd:integer(REPLACE(?duration, "^.*T(?:|.*[A-Z])(\\d+)M.*$", "$1")), 0) AS ?m)
  BIND(COALESCE(xsd:decimal(REPLACE(?duration, "^.*T(?:|.*[A-Z])(\\d*\\.?\\d*)S.*$", "$1")), 0) AS ?s)
  BIND(?coef * ((((?d * 24 + ?h) * 60) + ?m) * 60 + ?s) AS ?total)
}

This converts the duration into the total number of seconds, which you can then use in any calculations you wish, and then convert that to duration in seconds.

Note that durations with month-based components will not be taken into account, since average is not defined for that subset (you cannot have fractional months). In other words, this only makes sense for values of xs:dayTimeDuration.

Upvotes: 1

Related Questions