未来六个月的日期
我在Django中使用Python的datetime模块。我想计算一个日期,看它是否在当前日期的6个月以内或者正好是6个月。
我想生成一个从现在开始6个月后的日期,是为了设置一个提醒,能突出显示发生这个事件的字段或列。我不知道我的问题是否表达清楚了。我一直在阅读timedelta这个函数,但还是搞不太明白。我正在尝试写一个if语句来满足这个条件。有没有人能帮帮我呢?我还是Django和Python的新手。
4 个回答
我建议你认真看看Delorean这个库。它是基于dateutil
和pytz
构建的,可以帮助你完成你想要的功能。
>>> d = Delorean()
>>> d
Delorean(datetime=2013-02-21 06:00:21.195025+00:00, timezone=UTC)
>>> d.next_month(6)
Delorean(datetime=2013-08-21 06:00:21.195025+00:00, timezone=UTC)
这个库考虑了所有与日期相关的计算,还提供了处理时区转换的接口。要获取所需的日期时间,只需在Delorean对象上使用.datetime
就可以了。
如果你说的“6个月”是指180天的话,你可以用:
import datetime
d = datetime.date.today()
d + datetime.timedelta(6 * 30)
不过如果你是指实际的6个月,也就是按日历算的,那你就需要查一下日历模块,然后对每个月进行一些查找。比如:
import datetime
import calendar
def add_6_months(a_date):
month = a_date.month - 1 + 6
year = a_date.year + month / 12
month = month % 12 + 1
day = min(a_date.day,calendar.monthrange(year, month)[1])
return datetime.date(year, month, day)
这里有两种方法,一种稍微不准确,另一种以不同的方式不准确:
第一种方法是加上一个
datetime.timedelta()
,这个值是 365.25 / 2 天(平均一年长度除以二):import datetime sixmonths = datetime.datetime.now() + datetime.timedelta(days=365.25/2)
这种方法会给你一个未来6个月的时间戳,我们把6个月定义为正好半年的时间(平均而言)。
第二种方法是使用外部的
dateutil
库,它有一个很棒的relativedelta
类,可以根据日历计算给你当前日期加上6个月:import datetime from dateutil.relativedelat import relativedelta sixmonths = datetime.datetime.now() + relativedelta(months=6)
这种方法会给你一个未来6个月的时间戳,其中日期的月份部分会加6,并且会考虑到月份的边界,确保不会跨越它们。例如,8月30日加6个月变成了2月28日或29日(闰年时)。
举个例子可能会更清楚。在我所在的时区,发布时的结果是:
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2013, 2, 18, 12, 16, 0, 547567)
>>> now + datetime.timedelta(days=365.25/2)
datetime.datetime(2013, 8, 20, 3, 16, 0, 547567)
>>> now + relativedelta(months=6)
datetime.datetime(2013, 8, 18, 12, 16, 0, 547567)
所以这两种方法之间有1天15小时的差异。
这两种方法同样适用于 datetime.date
对象:
>>> today = datetime.date.today()
>>> today
datetime.date(2013, 2, 18)
>>> today + datetime.timedelta(days=365.25/2)
datetime.date(2013, 8, 19)
>>> today + relativedelta(months=6)
datetime.date(2013, 8, 18)
当只应用于日期时,半年的时间差就会稍微不准确一些(因为这个时间差中的5/8天部分被忽略了)。