【问题标题】:BiWeekly Iterating over daylight savings changeBiWeekly 迭代夏令时变化
【发布时间】:2020-02-13 05:35:53
【问题描述】:

我正在尝试使用 Java BiWeekly 库在夏令时更改中迭代一个事件。

假设活动从早上 8 点开始,我希望它一直保持在早上 8 点,无论夏令时是否有效。

以下代码来自BiWeekly网站:https://github.com/mangstadt/biweekly/wiki/Examples#calculating-the-dates-in-a-recurring-event

ICalendar ical = ...
TimezoneInfo tzinfo = ical.getTimezoneInfo();

VEvent event = ical.getEvents().get(0);
DateStart dtstart = event.getDateStart();

TimeZone timezone;
if (tzinfo.isFloating(dtstart)){
  timezone = TimeZone.getDefault();
} else {
  TimezoneAssignment dtstartTimezone = tzinfo.getTimezone(dtstart);
  timezone = (dtstartTimezone == null) ? TimeZone.getTimeZone("UTC") : dtstartTimezone.getTimeZone();
}
DateIterator it = event.getDateIterator(timezone);

如果我将 celendar 创建为:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Michael Angstadt//biweekly 0.6.3//EN
BEGIN:VEVENT
UID:deb01413-942a-4ea9-a53c-541493fa668a
DTSTAMP:20200213T051827Z
SUMMARY;LANGUAGE=en-us:Team Meeting
DTSTART;TZID=/Pacific/Auckland:20200213T181827
DURATION:PT1H
RRULE:FREQ=WEEKLY;INTERVAL=2
END:VEVENT
END:VCALENDAR

在此进行迭代,当时间越过夏令时边界时,时间会改变一个小时。

应该如何做才能使事件在给定时间发生? (在UTC同时发生是正确的,但我希望它在本地同时发生。)

【问题讨论】:

  • 你在哪个时区?使用 Java,您可以获得自 1970 年以来的 EPOCH 时间(以毫秒为单位),这已经是 UTC,您只需为您的时区偏移。
  • 不相信,看起来这是一个时区问题,问题在于如果 dtstartTimezone 为空,迭代器上面的代码正在获取 UTC 时区。强制正确的时区有效。关于为什么它没有选择(我相信)在日历中的太平洋/奥克兰时区,我仍然需要做更多的测试。一旦想通了,我会回复一个答案。感谢您的回复。
  • 嘿,这是双周刊的创建者。我自己无法重现该问题,但如果您仍然遇到问题,请不要犹豫,在项目的 GitHub 页面上打开问题:github.com/mangstadt/biweekly/issues

标签: java icalendar biweekly


【解决方案1】:

由于某种原因,上面代码中的 dtstartTimezone 返回 null,即使事件的 DTSTART 中有一个时区。 (这可能是另一个需要追查的问题。)

因为这是 null,所以迭代器获取的是 UTC 时区,因此迭代的日期是基于 UTC 的,并且在跨越目标时区的夏令时边界时发生变化。

删除将时区从日历中提取出来的时区分配代码并将其替换为 val timezone = TimeZone.getTimeZone("Pacific/Auckland")(或正确的时区)并在迭代器中使用它可以解决此问题。

【讨论】:

    猜你喜欢
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 2011-02-22
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多