在有 53 周的年份中,Python 的 `datetime.strptime` 是否存在周数错误?

Is Python's `datetime.strptime` buggy for week numbers on years with 53 weeks?

我正在使用 Python 2.7,我正在尝试将周数转换为实际日期。

我使用的是 this 解决方案,它对基础测试非常有效,但我发现了一个似乎有中断的情况:在有 53 周的年份中。

下面的例子说明了这个问题:

datetime.datetime.strptime( "2015-W53-0", "%Y-W%W-%w").strftime("%Y-W%W-%w")

这个returns'2016-W01-0',我觉得没有意义。

这是一个已知问题吗,是否有已知的解决方法?

注意:

datetime.datetime.strptime( "2015-W53-0", "%Y-W%W-%w").isocalendar()

产生 (2016, 1, 7),所以这里可能 strptime 猜错了。

%W 是一年中的第几周,包含星期一的第一周算作第 1 周。

一周的第一天是星期一,%w 天数为 1。一周的最后一天是星期日,天数为 0。所以在这个计算中 %Y-%W -0 总是比 %Y-%W-1 晚六天。

按此计算,第 52 周从 12 月 28 日开始,并且不包含星期日。所以 2015-W52-0 被解释为 2016 年的第一个星期日(1 月 3 日)。由于这是在第一个星期一之前,因此 2015-W52-0 是规范的 2016-W00-0,而 2015-W53-0 是 2016 年的第二个星期日,即第 1 周结束时,即 1 月 10 日,或 2016-W01 -0.

因此这些方法的工作方式为 documented

%W 和 %w 没有实现 ISO 周日期算法,该算法将第一周设置为包含星期四的那一周。 2015 年包含 ISO 方法的第 53 周,但不是 %W 方法。如果你想使用 ISO 工作日,你应该使用 isocalendar

由于 python 的标准实现只是调用 C 库函数,您可以根据 ISO 算法使用 %G(年份)和 %V(周数)。但是这些不能保证便携。

我实际上找到了一个名为 isoweek 的好库,它可以正常工作。

#This is Week 53 of 2015 according to ISO
week = isoweek.Week.withdate( datetime.date( 2016,1,1) )
monday = week.monday()
print monday.isocalendar()
#Prints (2015, 53, 1), which is correct.

我认为这是处理这些问题的最简单方法。