datetime.datetime - 日期字段超出范围

3 投票
3 回答
8585 浏览
提问于 2025-04-17 17:26

我发现使用datetime.datetime对象处理日期非常有用,但现在我遇到了一个情况,datetime.datetime对我来说不太管用。在程序运行时,日期中的天数是动态计算的,这就是问题所在:

>>> datetime.datetime(2013, 2, 29, 10, 15)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day is out of range for month

好吧,二月份确实没有29天,但如果datetime能自动识别这一点并返回正确的对象,那就太好了。

datetime.datetime(2013, 3, 1, 10, 15)

那么,解决这个问题的最好方法是什么呢?我在寻找一个通用的解决方案,当天数超过了一个月可能有的天数时,应该怎么处理。

3 个回答

1

使用下个月的第一天,然后减去一天,这样就可以避免使用日历。

datetime.datetime(targetYear, targetMonth+1, 1) + dt.timedelta(days = -1)
6

来自Python的哲学:明确比隐含更好。当你犯错,比如试图创建一个无效的日期时,你需要明确地处理这个情况。

你如何处理这个错误完全取决于你的应用程序。你可以告诉用户发生了错误,或者试着把多出来的天数移到下个月,或者把日期限制在当前月份的最后一天。这些都是有效的选择,具体要看你的使用场景

下面的代码会把多出来的天数移到下个月。所以2013-02-30会变成2013-03-02。

import calendar
import datetime

try:
    dt = datetime.datetime(year, month, day, hour, minute)
except ValueError:
    # Oops, invalid date. Assume we can fix this by shifting this to the next month instead
    _, monthdays = calendar.monthrange(year, month)
    if monthdays < day:
        surplus = day - monthdays
        dt = datetime.datetime(year, month, monthdays, hour, minute) + datetime.timedelta(days=surplus)
3

在这种情况下,使用 try...except 有很多可以讨论的地方,但如果你只需要月份和天数的偏移量,可以这样做:

d = datetime.datetime(targetYear,targetMonth,1,hour,min,sec)
d = d + datetime.timedelta(days=targetDayOfMonth-1)

基本上,你可以把这个月的日期设置为1,因为每个月都有1号,然后再加上时间差,这样就能得到当前或未来某个月的正确日期。

d = datetime.datetime(2013, 2, 1, 10, 15) # day of the month is 1
# since the target day is the 29th and that is 28 days after the first
# subtract 1 before creating the timedelta.
d = d + datetime.timedelta(days=28) 
print d
# datetime.datetime(2013, 3, 1, 10, 15)

撰写回答