在Python中检查日期是否在日期范围内

63

我有一个日期变量:2011-01-15,我想判断这个日期是否在今天之前的3天内。我不太清楚如何在Python中构造此功能。我只涉及日期而非时间。

我的工作示例是一个“宽限期”。当用户登录我的网站时,如果宽限期在今天之前的3天内,那么该用户将省略其他脚本等操作。

我知道你可以在Python的日期模块中进行一些复杂的操作,但我不确定该去哪里查找。

5个回答

147

在Python中,要检查一个范围,可以使用 a <= x <= b

>>> import datetime
>>> today = datetime.date.today()
>>> margin = datetime.timedelta(days = 3)

>>> today - margin <= datetime.date(2011, 1, 15) <= today + margin
True

给予Mark Byers的一分。我同意,这种方法更易读但与Thomas的答案同样有效。谢谢你们俩。我已将这两种方法都添加到了我的日记中。非常有道理。 - Ben Keating

12

从两个date对象相减将会得到一个timedelta对象,你可以将其与其他timedelta对象进行比较。

例如:

>>> from datetime import date, timedelta
>>> date(2011, 1, 15) - date.today()
datetime.timedelta(1)
>>> date(2011, 1, 15) - date.today() < timedelta(days = 3)
True
>>> date(2011, 1, 18) - date.today() < timedelta(days = 3)
False

"where to look"指的是查找Python相关日期和时间信息的来源,官方文档非常优秀。


我在Python 3.1.3中尝试了这个,当使用01代替1来表示一月份时,会出现“SyntaxError: invalid token”的错误提示。但是仍然会给你#1... :) - a2j
哦,抱歉。Python 2会将其解释为八进制,但是在Python 3中他们放弃了这种语法,因为它很容易混淆。我总是用八进制写我的日期,你呢?;) - Thomas
我是Python的新手,所以不知道该怎么做。我欢迎所有的指导!这就是为什么我每天都来SO的原因。 - a2j

9

其他人已经给出了足够的答案,所以不需要对这个答案进行投票。
(使用了Mark Byers在答案中展示的技巧;对他点赞+1)。

import datetime as dt

def within_days_from_today(the_date, num_days=7):
    '''
        return True if date between today and `num_days` from today
        return False otherwise

        >>> today = dt.date.today()
        >>> within_days_from_today(today - dt.timedelta(days=1), num_days=3)
        False
        >>> within_days_from_today(dt.date.today(), num_days=3)
        True
        >>> within_days_from_today(today + dt.timedelta(days=1), num_days=3)
        True
        >>> within_days_from_today(today + dt.timedelta(days=2), num_days=3)
        True
        >>> within_days_from_today(today + dt.timedelta(days=3), num_days=3)
        True
        >>> within_days_from_today(today + dt.timedelta(days=4), num_days=3)
        False
    '''
    lower_limit = dt.date.today()
    upper_limit = lower_limit + dt.timedelta(days=num_days)
    if lower_limit <= the_date <= upper_limit:
        return True
    else:
        return False

if __name__ == "__main__":
    import doctest
    doctest.testmod()

我也喜欢这个。我喜欢支持大小写,因为我可能不想计算今天之前的天数。附带doctest!;) - Ben Keating

8

面向对象的解决方案

import datetime

class DatetimeRange:
    def __init__(self, dt1, dt2):
        self._dt1 = dt1
        self._dt2 = dt2

    def __contains__(self, dt):
        return self._dt1 < dt < self._dt2

dt1 = datetime.datetime.now()
dt2 = dt1 + datetime.timedelta(days = 2)
test_true = dt1 + datetime.timedelta(days = 1)
test_false = dt1 + datetime.timedelta(days = 5)

test_true in DatetimeRange(dt1, dt2) #Returns True
test_false in DatetimeRange(dt1, dt2) #Returns False

我喜欢你的解决方案,但我认为范围应该是包括的,所以使用小于等于符号:<=。 - Benjamin

0
将经过的时间转换为天数,然后对经过的天数应用三元操作。
current_dt=datetime.now()
feed_dt = datetime.now()-timedelta(days=3)
from_dt=datetime(year=feed_dt.year,month=feed_dt.month,day=feed_dt.day)
days_elapsed=(current_dt-from_dt).days
print(True if days_elapsed <=3 else False)

输出: 真


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接