gpt4 book ai didi

python - Django ical 与 pytz 的 Vobject 问题

转载 作者:行者123 更新时间:2023-12-01 05:27:01 31 4
gpt4 key购买 nike

我正在使用 vobject 在 Django 中创建一个 ical 事件。我在使用较低级别的代码时遇到问题。看起来 ical 正在尝试使用 obj.add(TimezoneComponent(tzinfo=getTzid(tzid))) 获取时区。但后来我从 pytz 得到了 raise NonExistentTimeError(dt) 。有什么建议吗?当我使用变量 start1 中的 print 语句查看时,年、月、日显示正确。

 File "/home/git/chrono/chrono/requests_app/views.py", line 110, in form_valid
ics_form = create_ics(data)
File "/home/git/chrono/chrono/requests_app/views.py", line 126, in create_ics
response = HttpResponse(cal.serialize(), content_type='text/calendar')
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/base.py", line 186, in serialize
return behavior.serialize(self, buf, lineLength, validate)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/behavior.py", line 147, in serialize
cls.generateImplicitParameters(obj)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 853, in generateImplicitParameters
obj.add(TimezoneComponent(tzinfo=getTzid(tzid)))
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 75, in __init__
self.tzinfo = tzinfo
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/base.py", line 468, in __setattr__
prop.fset(self, value)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 145, in settzinfo
transition = getTransition(transitionTo, year, tzinfo)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 1856, in getTransition
uncorrected = firstTransition(generateDates(year, month, day), test)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 1816, in firstTransition
if not test(dt):
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/vobject/icalendar.py", line 1843, in test
def test(dt): return tzinfo.dst(dt) != zeroDelta
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/pytz/tzinfo.py", line 445, in dst
dt = self.localize(dt, is_dst)
File "/home/one/.virtualenvs/chronos/local/lib/python2.7/site-packages/pytz/tzinfo.py", line 327, in localize
raise NonExistentTimeError(dt)
NonExistentTimeError: 2000-04-02 02:00:00



def create_ics(data):
start1 = data['date_due']
print start1.day
start2 = datetime.datetime(start1.year, start1.month, start1.day)
start3 = data['action']
cal = vobject.iCalendar()
cal.add('method').value = 'PUBLISH'
vevent = cal.add('vevent')
vevent.add('dtstart').value = start1
vevent.add('dtend').value = start2
vevent.add('dtstamp').value = datetime.datetime.now()
vevent.add('summary').value = data['action'].name
response = HttpResponse(cal.serialize(), content_type='text/calendar')
response['Filename'] = 'filename.ics'
response['Content-Disposition'] = 'attachment; filename=filename.ics'
return response

来自模型,日期时间字段:

date_due = models.DateTimeField()

更新:

发现我必须放置:

>>> utc = vobject.icalendar.utc
>>> start = cal.vevent.add('dtstart')
>>> start.value = datetime.datetime(2006, 2, 16, tzinfo = utc)

进入其中,效果很好。

最佳答案

简短回答: vobject 与 pytz 不兼容(从 0.9.2 开始)。因此,在尝试序列化 vobject iCalendar 中的每个日期时间之前,请确保已使用 .astimezone(pytz.utc) 之类的内容将其转换为 UTC。

(这是每个 dtstart、dtend、dtstamp、created、last-modified,也许还有一些我忘记的其他 vevent 字段。)

长答案: vobject 尝试对非 UTC 日期时间做正确的事情,但在使用 pytz 时遇到了麻烦。 “正确的事情”来自RFC 5545其中指定 iCalendar:

  1. 使用 DATE-TIME Form #3 表示日期时间“带有本地时间和时区引用的日期”。这可能类似于 DTSTART;TZID=America/New_York:20160714T133000 - 请注意您的事件时区的 TZID。

  2. 添加VTIMEZONE阻止您的 iCalendar 获取事件中使用的每个唯一 TZID。这是该时区的完整定义:如何针对可能出现的任何日期时间计算该时区相对于 UTC 的偏移量,包括夏令时规则。 (RFC 5545 doesn't specify 任何特定的时区名称,因此您必须在 iCalendar 本身中包含时区定义。vobject 自动为您完成此操作。)

要弄清楚时区转换规则,vobject searches through "all time" (默认年份 2000-2030),查找时区相对 UTC 偏移量的变化。这就是问题所在,因为 vobject 代码不处理 pytz 的无效时间错误。

2000 年 4 月 2 日凌晨 2:00 是 2000 年至 2030 年之间的第一次 DST 转换,这就是您在该时间收到错误的原因(即使您没有在自己的代码中的任何地方使用它)。

选项:

  • 如果您不想要一天中的特定时间(如原始问题中所示),请使用date 而不是datetime。日期没有时区,因此这些都不适用。 (vobject 可以很好地处理日期。)
  • 将所有日期时间转换为 UTC 格式的感知日期时间。 UTC 不需要 VTIMEZONE 定义。
  • 使用dateutil timezones而不是 pytz。例如,from dateutil import tz; ... tzinfo=tz.gettz('美国/洛杉矶').由于 dateutil 是 vobject 依赖项,我认为这是 vobject 的 VTIMEZONE 生成器所针对的格式。 (但尚未进行广泛测试。此外,gettz 需要在您的计算机上安装 tzdb 文件,因此不完全可移植。)
  • 为您使用的每个 TZID 添加您自己的 VTIMEZONE 定义到 iCalendar,这应该避免 vobject 中出现有问题的自动时区生成代码。 (未经测试。并且在一般情况下很难正确处理。)
  • 提交 PR to fix vobject to work with pytz .

关于python - Django ical 与 pytz 的 Vobject 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21128695/

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