ical RRULE语句中UNTIL的时区问题 [英] Timezone issue with UNTIL in ical RRULE statement

查看:70
本文介绍了ical RRULE语句中UNTIL的时区问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码引发异常,该异常很可能与我修复某些其他错误所需执行的TZID替换有关.如果我从ical字符串中删除"UNTIL"语句,则代码可以正常工作.

The following code throws an exception, which most probably pertains to the TZID replacements I needed to do to fix some other bugs. If I remove the the "UNTIL" statement from the ical string, the code works just fine.

from icalendar.cal import Calendar
import datetime
from dateutil import rrule
from dateutil.tz import gettz

cal_str = "BEGIN:VEVENT\nDTSTART;TZID=America/Los_Angeles:20171019T010000\nDTEND;TZID=America/Los_Angeles:20171019T230000\nRRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=20180423T191500\nX-OP-ENTRY-STATE:unlocked\nEND:VEVENT"
ical = Calendar.from_ical(cal_str)
start_time_dt = ical.get("DTSTART").dt
end_time_dt = ical.get("DTEND").dt
tzinfo = gettz(str(start_time_dt.tzinfo)) 
start_time_dt = start_time_dt.replace(tzinfo=tzinfo)
recurring_rule = ical.get('RRULE').to_ical().decode('utf-8')
rules = rrule.rruleset()
first_rule = rrule.rrulestr(recurring_rule, dtstart=start_time_dt)
rules.rrule(first_rule)
event_delta = end_time_dt -start_time_dt
now = datetime.datetime.now(datetime.timezone.utc)
for s in rules.between(now - event_delta, now + datetime.timedelta(minutes=1)):
    print(s)

这里是个例外:

Traceback (most recent call last):
  File "ical_test.py", line 27, in <module>
    for s in rules.between(now - event_delta, now + datetime.timedelta(minutes=1)):
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 290, in between
    for i in gen:
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 1362, in _iter
    self._genitem(rlist, gen)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 1292, in __init__
    self.dt = advance_iterator(gen)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 861, in _iter
    if until and res > until:
TypeError: can't compare offset-naive and offset-aware datetimes

任何人都可以找出此错误的根本原因以及解决此问题的方法吗?

Anyone help for finding out the root cause of this error and a way to fix this?

推荐答案

首先,他们在 dateutil> 2.7.1 中将异常更明确地解决了这一问题:

First of all they fixed the exception to be more explicit in dateutil>2.7.1 to this:

Traceback (most recent call last):
  File "ical_test.py", line 23, in <module>
    first_rule = rrule.rrulestr(recurring_rule, dtstart=start_time_dt)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 1664, in __call__
    return self._parse_rfc(s, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 1547, in _parse_rfc
    tzinfos=tzinfos)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 1506, in _parse_rfc_rrule
    return rrule(dtstart=dtstart, cache=cache, **rrkwargs)
  File "/usr/local/lib/python3.5/dist-packages/dateutil/rrule.py", line 461, in __init__
    'RRULE UNTIL values must be specified in UTC when DTSTART '
ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware

解决方案是按UTC计算UNTIL时间,并按照RFC中的说明在时间字符串的末尾添加 Z :

The solution is to calculate the UNTIL time in UTC and add Z to the end of the time string as described in the RFC:

https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html

正确的RRULE字符串应如下所示:

the correct RRULE string should look like this:

cal_str ="BEGIN:VEVENT \ nDTSTART; TZID = America/Los_Angeles:20171019T010000 \ nDTEND; TZID = America/Los_Angeles:20171019T230000 \ nRRULE:FREQ = WEEKLY; BYDAY = MO,TU,WE,TH,FR; UNTIL = 20180423T001500Z \ nX-OP-ENTRY-STATE:未锁定\ nEND:VEVENT"

这篇关于ical RRULE语句中UNTIL的时区问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆