【问题标题】:In SparQL, how to distinguish a year like 2017, and January 1st, 2017?在 SparQL 中,如何区分 2017 年和 2017 年 1 月 1 日这样的年份?
【发布时间】:2017-04-20 08:39:10
【问题描述】:

以下使用WikidataREST API 的SPARQL 查询都返回xsd:datetime 类型的日期,日期为1 月1 日:

>>> # Inception of Manchester United F.C. = in 1875
>>> wikidata_rest_query("SELECT ?date WHERE { wd:Q18656 wdt:P571 ?date }")
{'head': {'vars': ['date']},
 'results': {'bindings': [{'date': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
     'type': 'literal',
     'value': '1875-01-01T00:00:00Z'}}]}}

>>> # Istanbul nightclub attack = on January 1st 2017
>>> wikidata_rest_query("SELECT ?date WHERE { wd:Q28094271 wdt:P585 ?date }")
{'head': {'vars': ['date']},
 'results': {'bindings': [{'date': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
     'type': 'literal',
     'value': '2017-01-01T00:00:00Z'}}]}}

在第一种情况下,日期仅表示“1875 年”,而不是字面意义上的 1875 年 1 月 1 日午夜。在第二种情况下,日期实际上是指“2017 年 1 月 1 日”,但不是特别指午夜。我会更喜欢“1875”和“2017-01-01”这样的回复。

在浏览这些主题(Manchester United F.C.2017 Istanbul Night Club Attack)的 Wikidata 页面时,会显示正确的详细程度(即第一种情况是 1875,但第二种情况是 2017 年 1 月 1 日),因此它们必须在他们的数据库中有正确的信息,希望有办法查询它。

有什么想法吗?

注意

我尝试查询datatype(?date),希望看到不同之处,但在两个示例中它都返回xsd:datetime

编辑

这里是wikidata_rest_query()的python 3代码,如果你想测试上面的查询:

from urllib.request import urlopen, quote
import json

def wikidata_rest_query(query):
    url = "https://query.wikidata.org/sparql?query=%s&format=json" % quote(query)
    with urlopen(url) as f:
        response = f.read().decode("utf-8")
    return json.loads(response)

【问题讨论】:

  • 后端 (Blazegraph) 可能会将所有数据值返回为 xsd:dateTime,尽管在内部某些值确实是 xsd:date 类型 - 但这只是一个猜测。
  • 确实,我担心他们有数据,但他们返回错误。也许有办法查询type(?date),这样我就可以在客户端解决问题?
  • 我刚刚找到了解决方案,请查看我的答案。 :)

标签: datetime sparql wikidata wikidata-api


【解决方案1】:

Wikidata 通过存储有关每个xsd:datetime 的附加信息解决了这个问题,尤其是timePrecision

>>> query = """
... SELECT ?time ?timeprecision ?timezone ?timecalendar WHERE {
...     wd:Q18656 p:P571/psv:P571 ?timenode.
...     ?timenode wikibase:timeValue         ?time.
...     ?timenode wikibase:timePrecision     ?timeprecision.
...     ?timenode wikibase:timeTimezone      ?timezone.
...     ?timenode wikibase:timeCalendarModel ?timecalendar.
... }
... """
>>> wikidata_rest_query(query)
{'head': {'vars': ['time', 'timeprecision', 'timezone', 'timecalendar']},
 'results': {'bindings': [{'time': {'datatype': 'http://www.w3.org/2001/XMLSchema#dateTime',
     'type': 'literal',
     'value': '1875-01-01T00:00:00Z'},
    'timecalendar': {'type': 'uri',
     'value': 'http://www.wikidata.org/entity/Q1985727'},
    'timeprecision': {'datatype': 'http://www.w3.org/2001/XMLSchema#integer',
     'type': 'literal',
     'value': '9'},
    'timezone': {'datatype': 'http://www.w3.org/2001/XMLSchema#integer',
     'type': 'literal',
     'value': '0'}}]}}

timePrecision 等于 9,表示 。其他可能的精度是listed here:

精度的代码是0:十亿年,1:亿年 年,3:百万年,4:十万年,5:万年 年,6:千年,7:世纪,8:十年,9:年,10:月,11: 日,12:小时,13:分钟,14:秒。

如果您尝试伊斯坦布尔查询,您将得到一个等于 11: 天的timePrecision,正如预期的那样。

如果我们只写timePrecision(?date) 肯定会更简单,但这就是生活,至少我们有一个解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    相关资源
    最近更新 更多