ruvim
ruvim

Reputation: 8544

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.

Upvotes: 1

Views: 441

Answers (2)

ruvim
ruvim

Reputation: 8544

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.

Upvotes: 0

Leo Wörteler
Leo Wörteler

Reputation: 4241

This is how the solution proposed by @michael.hor257k would look in XQuery:

declare variable $ONE_MIN := xs:dayTimeDuration("PT1M");
declare variable $MIDNIGHT := xs:time("00:00:00");

declare function local:round-time-to-minutes($time) {
  $MIDNIGHT + round(($time - $MIDNIGHT) div $ONE_MIN) * $ONE_MIN
};

Upvotes: 2

Related Questions