首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dateutils rrule返回间隔2个月的日期。

dateutils rrule返回间隔2个月的日期。
EN

Stack Overflow用户
提问于 2016-07-12 11:59:42
回答 2查看 3.1K关注 0票数 5

我对Python和dateutil模块都是新手。我谨提出以下论点:

代码语言:javascript
复制
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)]

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

截止日期是现在。

当我使用:

代码语言:javascript
复制
disclosure_dates = [dt for dt in rrule(MONTHLY, dtstart=disclosure_start_date, until=disclosure_end_date)]

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

代码语言:javascript
复制
>>> 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)]

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-24 18:21:39

您遇到的问题来自这样一个事实:datetime.datetime(2012, 10, 31, 0, 0)是一个月的第31位,而不是所有的月份都有第31位。因为rrule模块是RFC 2445的一个实现。根据RFC 3.3.10:

递归规则可以生成具有无效日期(例如,2月30日)或不存在的本地时间的递归实例(例如,在本地时间在凌晨1:00移动1小时的一天中,1:30上午1: 30)。这类重复实例必须被忽略,不应被视为递归集的一部分。

由于您有一个月规则,生成一个月的第31天,它将跳过30天或30天以下的所有月份。您可以在这个错误报告中看到关于这个问题的dateutil

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

代码语言:javascript
复制
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,如果-而且只有在有必要的情况下(例如,如果有必要的话--如果有必要的话(例如,您对1月30日做了什么?),但是您不想使用bymonthday=-2,因为这将给您2月27日的时间,等等)。

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

代码语言:javascript
复制
from dateutil.relativedelta import relativedelta
from datetime import datetime

def disclosure_dates(dtstart, rd, dtend=None):
    ii = 0
    while True:
        cdate = dtstart + ii*rd
        ii += 1

        yield cdate
        if dtend is not None and cdate >= dtend:
            break


dtstart = datetime(2013, 1, 31, 0, 0)
rd = relativedelta(months=1)
rr = disclosure_dates(dtstart, rd, dtend=datetime(2013, 5, 1))

# >>> list(rr)
# [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),
#  datetime.datetime(2013, 5, 31, 0, 0)]

请注意,我专门使用了cdate = dtstart + ii * rd,您不想只保留一个“运行计数”,因为这将影响到统计所见的最短月份:

代码语言:javascript
复制
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

结果:

代码语言:javascript
复制
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
票数 9
EN

Stack Overflow用户

发布于 2022-01-18 20:22:17

页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38328313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档