gpt4 book ai didi

python - 没有 dtend 作为规则参数?

转载 作者:行者123 更新时间:2023-12-04 13:35:06 25 4
gpt4 key购买 nike

我正在尝试使用 dateutil.rrule 查找给定 datetime 之前的第一场比赛.
尝试 1:
我的第一次尝试是:

dtstart = datetime(2010, 1, 1, 0, 00)
myRule = rrule(freq=WEEKLY, dtstart=dt)
result = myRule.before(dt)
它不起作用,变量结果将等于 None .
如果我是对的,当你执行该方法时 beforerrule ,不幸的是,您会在 datetime 之后搜索传递给参数 dtstart .
所以基本上,我以前的代码可以表示为那种时间线:
[A区] [TARGET] [B区] [dtstart] [C区]
在那个时间线中,只有 [zone C] 被解析,所以我的目标从未被找到。
尝试 2:
我的第二次尝试有效,但真的很丑......目的是转移 [dtstart]之前 [TARGET]得到一个看起来像这样的时间表:
[A区] [dtstart] [B区] [TARGET] [C区]
为此,我必须找出一个 dtstart也就是说,当然,在目标之前而不是那么远,以避免性能问题。所以 [zone B] 必须存在,但必须尽可能短。
seekdt = datetime(2010, 1, 1, 0, 00)
startdt = seekdt - timedelta(days=7) # While my rrule.freq is WEEKLY and the interval is 1 (default), I'm sure that my startdt will be before my target if I shift it by 7 days
myRule = rrule(freq=WEEKLY, dtstart=startdt)
result = muRule.before(seekdt)
正如我所说,这个解决方案真的很丑……如果我有一个更复杂的规则或规则集,也很难定义最佳转变。
最好的解决方案,但实际上并不存在... :'( :
如果 rrule 可以采用 dtend 而不是 dtstart,那就完美了。我可以做这样的事情:
dtstart = datetime(2010, 1, 1, 0, 00)
myRule = rrule(freq=WEEKLY, dtend=dt)
result = muRule.before(dt)
问题:
如果没有任何简单的功能可以做到这一点,对我来说接缝很奇怪。有什么优雅的方法可以达到我的目标吗?我的尝试 2 是最好的解决方案吗?
换句话说(同样有问题,但作为练习):
您将如何找到 2 月 13 日的最后一个星期五(基于今天)?

最佳答案

假设 dateutils.rrule 没有提供开箱即用的功能,我认为您自己的解决方案很接近但还没有完全实现。您需要以正确的间隔倒退并计算目标日期之前的最后结果。如果您的规则没有完全指定并且结果继承了原始日期的某些属性,则“正确的间隔”很重要。
例如,如果您的规则是 MONTHLY您必须确保您在上个月或上个月的同一天结束。这很棘手,因为上个月甚至可能没有那一天,例如从 7 月 31 日向后 1 个月会给您一个不正确的结果 - 在这种情况下,您必须一直返回到 5 月 31 日。另一个例子:从 2 月 29 日开始,返回 YEARLY规则 - 你必须倒退 4 年(有时甚至是 8 年)。
此外,您必须确保跳过规则中指定的间隔数。对于每两周一次的规则(例如 FREQ=WEEKLY;INTERVAL=2 ),您必须回溯 2 周,否则您的结果将出现在错误的一周。
另一个需要注意的陷阱是间隔可能是空的。拿你的例子来说,你可能需要倒退几周才能找到匹配 FREQ=WEEKLY;BYDAY=FR;BYMONTHDAY=13 的日期。 .你必须为此做好准备并继续向后走,直到找到一个非空的。
我对 dateutil.rrule 不熟悉,所以这里有一些伪代码可以引导你:

rule = … // your rule
target = … // the pivot date
dtstart = target

DO
DO
SWITCH(rule.freq)
CASE YEARLY ->
dtstart = same month, same day of month rule.interval years before old dtstart
BREAK
CASE MONTHLY:
dtstart = same day of month rule.interval months before old dtstart
BREAK
CASE WEEKLY:
dtstart = 7 * rule.interval days before old dtstart
BREAK
CASE DAILY:
dtstart = rule.interval days before old dtstart
BREAK
UNTIL dtstart is a valid date

rule.dtstart = dtstart
candidate = rule.before(target)
UNTIL candidate is a date

// candidate is your result
请注意,很可能以一种不会产生单一结果的方式指定规则。因此,如果您的代码接受用户输入,您应该为此做好准备并避免无限循环。
处理继承属性的另一种方法是在某些字段不存在时调整规则。例如,对于 MONTHLY没有规则 BYMONTHDAY你可以设置 rule.bymonthday到目标日期的月日。但是您必须设置的字段因 FREQ而异所以这有其自身的缺陷。

关于python - 没有 dtend 作为规则参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62597798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com