Reputation: 71
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
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