You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python解析年-周数字符串时%W与%U的结果不一致问题

Python datetime中%W与%U解析年周字符串的不一致问题及原因

正常解析情况

from datetime import datetime

print("\nISO周:") # ISO标准周(周一为起始,周数从1开始)
for i in range(1,8): # %u 是1-based(1=周一,7=周日)
    print(datetime.strptime(f"2019-01-{i}", "%G-%V-%u"))
# 输出:
# 2018-12-31 00:00:00
# 2019-01-01 00:00:00
# 2019-01-02 00:00:00
# ...  
    
# %U -> 以周日为一周起始的年度周数
# 2019年第一个周日是2019-01-06
print("\n%U格式解析:")    
for i in range(0,7): # %w 是0-based(0=周日,6=周六)
    print(datetime.strptime(f"2019-01-{i}", "%Y-%U-%w"))
# 输出:
# 2019-01-06 00:00:00
# 2019-01-07 00:00:00
# 2019-01-08 00:00:00
# ...  

异常情况

# %W -> 以周一为一周起始的年度周数
# 2019年第一个周一是2019-01-07
print("\n%W格式解析:")    
for i in range(0,7):
    print(datetime.strptime(f"2019-01-{i}", "%Y-%W-%w"))
# 输出:
# 2019-01-13 00:00:00 ## <-- 预期为2019-01-06
# 2019-01-07 00:00:00 
# 2019-01-08 00:00:00
# 2019-01-09 00:00:00
# 2019-01-10 00:00:00
# 2019-01-11 00:00:00
# 2019-01-12 00:00:00

问题原因分析

1. Python datetime的%W逻辑细节

Python的%W格式符规则是:以周一为一周起始,新年中第一个周一之前的所有日期都归为第0周。而%w格式符的定义固定为0代表周日、6代表周六,和周数的起始日无关。

在测试场景中:

  • 2019年第一个周一是1月7日,因此1月1日至1月6日都属于%W的第0周,1月7日起进入第1周。
  • 当解析"2019-01-0"时,%W=01(第1周)、%w=0(周日),对应第1周的最后一天——1月13日(第1周从1月7日周一到1月13日周日),这就是第一个输出结果的由来。
  • 若要解析1月6日(第0周的周日),需使用%W=00,比如执行datetime.strptime("2019-00-0", "%Y-%W-%w")会返回2019-01-06。

对比%U的逻辑:
%U是以周日为一周起始,新年中第一个周日之前的日期属于第0周。2019年第一个周日是1月6日,因此"2019-01-0"对应第1周的周日(1月6日),后续日期依次递增,符合预期。

2. Rust chrono库报错的原因

chrono库对日期组合的有效性校验更严格:当用%W(周一为起始的周数)搭配%w=0(周日)解析2019-01-0时,它会校验该周数对应的星期是否存在。由于2019年第1周从1月7日周一才开始,该周的周日是1月13日,输入的%w=0无法对应第1周的有效日期,因此chrono判定该组合无效并抛出错误。

内容的提问来源于stack exchange,提问作者FObersteiner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:55:35