如何用strptime从年份和周数获取日期?结果异常排查
为什么用strptime根据ISO周数获取周一日期会得到下一周的结果?
我尝试根据当前日期的ISO年份和周数获取对应周一的日期,但strptime返回了错误的日期。测试代码如下:
from datetime import date, datetime today = date.today() today_year = today.isocalendar()[0] today_weeknr = today.isocalendar()[1] print(today) print(today_year, today_weeknr) d = "{}-W{}-1".format(today_year, today_weeknr) monday_date = datetime.strptime(d, "%Y-W%W-%w").date() print(monday_date) print(monday_date.isocalendar()[1])
运行结果:
$ python test.py 2025-02-13 2025 7 2025-02-17 8
得到的日期居然属于下一周,这是为什么?
问题根源
你混淆了Python strptime中两种不同的周数格式符:
%W:表示本地周数(以周一为一周起始,范围00-53),它的周数计算规则是从当年的第一个周一开始计数,和ISO 8601标准的周数规则不一致。%V:表示ISO周数(符合ISO 8601标准,范围01-53),这才和date.isocalendar()返回的周数完全对应。
另外,%w代表的星期几规则是0=周日,1=周一…6=周六,而ISO标准中周一对应的格式符是%u(1=周一,7=周日)——虽然这里-1刚好能匹配周一,但结合错误的周数格式符,最终导致日期解析偏差。
解决方法
把解析格式改成%G-W%V-%u:
%G:ISO周对应的4位数年份(和isocalendar()[0]的结果一致)%V:ISO周数(和isocalendar()[1]的结果一致)%u:ISO标准的星期几(1代表周一)
修改后的代码:
from datetime import date, datetime today = date.today() today_year = today.isocalendar()[0] today_weeknr = today.isocalendar()[1] print(today) print(today_year, today_weeknr) d = "{}-W{}-1".format(today_year, today_weeknr) # 改用ISO周对应的格式符解析 monday_date = datetime.strptime(d, "%G-W%V-%u").date() print(monday_date) print(monday_date.isocalendar()[1])
运行后会得到正确的2025年第7周的周一:2025-02-10,对应的周数也会显示为7。
兼容性替代方案
如果你的Python版本低于3.6(%G和%V在3.6及以上版本才支持),可以直接通过日期计算得到ISO周的周一:
from datetime import date, timedelta today = date.today() year, week, day_of_week = today.isocalendar() # 当前日期减去(当前星期几-1)天,得到本周一 monday_date = today - timedelta(days=day_of_week - 1) print(monday_date) print(monday_date.isocalendar()[1])
这种方法不依赖strptime的特殊格式符,兼容性更好。
内容的提问来源于stack exchange,提问作者Harm
相关产品推荐
相关产品推荐

