Xpath 中的循环时间
Round time in Xpath
在 XPath 中舍入时间和日期时间的最简单和正确的方法是什么?
例如,如何定义一个函数 local:round-time-to-minutes
使得下面的测试用例:
let $t1 := xs:time( "12:58:37" )
let $t2 := local:round-time-to-minutes( $t1 )
return format-time( $t2, '[H01]:[m01]:[s01]' )
将 return "12:59:00"
。
不确定在“23:59:31”的情况下什么更好——return“00:00:00”或引发动态错误。
和处理日期时间的类似函数local:round-datetime-to-minutes
?
(它没有像上面这样的边缘情况)
让这些函数使用 "round half towards positive infinity" 规则,其中一半是 30.0 秒。
这是@michael.hor257k 提出的解决方案在 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
};
另一种解决方案是从给定的日期时间中减去秒数,如果秒数不小于 30,则增加一分钟(60 秒)。
为了将秒数转换为持续时间,我们将其乘以 1S
持续时间(实际上,编译器可以消除此操作)。
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) )
};
此解决方案对于 xs:time
和 xs:dateTime
类型的情况是统一的。
在 XPath 中舍入时间和日期时间的最简单和正确的方法是什么?
例如,如何定义一个函数 local:round-time-to-minutes
使得下面的测试用例:
let $t1 := xs:time( "12:58:37" )
let $t2 := local:round-time-to-minutes( $t1 )
return format-time( $t2, '[H01]:[m01]:[s01]' )
将 return "12:59:00"
。
不确定在“23:59:31”的情况下什么更好——return“00:00:00”或引发动态错误。
和处理日期时间的类似函数local:round-datetime-to-minutes
?
(它没有像上面这样的边缘情况)
让这些函数使用 "round half towards positive infinity" 规则,其中一半是 30.0 秒。
这是@michael.hor257k 提出的解决方案在 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
};
另一种解决方案是从给定的日期时间中减去秒数,如果秒数不小于 30,则增加一分钟(60 秒)。
为了将秒数转换为持续时间,我们将其乘以 1S
持续时间(实际上,编译器可以消除此操作)。
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) )
};
此解决方案对于 xs:time
和 xs:dateTime
类型的情况是统一的。