Python 领先 days/weeks/months
Python get days/weeks/months ahead
我一直在通过 Whosebug 搜索答案,但我无法在 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 天的月份呢?这不会导致某种开销并在某些时候出错吗?
- 有没有更好的方法来获取这些信息? datetime 或 dateutil 的某种库或内置函数 returns 你有这个信息吗?
提前致谢。如果问题得到回答,请 link 我到 post 我会仔细阅读。如果需要,我愿意提供更多信息。
编辑
我在这里包含了我完整的更新代码,以供在 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 ""
是的,您当前的代码有问题,因为并非所有月份都有 31 天。在实践中,您可能会认为如果它实际上是在 1 个月零 28 天内到期,但它说“2 个月内到期”并不太重要。毕竟,向下舍入意味着您在 2 个月零 28 天后到期时显示“2 个月内到期”。
因为您使用的是 dateutil
module already, note that you can use relativedelta
the other way around as well (see the examples page).
如果您用两个日期对象实例化一个 relativedelta
,它 returns 一个 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
我一直在通过 Whosebug 搜索答案,但我无法在 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 天的月份呢?这不会导致某种开销并在某些时候出错吗? - 有没有更好的方法来获取这些信息? datetime 或 dateutil 的某种库或内置函数 returns 你有这个信息吗?
提前致谢。如果问题得到回答,请 link 我到 post 我会仔细阅读。如果需要,我愿意提供更多信息。
编辑
我在这里包含了我完整的更新代码,以供在 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 ""
是的,您当前的代码有问题,因为并非所有月份都有 31 天。在实践中,您可能会认为如果它实际上是在 1 个月零 28 天内到期,但它说“2 个月内到期”并不太重要。毕竟,向下舍入意味着您在 2 个月零 28 天后到期时显示“2 个月内到期”。
因为您使用的是 dateutil
module already, note that you can use relativedelta
the other way around as well (see the examples page).
如果您用两个日期对象实例化一个 relativedelta
,它 returns 一个 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