tl;dr : datetime 不能处理那种事情,所以不要尝试。你有字符串,保留它们并照此对待它们。
您可以简单地将它们排序为字符串,只要它们具有一致的长度(否则根据需要填充)和格式。这将允许对“扩展的” ISO8601:2004 时间戳进行排序(按照标准00
,月份和日期是不允许的)。
假设 Python3,这段代码:
import urllib.request,json
url = urllib.request.urlopen("https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=Q90&props=info%7Caliases%7Clabels%7Cdescriptions%7Cclaims%7Cdatatype%7Csitelinks%2Furls&languages=fr&languagefallback=1&formatversion=2")
data = json.loads(url.read().decode())
P6 = sorted(data['entities']['Q90']['claims']['P6'], key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'])
for x in P6:
print(x['mainsnak']['datavalue']['value']['numeric-id'])
产生这个结果集:
1685301
947901
656015
2596877
3131449
1986521
1685102
1684642
601266
677730
289303
959708
2105
1685859
256294
2851133
此外,您需要将列表分成两部分:
然后按月-日期-时间升序对第一个列表进行排序,然后按由字符串表示的年份的无符号整数值(保证为“稳定”sort()
) ,对第二个列表进行简单排序,然后再次将它们连接起来。这将允许对签名的ISO8601 时间戳进行正确排序。sorted()
neg = [x for x in P6 if x['qualifiers']['P580'][0]['datavalue']['value']['time'].startswith('-') ]
pos = [x for x in P6 if x['qualifiers']['P580'][0]['datavalue']['value']['time'].startswith('+') ]
neg.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'][5:])
neg.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'][1:5])
pos.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'])
P6sorted = neg+pos
至于填充,如果需要,使用它就足够微不足道了string.rjust()
(尽管您必须稍微改变排序以反映“新”时间戳的长度;string.zfill()
不是该工作的正确工具,因为您是改变不是数字,有'T'、'Z'、'-'和':'):
maxlength = max( map( lambda claim: len( claim['qualifiers']['P580'][0]['datavalue']['value']['time'] ), P6 ) )
for claim in P6:
claim['qualifiers']['P580'][0]['datavalue']['value']['time'] = claim['qualifiers']['P580'][0]['datavalue']['value']['time'][0] + claim['qualifiers']['P580'][0]['datavalue']['value']['time'][1:].rjust(maxlength-1, "0");
neg = [x for x in P6 if x['qualifiers']['P580'][0]['datavalue']['value']['time'].startswith('-') ]
pos = [x for x in P6 if x['qualifiers']['P580'][0]['datavalue']['value']['time'].startswith('+') ]
neg.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'][maxlength-16:])
neg.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'][maxlength-22:maxlength-16], reverse=True)
pos.sort(key=lambda claim: claim['qualifiers']['P580'][0]['datavalue']['value']['time'])
P6sorted = neg+pos
for claim in P6sorted:
print([claim['mainsnak']['datavalue']['value']['id'],claim['qualifiers']['P580'][0]['datavalue']['value']['time']])
顺便说一句,为了可读性,您可能想要“装饰-排序-不装饰”(执行 Schwartzian 变换)。
最后,如果您担心儒略历和公历,则必须通过添加相应的天数将儒略日期转换为基于国家和年份的公历日期,并应用上述方法。但请记住,儒略历 (YYYY)-(MM)-(DD) 早于“似乎提前一天”的公历日期,所以真的不应该太担心。