【问题标题】:Python get days/weeks/months aheadPython 提前几天/几周/几个月
【发布时间】:2021-01-05 01:38:37
【问题描述】:

我一直在通过 stackoverflow 寻找答案,但我无法以 Python 和 Python 的方式找到我想要的东西。

我正在尝试根据两个日期提前获得天数、周数或月数。这是我创建的一个小脚本,它可以做我想做的事,但我很担心。

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 &lt; 30,但是有 31 天的月份呢?这不会导致某种开销并在某些时候产生错误吗?
  • 有没有更好的方法来获取这些信息? datetime 或 dateutil 的某种库或内置函数会返回此信息吗?

提前致谢。如果问题得到解答,请将我链接到帖子,我会仔细阅读。如果需要,我愿意提供更多信息。

编辑

我在这里包含了我的完整更新代码,供任何在 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 ""

【问题讨论】:

    标签: python datetime python-dateutil


    【解决方案1】:

    是的,您当前的代码存在问题,因为并非所有月份都有 31 天。在实践中,您可能会认为,如果它实际上是在 1 个月零 28 天后到期时显示“2 个月内到期”,这并不是太重要。毕竟,四舍五入意味着您在 2 个月零 28 天后到期时显示“2 个月后到期”。

    由于您已经在使用dateutil 模块,请注意您也可以反过来使用relativedelta(请参阅the examples page)。

    如果你用两个日期对象实例化一个relativedelta,它会返回一个带有yearmonthday属性的relativedelta对象。

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

    【讨论】:

    • Amazing 不知道这一点。非常感谢。
    • 请注意,为以后的读者注意,“months = 12 * rd.years + rd.months”行的末尾不应有额外的“:”。
    • 好地方@swapnilbhate,我已经更新了答案。您可以使用编辑按钮提出这样的更改建议。
    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多