【问题标题】:How to compare Dates in MarkLogic?如何比较 MarkLogic 中的日期?
【发布时间】:2018-07-13 09:54:07
【问题描述】:

我在 $doc 变量中有以下 XML

 let $doc := <root>
              <date>12/31/2016</date>
             </root>

我想获取这个日期并将其与今天的日期进行比较。它应该返回 True,但返回的是 false。

我正在使用以下代码-

let $doc := <root>
              <date>12/31/2016</date>
             </root>


let $date := $doc/date/text()
let $today :=fn:format-date(fn:current-date(),"[M01]/[D01]/[Y0001]")
return $date le $today

有什么建议吗?

【问题讨论】:

    标签: xquery marklogic


    【解决方案1】:

    您需要将日期字符串转换为 xs:date 才能以这种方式比较它们。使用fn:format-date() 格式化只会产生一个字符串,而fn:current-date() 返回一个xs:date。这个 sn-p 完成了你想要的,但你可能还想考虑在你的文档中以 xs:date 格式保存数据,即&lt;date&gt;2016-12-31&lt;/date&gt;

    let $doc := 
        <root>
            <date>12/31/2016</date>
        </root>
    let $date-string := $doc/date/text()
    let $date-parts := fn:tokenize($date-string,"/")
    
    (: rearrange date parts into yyyy-mm-dd string and cast as xs:date :)
    let $date := xs:date(fn:concat($date-parts[3],"-",$date-parts[1],"-",$date-parts[2]))
    
    let $today := fn:current-date()
    
    return $date le $today
    
    => false
    

    如果日期以 xs:date 格式保存,可以这样简化:

    let $doc := 
        <root>
            <date>2016-12-31</date>
        </root>
    
    return xs:date($doc/date/text()) le fn:current-date() 
    

    您还可以在日期元素上使用范围索引来利用cts:element-range-query() 来选择满足您所需条件的文档,等等。当日期以这种方式保留时。

    【讨论】:

    • Daldei 建议的 xdmp:parse-dateTime 也可以,但对文本月份最有用(2016 年 12 月 31 日)。像这样的日期很容易通过字符串操作来规范化。以下库能够处理许多奇怪的日期格式,为您解决一些麻烦:github.com/grtjn/ml-datetime
    【解决方案2】:

    您在代码中所做的是创建 2 个 xs:string 变量,然后对它们进行词法比较。 (例如“12/31/2016”与“mm/dd/yyyy”比较) 这将根据语言环境进行比较,因为字符串比较而不是日期比较。 只有少数格式可以在词法上与键入的日期值进行比较,xs:date 就是其中之一,它的格式是 YYYY-MM-DD,它具有在词法上和键入的日期上可比较的属性。 一般来说,最好不要依赖它,而是转换为 xs:date 或 xs:dateTime 并按 dateTime 值进行比较——过程相同,您需要使用 xdmp 将这些文本值强制转换为标准日期格式:parse-dateTime() 或给定手头格式的类似函数,或通过解析文本格式并生成 xs:date() 想要的格式。然后比较两个键入的日期值。

    https://docs.marklogic.com/xdmp:parse-dateTime

    【讨论】:

    • DALDEI- 谢谢你的澄清 :) 我现在明白了这个概念。
    【解决方案3】:

    我使用了以下方法-

    let $doc := <root>
              <date>12/31/2016</date>
             </root>
    
    
    let $date := fn:format-date(xs:date(xdmp:parse-dateTime([Y0001]/[M01]/[D01]",$doc/date/text())),"[Y0001]/[M01]/[D01]")
    let $today := fn:format-date(fn:current-date(),"[Y0001]/[M01]/[D01]")
    return $date le $today
    

    【讨论】:

    • 如果您取消 format-date 调用,上述方法同样适用。您可以直接比较 xs:date。
    • grtjn-谢谢 :)
    猜你喜欢
    • 2016-04-27
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    相关资源
    最近更新 更多