dateutils rrule返回2个月ap的日期

2024-04-18 10:52:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python的新手,也是dateutil模块。我提出以下论点:

disclosure_start_date = resultsDict['fd_disclosure_start_date']
disclosure_end_date = datetime.datetime.now()
disclosure_dates = [dt for dt in rrule(MONTHLY, dtstart=disclosure_start_date, until=disclosure_end_date)]

这里disclosure_start_date = 2012-10-31 00:00:00转换成datetime的是datetime.datetime(2012, 10, 31, 0, 0)

结束日期从现在起。在

当我使用:

^{pr2}$

我每隔一个月或两个月得到一次约会。结果是:

>>> list(disclosure_dates)
[datetime.datetime(2012, 10, 31, 0, 0), 
 datetime.datetime(2012, 12, 31, 0, 0), 
 datetime.datetime(2013, 1, 31, 0, 0), 
 datetime.datetime(2013, 3, 31, 0, 0), 
 datetime.datetime(2013, 5, 31, 0, 0), 
 datetime.datetime(2013, 7, 31, 0, 0), 
 datetime.datetime(2013, 8, 31, 0, 0), 
 datetime.datetime(2013, 10, 31, 0, 0), 
 datetime.datetime(2013, 12, 31, 0, 0), 
 datetime.datetime(2014, 1, 31, 0, 0), 
 datetime.datetime(2014, 3, 31, 0, 0), 
 datetime.datetime(2014, 5, 31, 0, 0), 
 datetime.datetime(2014, 7, 31, 0, 0), 
 datetime.datetime(2014, 8, 31, 0, 0), 
 datetime.datetime(2014, 10, 31, 0, 0), 
 datetime.datetime(2014, 12, 31, 0, 0), 
 datetime.datetime(2015, 1, 31, 0, 0), 
 datetime.datetime(2015, 3, 31, 0, 0), 
 datetime.datetime(2015, 5, 31, 0, 0), 
 datetime.datetime(2015, 7, 31, 0, 0), 
 datetime.datetime(2015, 8, 31, 0, 0), 
 datetime.datetime(2015, 10, 31, 0, 0), 
 datetime.datetime(2015, 12, 31, 0, 0), 
 datetime.datetime(2016, 1, 31, 0, 0), 
 datetime.datetime(2016, 3, 31, 0, 0), 
 datetime.datetime(2016, 5, 31, 0, 0)]

我不知道我做错了什么。有人能指出这里的错误吗?在


Tags: 模块fordatetimedatedtstartnowend
1条回答
网友
1楼 · 发布于 2024-04-18 10:52:35

您遇到的问题来自于这样一个事实,即datetime.datetime(2012, 10, 31, 0, 0)是一个月的31号,并且不是所有的月份都有31号。根据RFC 3.3.10:

Recurrence rules may generate recurrence instances with an invalid date (e.g., February 30) or nonexistent local time (e.g., 1:30 AM on a day where the local time is moved forward by an hour at 1:00 AM). Such recurrence instances MUST be ignored and MUST NOT be counted as part of the recurrence set.

因为您有一个生成一个月31日的月度规则,它将跳过30天或更少天数的所有月份。您可以在dateutil中看到关于此问题的this bug report。在

如果您只想要一个月的最后一天,您应该使用bymonthday=-1参数:

from dateutil.rrule import rrule, MONTHLY
from datetime import datetime

disclosure_start_date = datetime(2012, 10, 31, 0, 0)

rr = rrule(freq=MONTHLY, dtstart=disclosure_start_date, bymonthday=-1)
# >>>rr.between(datetime(2013, 1, 1), datetime(2013, 5, 1))
# [datetime.datetime(2013, 1, 31, 0, 0),
#  datetime.datetime(2013, 2, 28, 0, 0),
#  datetime.datetime(2013, 3, 31, 0, 0),
#  datetime.datetime(2013, 4, 30, 0, 0)]

不幸的是,我不认为有一种与RFC兼容的方法来生成一个简单的RRULE,该RRULE只会在必要时返回到月末(例如,1月30日做什么-2月需要回退,但您不想使用bymonthday=-2,因为这会给您2月27日,等等)。在

或者,对于这样一个简单的月度规则,一个更好的选择可能是只使用relativedelta,这会使回到月末:

^{pr2}$

请注意,我特别使用了cdate = dtstart + ii * rd,您确实希望只保留一个“正在运行的计数”,因为这将锁定到计数所看到的最短月份:

dt_base = datetime(2013, 1, 31)
dt = dt_base
for ii in range(5):
    cdt = dt_base + ii*rd
    print('{} | {}'.format(dt, cdt))
    dt += rd

结果:

2013-01-31 00:00:00 | 2013-01-31 00:00:00
2013-02-28 00:00:00 | 2013-02-28 00:00:00
2013-03-28 00:00:00 | 2013-03-31 00:00:00
2013-04-28 00:00:00 | 2013-04-30 00:00:00
2013-05-28 00:00:00 | 2013-05-31 00:00:00

相关问题 更多 >