2013-02-28 113 views
3

我在处理日期时发现非常有用的datetime.datetime对象,但是现在有情况,现在datime.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 

OK,月没有29日,但将是巨大的,如果日期时间能明白这一点,并返回该对象

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

什么是最好的方式解决这种情况?所以,我在寻找一个通用的解决方案,当天参数大于月可能有的天数时。

+5

不,这将*不*很大。显式比隐式更好。 – 2013-02-28 11:31:12

+0

您实际上无法获得修复损坏的逻辑的一般解决方案。你可以尝试使用'导入日历; calendar.monthrange(year,month)'获取月份日期。 – dmg 2013-02-28 11:36:51

回答

3

虽然有很多可说的对在这种情况下使用try...except,如果你真的只需要一个月+ 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) 
+0

对我而言,谢谢。 – Zed 2013-02-28 11:44:53

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

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

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