【问题标题】:Remove time from datetime in spaqrl从 sparql 中的日期时间中删除时间
【发布时间】:2016-04-14 17:40:53
【问题描述】:

我正在SPARQL 中编写查询,我想比较没有时间的日期值。目前,我得到了一个日期时间值,例如2014-08-14T13:00:00Z。但是,我想对日期进行过滤,例如

FILTER (?date = "2014-08-15"^^xsd:dateTime)

我是 SPARQL 的新手,所以我需要一些帮助。谢谢。

已编辑


感谢大家的回复。我为xsd:dateTime道歉

FILTER (?date = "2014-08-15"^^xsd:date)

尽管我想要一个更“漂亮”的解决方案,但我还是决定尝试以下方法。

FILTER (?date >= "2014-08-15T00:00:00Z"^^xsd:dateTime && ?date <= "2014-08-15T24:00:00Z"^^xsd:dateTime)

【问题讨论】:

  • 请注意"2014-08-15"^^xsd:dateTime 可能不是合法的日期时间,即使它是合法的xsd:date
  • 建议改用"2014-08-15"^^xsd:date

标签: sparql owl ontology rdfs


【解决方案1】:

您可以这样做,但不完全按照您的问题提出的方式。 dateTimes 的文字形式必须包含所有字段(时区除外),因此 "2014-08-15"^^xsd:dateTime 实际上不是合法的 dateTime。有关日期时间格式的更多信息,请参阅the definition

也就是说,很容易从日期时间中提取年、月和日,然后将它们重新组合成一个可以与其他日期进行比较的日期:

prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select ?dt ?date where {
  values ?dt { "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime }

  bind(xsd:date(concat(str(year(?dt)),"-",
                       str(month(?dt)),"-",
                       str(day(?dt))))
       as ?date)
}
--------------------------------------------------------------------------
| dt                                            | date                   |
==========================================================================
| "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime | "2011-01-10"^^xsd:date |
--------------------------------------------------------------------------

如果您想包含时区,您也可以这样做;它们在 xsd:dates 中是允许的。

如果您想在不创建新日期的情况下进行过滤,您也可以执行类似的操作

filter (year(?dt) = 2015 &&
        month(?dt) = 01 &&
        day(?dt) = 10)

这可能是一个相当干净的解决方案。

不过,请注意关于您的过滤器。您可以像以前一样根据常量过滤变量的值,但这通常(但并非总是)建议一种更简单的方法。例如,而不是:

select ?s where {
  ?s a ?o .
  filter ( ?o = <something> )
}

您通常只使用适当的值,或使用 values 来指定变量的值:

select ?s where {
  ?s a <something> .
}
select ?s where {
  values ?o { <something> }
  ?s a ?o .
}

【讨论】:

    【解决方案2】:

    您可以尝试对xsd:date 进行简单的强制转换,但 SPARQL 引擎可能会保留时间。所以它变成了解析的问题。一种方法是只使用SUBSTR,因为字符数是已知的:

    FILTER (xsd:date(SUBSTR(str(?date), 0, 11)) = "2014-08-15"^^xsd:date)
    

    另一个是从日期时间格式构建日期:

    FILTER (xsd:date(CONCAT(str(YEAR(?date)), "-", str(MONTH(?date)), "-", str(DAY(?date)))) = "2014-08-15"^^xsd:date)
    

    考虑到CONCAT 需要字符串转换,可能不太方便,但总体思路是从日期时间值构建字符串并转换为xsd:date

    【讨论】:

    • 请注意,substr 解决方案(以及您和我都使用的字符串连接)的弱点在于它们不包含时区,并且时区 允许在xsd:日期。
    • 我没有掌握所有的日期算法,但是一个时区中的 YYYY-MM-DD 是否可能与另一个时区中的 YYYY-MM-DD+1 日期相同?保留这些时区可能很重要。
    • 是的,这似乎是一个不同的话题,并且很大程度上取决于时间是如何产生的以及需要进行哪些比较。总是可以添加偏移量以达到 UTC。
    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2017-07-10
    • 2019-07-05
    • 1970-01-01
    相关资源
    最近更新 更多