首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django ical与Vobject的问题与pytz

Django ical与Vobject的问题与pytz
EN

Stack Overflow用户
提问于 2014-01-15 11:38:45
回答 1查看 603关注 0票数 1

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

代码语言:javascript
复制
 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

在models中,datetime字段:

代码语言:javascript
复制
date_due = models.DateTimeField()

更新:

我发现我必须放置:

代码语言:javascript
复制
>>> utc = vobject.icalendar.utc
>>> start = cal.vevent.add('dtstart')
>>> start.value = datetime.datetime(2006, 2, 16, tzinfo = utc)

进入其中,它起作用了。

EN

回答 1

Stack Overflow用户

发布于 2016-05-27 07:07:09

简短回答: pytz vobject (从0.9.2开始)与不兼容。因此,在尝试序列化它之前,请确保您的vobject iCalendar中的每个datetime都已转换为UTC,并使用类似于.astimezone(pytz.utc)的东西。

(这是我忘记的每个dtstart、dtend、dtstamp、created、last-modified和其他vevent字段)。

漫长的答案: pytz试图为非日期时间做正确的事情,但在上遇到了麻烦。“正确的东西”来自RFC 5545,它指定了iCalendar:

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

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

要了解时区转换规则,请使用vobject searches through "all time" (默认年份为2000-2030年),查找时区相对于协调世界时的偏移量的变化。这就是问题所在,因为vobject代码不能处理pytz的无效时间错误。

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

选项:

  • 如果您不想要特定的时间段(如原始问题所示),请使用date而不是datetime。日期没有时区,所以这些都不适用。(和vobject处理日期只需fine.)
  • Convert所有的datetime,以了解UTC的日期时间。UTC不需要VTIMEZONE definition.
  • Use dateutil timezones而不是pytz。例如,from dateutil import tz; ... tzinfo=tz.gettz('America/Los_Angeles')。由于dateutil是一个vobject依赖项,我认为这就是vobject的VTIMEZONE生成器所针对的格式。(但没有进行广泛的测试。此外,gettz需要在您的机器上安装tzdb文件,所以对于您使用的每个TZID,您自己的VTIMEZONE定义并不完全portable.)
  • Add到iCalendar,这应该可以避免vobject中有问题的自动时区生成代码。(未经测试。而且在一般的case.)
  • Submit a PR to fix vobject to work with pytz.

中获得正确的信息也很复杂

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21128695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档