【问题标题】:ValueError: day is out of range for month - How to do math with dates that are in different months [duplicate]ValueError:日期超出月份的范围-如何使用不同月份的日期进行数学运算[重复]
【发布时间】:2021-11-29 17:34:55
【问题描述】:

我有一个 python 程序,它将一年中的星期作为输入,格式为:YYYY-W# 该程序使用此输入为一周中的每一天生成值并将数据输出到 Excel 文件。

我收到错误消息:ValueError: day is out of range for month,我意识到当一周中的几天在不同的月份(例如,星期一、星期二是 11 月,星期三、星期四等是 12 月)时,我会收到此错误。

以下代码是我获取星期几的值的方式:

monday = datetime.datetime.strptime(week + '-1', '%G-W%V-%u')
tuesday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 1)
wednesday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 2)
thursday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 3)
friday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 4)
saturday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 5)
sunday = datetime.datetime(monday.year, monday.month, monday.day - monday.weekday() + 6)

如果整周都在同一个月内,此代码可以正常工作,有没有办法修改它以考虑可能不在同一个月内的周?

【问题讨论】:

    标签: python datetime


    【解决方案1】:

    使用timedelta:

    tuesday = monday + datetime.timedelta(days=1)
    wednesday = ... # (and so on)
    

    【讨论】:

    • 有没有办法独立于今天的日子来做到这一点?例如,如果我做monday = datetime.datetime.strptime('2021-W47')) 不是本周而是前一周,那么我做tuesday = monday + datetime.timedelta(days=1) 我得到的是本周的星期二而不是前一周的星期二
    • 检查您的代码。如果您找不到错误,也许可以在其他问题中打印它。我的代码总是从指定的一周获得星期二。当然会在第 52 周进入明年。
    • 我最终只使用了这个:days_in_week = [datetime.datetime.strptime(week + str(x), "%G-W%V-%u") for x in range(-7,0)] 来解决问题,虽然 timedelta 确实有效
    【解决方案2】:

    结合Get date from week number的(轻微)重复问题中的答案和Rustam A.的答案:

    from datetime import datetime, timedelta
    
    d = "2021-W48"
    monday = datetime.strptime(d + "-1", "%Y-W%W-%w")
    week = [monday + timedelta(days=x) for x in range(7)]
    
    print(week)
    # [datetime.datetime(2021, 11, 29, 0, 0), datetime.datetime(2021, 11, 30, 0, 0), datetime.datetime(2021, 12, 1, 0, 0), datetime.datetime(2021, 12, 2, 0, 0), datetime.datetime(2021, 12, 3, 0, 0), datetime.datetime(2021, 12, 4, 0, 0), datetime.datetime(2021, 12, 5, 0, 0)]
    

    (编辑:使用 ISO 周时,请像您一样使用 %G-W%V-%u

    【讨论】:

    • 我唯一的问题是我对另一个答案的评论是,使用 timdelta 会返回当前一周的日期,但星期一可能是一年中的任何一周
    • 正如 Rustam A. 提到的,首先仔细检查星期一是否正确创建。我的答案中的代码确实给了我正确的日期。您在 Rustam A. 的评论中得到了答案。似乎可以完成这项工作(如您所说);它类似于我的答案中的代码,尽管它解析用户输入 7 次(而不是一次 - 请参阅我的答案)并执行字符串操作而不是 timedeltas。这是设计上的不同,但不管怎样,很高兴你能成功!
    猜你喜欢
    • 2023-03-12
    • 2017-07-29
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多