datetime - 在SparQL中,如何区分2017年和2017年1月1日这样的年份?

标签 datetime sparql wikidata wikidata-api

以下 SPARQL 查询使用 WikidataREST API两者都返回 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)的维基数据页面时,会显示正确的详细级别(即第一种情况是 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)

最佳答案

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 :

The codes for precision are 0: billion years, 1: hundred million years, 3: million years, 4: hundred thousand years, 5: ten thousand years, 6: millennium, 7: century, 8: decade, 9: year, 10: month, 11: day, 12: hour, 13: minute, 14: second.

如果您尝试 Istanbul 查询,您将获得等于 11: day 的 timePrecision,正如预期的那样。

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

关于datetime - 在SparQL中,如何区分2017年和2017年1月1日这样的年份?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43514388/

相关文章:

python 脚本卡在 results = sparql.query().convert() 处

sparql - 维基数据+SPARQL : lookup a company based on it's ticker symbol

sparql - 维基数据结果按类似于 PageRank 的方式排序

python - 我想将数据框中的时间戳更改为日期时间

python - 使用 ephem 计算 "Solar Noon",转换为本地时间

rdf - 如何使用 SPARQL 查找相似内容

sparql - 基于部分名称匹配检索维基数据 ID 候选者

python - 在非本地时区快速解析 Python 日期时间,调整夏令时

php - 如何仅从 DateTime 对象中获取日期?

sparql - PROTEGE:使用长度路径