datetimexpathxqueryxpath-3.0

Round time in Xpath


What is the simplest and correct way to round the time and dateTime in XPath?

For example, how to define a function local:round-time-to-minutes in such way that the following test-case:

let $t1 := xs:time( "12:58:37" )
let $t2 := local:round-time-to-minutes( $t1 )
return format-time( $t2, '[H01]:[m01]:[s01]' )

will return "12:59:00". Don't sure what is better in case of "23:59:31" — to return "00:00:00" or to raise a dynamic error.

And similar function local:round-datetime-to-minutes to handle dateTime? (it doesn't have such edge case as above)

Let these functions use "round half towards positive infinity" rule, where half is 30.0 seconds.


Solution

  • Another solution is to subtract the number of second from the given dateTime and add one minute (60 seconds) if the number of seconds is not less than 30.

    To convert a number of seconds into duration we multiple it on 1S duration (actually, this operation can be eliminated by a compiler).

    declare function local:round-time-to-minutes ( $time as xs:time ) {
      let $s := seconds-from-time( $time )
      return $time - xs:dayTimeDuration('PT1S') * ( $s - 60 * ($s idiv 30) )
    };
    
    declare function local:round-dateTime-to-minutes ( $dt as xs:dateTime ) {
      let $s := seconds-from-dateTime( $dt )
      return $dt - xs:dayTimeDuration('PT1S') * ( $s - 60 * ($s idiv 30) )
    };
    

    This solution is uniform for the cases of xs:time and xs:dateTime types.