【问题标题】:Problems with DST in ICS files. How to get timezones definition from a Web Service / Web site, to include in a ICS file?ICS 文件中的 DST 问题。如何从 Web 服务/网站获取时区定义以包含在 ICS 文件中?
【发布时间】:2013-01-26 08:21:48
【问题描述】:

我们正在从 Java 代码生成一个 ICS 文件,并最初以 UTC 格式输入时间。

我们发现,在创建定期约会时,由于 DST 在第一个日期和最后一个日期之间发生变化,一些会议是在正确时间之前或之后 1 小时创建的。

我们进行了测试,发现如果我们不包含时区时间更改的完整定义,则无法使其正常工作。例如,对于在波士顿举行的会议,以下定义有效:

BEGIN:VTIMEZONE
TZID:Eastern Time (US & Canada)
BEGIN:STANDARD
DTSTART:16011104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
END:VTIMEZONE

有没有办法从任何现有的 Web 服务或网站获取这些信息?还是我们需要维护所有应用程序涉及的国家/地区的定义?

我们发现了 ICal4j 库的存在,但它似乎提供了生成 .ics 文件结构的方法,但没有提供我们需要的时区信息。

任何人都知道一种更简单的方法可以使 .ics 文件在不同的时区正常工作,并且在第一次和最后一次日期之间的时间发生变化时定期约会?

【问题讨论】:

  • 您的问题解决了吗?我对此问题的解决方案很感兴趣。

标签: timezone dst icalendar ical4j


【解决方案1】:

我知道我在这方面迟到了,但只是想为遇到此问题的任何人提供一个带有 iCal4j 的解决方案。

在 iCalendar 标准中确实没有隐式管理时区,您必须在 ICS 文件 (RFC) 中显式添加 VTIMEZONE 定义。您不能只使用时区标识符 (TZID )。

您可以参考this answer 了解为什么需要时区信息。

下面是一个使用 iCal4j 的示例:

// get timezone
final TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
final TimeZone timezone = registry.getTimeZone("Europe/Zurich");
final VTimeZone tz = timezone.getVTimeZone();

// event start date
final java.util.Calendar startDate = new GregorianCalendar();
startDate.setTimeZone(timezone);
startDate.set(2016, java.util.Calendar.MARCH, 8, 9, 0, 0);

// event end date
final java.util.Calendar endDate = new GregorianCalendar();
endDate.setTimeZone(timezone);
endDate.set(2016, java.util.Calendar.MARCH, 8, 17, 0, 0);

// create event
final DateTime start = new DateTime(startDate.getTime(), timezone);
final DateTime end = new DateTime(endDate.getTime(), timezone);
final VEvent meeting = new VEvent(start, end, "Test");
meeting.getProperties().add(new RandomUidGenerator().generateUid());
meeting.getProperties().add(new Location("Somewhere"));

// create calendar
final net.fortuna.ical4j.model.Calendar icsCalendar = new net.fortuna.ical4j.model.Calendar();
icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
icsCalendar.getProperties().add(CalScale.GREGORIAN);
icsCalendar.getProperties().add(Version.VERSION_2_0);

// add the timezone definition <- this is what you are missing
icsCalendar.getComponents().add(tz);

// add event to calendar
icsCalendar.getComponents().add(meeting);

VTimeZone 组件添加到Calendar 中的重要行。因此,您无需从 Web 服务中获取定义。

您可以参考iCal4j documentation

那么你应该得到这样的结果(对于Europe/Zurich 时区):

BEGIN:VCALENDAR
PRODID:-//Events Calendar//iCal4j 1.0//EN
CALSCALE:GREGORIAN
VERSION:2.0

BEGIN:VEVENT
DTSTAMP:20160307T231014Z
DTSTART;TZID=Europe/Zurich:20160308T090000
DTEND;TZID=Europe/Zurich:20160308T170000
SUMMARY:Test
TZID:Europe/Zurich
UID:45c269ed-dbc0-435e-bb3d-ba152dfbf0db
LOCATION:Somewhere
END:VEVENT

BEGIN:VTIMEZONE
TZID:Europe/Zurich
LAST-MODIFIED:20201011T015911Z
TZURL:http://tzurl.org/zoneinfo/Europe/Zurich
X-LIC-LOCATION:Europe/Zurich
X-PROLEPTIC-TZNAME:LMT
BEGIN:STANDARD
TZNAME:BMT
TZOFFSETFROM:+003408
TZOFFSETTO:+002946
DTSTART:18530716T000000
END:STANDARD
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+002946
TZOFFSETTO:+0100
DTSTART:18940601T000000
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19410505T010000
RRULE:FREQ=YEARLY;UNTIL=19420504T000000Z;BYMONTH=5;BYDAY=1MO
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19411006T020000
RRULE:FREQ=YEARLY;UNTIL=19421005T000000Z;BYMONTH=10;BYDAY=1MO
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19810329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19810927T030000
RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU
END:STANDARD
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE

END:VCALENDAR

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多