我一直在通过stackoverflow搜索答案,但我无法在Python和Pythonic方式中找到我正在寻找的东西。
我试图根据两个日期提前几天,几周或几个月。这是我创建的一个小脚本,它可以完成我想做的事情,但我很关心它。
import datetime
from dateutil.relativedelta import relativedelta
now = datetime.datetime.now()
days_ahead = datetime.datetime.now() + relativedelta(days=3)
weeks_ahead = datetime.datetime.now() + relativedelta(weeks=2)
month_ahead = datetime.datetime.now() + relativedelta(months=1)
months_ahead = datetime.datetime.now() + relativedelta(months=3)
def get_relative_date(dt):
ahead = (dt - now).days
if ahead < 7:
return "Due in " + str(ahead) + " days"
elif ahead < 31:
return "Due in " + str(ahead/7) + " weeks"
else:
return "Due in " + str(ahead/30) + " months"
print get_relative_date(days_ahead)
print get_relative_date(weeks_ahead)
print get_relative_date(month_ahead)
print get_relative_date(months_ahead)
结果如下:
Due in 3 days
Due in 2 weeks
Due in 1 months
Due in 3 months
尽管答案很好,但我的担忧与:
有关ahead < 30
但是31天的月数呢?这不会导致某种开销并在某些时候出错吗?提前致谢。如果问题得到解答,请将我链接到帖子,我会仔细阅读。如果需要,我愿意提供更多信息。
我在这里包含了我在Python中需要此功能的任何人的完整更新代码。它还负责负日值和今天。
def relative_date(dt):
if dt is not None and len(dt) > 0:
now = datetime.now()
then = arrow.get(dt).naive
rd = relativedelta(then, now)
if rd.years or rd.months:
months = 12 * rd.years + rd.months
if months < 0:
if months == -1:
return "Due 1 month ago"
return "Due %i months ago" % -months
if months == 1:
return "Due in 1 month"
return "Due in %d months" % months
elif rd.days > 7 or rd.days < -7:
weeks = rd.days / 7
if weeks < 0:
if weeks == -1:
return "Due 1 week ago"
return "Due %i weeks ago" % -weeks
if weeks == 1:
return "Due in 1 week"
return "Due in %d weeks" % weeks
else:
if rd.days == 0:
return "Due Today"
elif rd.days < 0:
if rd.days == -1:
return "Due 1 day ago"
return "Due %i days ago" % -rd.days
elif rd.days == 1:
return "Due in 1 day"
return "Due in %d days" % rd.days
else:
return ""
答案 0 :(得分:5)
是的,您当前的代码存在问题,因为并非所有月份都有31天。在实践中,如果它在1个月和28天内实际到期时显示“2个月内到期”,您可能会认为它不太重要。毕竟,四舍五入意味着您在2个月和28天内到期时显示“2个月到期”。
由于您已经使用dateutil
模块,请注意您也可以反过来使用relativedelta
(请参阅the examples page)。
如果您使用两个日期对象实例化relativedelta
,则会返回一个relativedelta
个对象,其中包含year
,month
和day
个属性。
>>> relativedelta(date(2015, 7, 20), date(2014, 6, 10))
relativedelta(years=+1, months=+1, days=+10)
您可以在方法中使用此方法,如下所示:
from dateutil.relativedelta import relativedelta
def get_relative_date(dt):
rd = relativedelta(dt, now)
if rd.years or rd.months:
months = 12 * rd.years + rd.months:
return "Due in %d months" % months
elif rd.days > 7:
weeks = rd.days / 7
return "Due in %d weeks" % weeks
else:
return "Due in %d days" % rd.days