3

在处理日期时,我发现了非常有用的 datetime.datetime 对象,但是我现在遇到了 datime.datetime 对我不起作用的情况。在程序执行期间,day 字段是动态计算的,这就是问题所在:

>>> 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

好的,2 月没有 29 天,但如果 datetime 能够解决这个问题并返回这个对象,那就太好了

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

解决这种情况的最佳方法是什么?所以,我正在寻找一个通用的解决方案,当日参数大于月的天数时。

4

3 回答 3

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)
于 2013-02-28T11:36:02.390 回答
3

虽然try...except在这种情况下使用有很多话要说,但如果你真的只需要 month + daysOffset 你可以这样做:

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

基本上,将月份中的日期设置为 1,它始终在月份中,然后添加 timedelta 以返回当前或未来月份中的适当日期。

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)
于 2013-02-28T11:36:37.153 回答
1

使用下个月的第一天,然后减去一天以避免使用日历

datetime.datetime(targetYear, targetMonth+1, 1) + dt.timedelta(days = -1)
于 2017-04-12T13:08:15.317 回答