繁体   English   中英

VTIMEZONE 在 icalendar 中有什么用? 为什么不只是UTC时间?

[英]What's VTIMEZONE used for in icalendar? Why not just UTC time?

VTIMEZONE 在 icalendar 中有什么用?

例如 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 文档

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 我可以使用其他时区来描述第 2 部分和第 3 部分的时间吗?

例如

....
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

1. VTIMEZONE的定义是什么?

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

2.什么是VTIMEZONE用于?

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

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

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

你的例子是不正确的。

示例中的DTEND属性引用了不存在的VTIMEZONE组件(“Asia / Shanghai”)。

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我可以使用其他时区来描述第2部分和第3部分的时间吗?

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

来自时间压力下的程序员... 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做了同样的dtend

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM