【问题标题】:What's VTIMEZONE used for in icalendar? Why not just UTC time?icalendar 中的 VTIMEZONE 用于什么?为什么不只是UTC时间?
【发布时间】:2017-08-12 16:15:21
【问题描述】:

icalendar 中的 VTIMEZONE 是做什么用的?

例如1

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//Mac OS X 10.12.3//EN
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Asia/Shanghai
BEGIN:STANDARD
TZOFFSETFROM:+0900
RRULE:FREQ=YEARLY;UNTIL=19910914T150000Z;BYMONTH=9;BYDAY=3SU
DTSTART:19890917T000000
TZNAME:GMT+8
TZOFFSETTO:+0800
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0800
DTSTART:19910414T000000
TZNAME:GMT+8
TZOFFSETTO:+0900
RDATE:19910414T000000
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
TRANSP:OPAQUE
LAST-MODIFIED:20170305T083916Z
UID:gjo1burcjnsib4p2j8tbbv4hh0@google.com
DTSTAMP:20170305T083916Z
LOCATION:Cell Group
DESCRIPTION:
STATUS:CONFIRMED
SEQUENCE:0
SUMMARY:Study Bible
DTSTART;TZID=Asia/Shanghai:20170324T193000
DTEND;TZID=Asia/Shanghai:20170324T213000
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
CREATED:20160312T140632Z
RRULE:FREQ=WEEKLY;BYDAY=FR
BEGIN:VALARM
X-WR-ALARMUID:9B47E27E-9063-417E-B488-409387A3201A
UID:9B47E27E-9063-417E-B488-409387A3201A
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
ACKNOWLEDGED:20161125T105826Z
X-APPLE-DEFAULT-ALARM:TRUE
ACTION:NONE
END:VALARM
END:VEVENT
END:VCALENDAR

来自iCalendar Documentation

VTIMEZONE:提供一组定义时区的组件属性。

1。 VTIMEZONE的定义是什么?

描述某个地点的冬令时和夏令时是否有规则?

2。 VTIMEZONE 是做什么用的?

我不必在 icalendar 对象中指定 VTIMEZONE 组件。相反,我将本地时间转换为 UTC 时间,并导出 icalendar 事件。

# Before
DTSTART:20170324T113000Z
DTEND:20170324T130000

# After
DTSTART;TZID=Asia/Shanghai:20170324T193000
DTEND;TZID=Asia/Shanghai:20170324T213000

2.1 这有意义吗?没有 VTIMEZONE 的 icalendar 对象

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//Mac OS X 10.12.3//EN
BEGIN:VEVENT
TRANSP:OPAQUE
LAST-MODIFIED:20170305T083916Z
UID:gjo1burcjnsib4p2j8tbbv4hh0@google.com
DTSTAMP:20170305T083916Z
LOCATION:Cell Group
DESCRIPTION:
STATUS:CONFIRMED
SEQUENCE:0
SUMMARY:Study Bible
DTSTART;TZID=Asia/Shanghai:20170324T113000
DTEND;TZID=Asia/Shanghai:20170324T213000
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
CREATED:20160312T140632Z
RRULE:FREQ=WEEKLY;BYDAY=FR
BEGIN:VALARM
X-WR-ALARMUID:9B47E27E-9063-417E-B488-409387A3201A
UID:9B47E27E-9063-417E-B488-409387A3201A
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
ACKNOWLEDGED:20161125T105826Z
X-APPLE-DEFAULT-ALARM:TRUE
ACTION:NONE
END:VALARM
END:VEVENT
END:VCALENDAR

2.2 如果说得通的话,VTIMEZONE 有什么用?

3。 VTIMEZONE 和 VEVENT 之间的一致性

举个例子以 1 为例。

....
BEGIN:VTIMEZONE
TZID:Asia/Shanghai                           <- Part 1
.....
END:VTIMEZONE


BEGIN:VEVENT
....
DTSTART;TZID=Asia/Shanghai:20170324T193000   <- Part 2
DTEND;TZID=Asia/Shanghai:20170324T213000     <- Part 3
....
END:VEVENT

3.1。 VEVENT 中的时区必须与 VTIMEZONE 一致吗?

3.2 part2和part3的时间可以用其他时区来描述吗?

例如

....
BEGIN:VTIMEZONE
TZID:Asia/Shanghai                           <- Part 1
.....
END:VTIMEZONE


BEGIN:VEVENT
....
DTSTART:20170324T193000Z   <- Part 2 UTC time
DTEND:20170324T213000Z     <- Part 3 UTC Time
....
END:VEVENT

【问题讨论】:

    标签: calendar timezone icalendar rfc5545


    【解决方案1】:

    1. VTIMEZONE的定义是什么?

    VTIMEZONE 用于存储时区在任何给定时间点(即夏令时和标准时间)的 UTC 偏移量的特定规则。

    2。 VTIMEZONE 是做什么用的?

    当您想在特定时区而不是 UTC 下格式化整个 iCalendar 中的各种时间戳时使用它。

    您可能会问:为什么不到处使用 UTC?这不是更简单吗?答案是:由于重复规则,需要时区。如果您有重复事件,并且该事件跨越了日光/标准边界,则必须为该事件指定时区。如果您只是使用 UTC,那么一旦您通过日光/标准边界,事件的时间就会变得不正确。

    2.1 这有意义吗?没有 VTIMEZONE 的 icalendar 对象

    你的例子不正确。

    您示例中的 DTEND 属性引用了一个不存在的 VTIMEZONE 组件(“亚洲/上海”)。

    DTEND;TZID=Asia/Shanghai:20170324T213000
    

    iCalendar 解析器将查看该 TZID 参数,然后查找其 TZID 属性与之匹配的 VTIMEZONE 组件。因为您的 iCalendar 对象没有这样的 VTIMEZONE,所以 iCalendar 解析器在技术上不知道如何解释该日期。 TZID 参数仅被视为唯一标识符。它本身没有任何意义。

    如果您希望在特定时区下格式化日期,但又不想在 iCalendar 对象中包含 VTIMEZONE 组件,则可以使用全局时区 ID。全球时区 ID 与普通 TZID 参数不同,因为它们以 正斜杠开头:

    DTEND;TZID=/Asia/Shanghai:20170324T213000
    

    全局时区 ID 的缺点是 iCalendar 规范没有指定解析器应该如何解释这些 ID。但是,在实践中,我想在所有支持全局 ID 的解析器中,大多数可能将它们视为 Olson ID。

    3.1. VEVENT 中的时区必须与 VTIMEZONE 一致吗?

    在 VTIMEZONE 组件中定义的时区具有跨 iCalendar 对象的全局范围。因此,VEVENT 中的任何 TZID 参数都必须引用 VTIMEZONE 组件(除非它是全局时区 ID)。

    3.2 part2和part3的时间可以用其他时区来描述吗?

    仅仅因为您的 iCalendar 对象具有 VTIMEZONE 组件,并不意味着您必须使用它。你的例子是有效的。

    【讨论】:

    • 非常有用,时区的正斜杠提示让我很开心
    • 不开玩笑。为时区添加正斜杠是杀手锏。但是,不幸的是,它没有通过 ical 验证器工具。 icalendar.org/validator.html
    【解决方案2】:

    来自时间紧迫的程序员... VTIMEZONE 在 icalendar.py 中很难管理

    我选择了以下捷径:

    from datetime import datetime
    import pytz
    import icalendar
    
    mytz = pytz.timezone('<your timezone>')
    timestamp = datetime.now().replace(second=0, microsecond=0)
    
    # ... < Lots of code there >
    event.add('dtstamp',vDatetime(mytz.localize(timestamp).astimezone(pytz.UTC)))
    3 --- < tons of code here >
    
    

    dtstartdtend做了同样的事情

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-06
      • 2010-09-19
      • 2011-10-16
      • 2016-04-11
      • 1970-01-01
      • 2017-12-05
      • 2012-02-14
      • 2019-03-05
      相关资源
      最近更新 更多