请考虑这个问题:
我有一个过去的日期,我从那里开始添加句点。当添加这些期间导致日期大于今天时,我想停下来检查最后一个日期是什么。
这是计算会员借记日期的功能。一个成员加入,比如说,2007-01-31。他每个月都会被扣款。假设今天是 2013-03-29(实际上是 atm)。所以我需要从 2007 年 1 月 31 日开始计算月份,当我超过今天的日期时,我需要停止。然后我可以看到下一个借记日期是 2013-03-31。
我正在使用 dateutil 库来实现这一点,在 while 循环中添加 relativedelta,直到我超过当前日期。(我知道这可能不是最好的方法,但我对 Python 还是很陌生,这是一个概念验证)。问题是当我在 2007-01-31 中添加一个月时,下一个日期是 2007-02-28,这是正确的。但是下一次迭代的日期是 2007-03-28,因为 dateutil 不将 28 日识别为该月的最后一天,以保持其完整并迭代到 3 月的最后一天。当然,这是一个完全有效的实现。然后我尝试了 dateutils rrule 对象,但它具有相同的原理。它输出日期列表,但它只是跳过没有足够天数的月份。
period = rrule(MONTHLY, interval=1, dtstart=datetime.date(2012, 5, 31), until=datetime.date(2013, 3, 29))
print(list(period))
然后我想到了另一种方法:
如果我可以计算 2007 年 1 月 31 日到 2013 年 3 月 29 日期间的时间段数,我可以将这些时间段数添加到开始日期,并且 dateutil 将返回正确的日期。
问题是这个时期并不总是一个月。例如,也可以是四个星期、一个季度或一年。
我找不到一种方法来获取一个 relativedelta 并将它与另一个 relativedelta 相除,以获得后者进入第一个的次数。
如果有人能指出我正确的方向,我将不胜感激。例如,是否有一个库可以做到这一点(相互划分时间跨度,并在给定的时间块内输出结果,如几个月或几周)?是否有一个 datediff 函数可以接受一个句点作为输入(例如,我知道在 vbscript 中,您可以在任何您想要的时间段内获得两个日期之间的差异,无论是几周、几个月、几天等等)。可能有完全不同的解决方案吗?
为了完整起见,我将包含代码,但我认为文本已经解释了这一切:
def calculate(self, testdate=datetime.date.today()):
self._testdate = testdate
while self.next < self._testdate:
self.next += self._ddinterval
self.previous = self.next - self._ddinterval
return self.next
谢谢,
埃里克
编辑:我现在有一个解决方案可以做它应该做的,但它几乎不是 Pythonic、优雅或快速的。所以问题仍然是一样的,如果有人能提出更好的解决方案,请这样做。这是我想出的:
def calculate(self, testdate=datetime.date.today()):
self._testdate = testdate
start = self.next
count = 0
while self.next < self._testdate:
count += 1
self.next = start + (count * self._ddinterval)
self.previous = self.next - self._ddinterval
return self.next