2

count使用 pip 上可用的最新 dateutil,在使用重复规则调用该方法时,我会遇到奇怪的时间和与排序相关的行为DAILY

>>> import dateutil
>>> dateutil.__version__
'2.4.2'
>>> from dateutil import rrule
>>> import datetime

>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179  # ??? Expected 0

>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179  # ??? Expected 0

>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0  # Now its working???

>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179  # ??? Expected 0

>>> rules = rrule.rruleset()
>>> rules.count()
0
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0  # WHAT???
>>> rules.count()
0

>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179  # IM DONE... WTF
4

1 回答 1

2

答案很简单,因为您dtstart在创建规则集时没有包含该参数,当不包含该参数时,它默认为datetime.datetime.now(),即当前时间,并且它包含直到当前微秒的组件。

因此,当您第一次使用 - 创建规则集时 -

>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179

您从当前时间开始获得条目,最多微秒。

一段时间后,当你再次尝试时——

rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))

您再次rrule.rrule从当前时间开始创建一个对象,因此它与您在 中创建的前一个对象不同rules

要解决此问题,您可以指定dtstart属性以确保它同时启动。

例子 -

>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0), dtstart=datetime.datetime(now.year,now.month,now.day,0,0,0)))
>>> rules.count()
8179
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0), dtstart=datetime.datetime(now.year,now.month,now.day,0,0,0)))
>>> l3 = list(rules)
>>> len(l3)
0
>>> rules.count()
0

类似的问题出现在您的其他示例中。


鉴于上述情况,我认为 dateutil 代码中存在问题,它们实际上是在您第一次调用时缓存规则集的计数(长度)count(),然后仅在您对其进行迭代时才重新计算其正确长度,等等。

该问题发生在rrulebase类中,该类是ruleset. 代码是(来源 - https://github.com/dateutil/dateutil/blob/master/dateutil/rrule.py) -

def count(self):
    """ Returns the number of recurrences in this set. It will have go
        trough the whole recurrence, if this hasn't been done before. """
    if self._len is None:
        for x in self:
            pass
    return self._len

因此,即使在申请之后,exrule()如果您之前调用过.count(),它也会继续返回相同的计数。

我不能 100% 确定它是否是一个错误,或者它是否打算这样做,很可能它是一个错误。

我已经为此打开了问题

于 2015-08-12T06:57:18.377 回答