【问题标题】:Joda - the right way to get daylight savings independent timesJoda - 获得夏令时独立时间的正确方法
【发布时间】:2013-01-28 03:59:02
【问题描述】:

我正在开发一些闹钟功能,我正在使用 Joda 来计算每个闹钟时间的毫秒数。我有一些实用方法,例如:

 public static DateTime getNextDateTimeWithHourMinute(int hour, int minute) {
    DateTime now = new DateTime();
    DateTime then = now
            .withHourOfDay(hour)
            .withMinuteOfHour(minute)
            .withSecondOfMinute(0)
            .withMillisOfSecond(0);

    return then.isBefore(now) ? then.plusDays(1) : then;
}

它为我计算下一个小时和分钟的下一次出现。问题是,如果我们尝试获取例如 3 月 10 日凌晨 2:00,那么我们将得到一个

java.lang.IllegalArgumentException:由于时区而导致的非法瞬间 偏移过渡:2013-03-10T07:00:00.000

我知道在这种情况下根本不存在时间,但是有一种简单的方法可以确定now 和then 之间发生了一些转换,然后自动进行更正。显然,更正取决于您的用例。就我而言,我希望它是这样,如果从现在到现在时钟回落,我会得到一个延迟一个小时的 DateTime 对象。换句话说,例如,如果用户将闹钟设置为凌晨 3 点,然后时钟在该时间附近向后移动,则闹钟将在时钟时间显示为凌晨 3 点(现在是一小时后)时触发。抱歉吐槽了,希望这个问题有点道理。

【问题讨论】:

  • 您在库中弄错了“类型” - 请改用LocalTime 或LocalDate(使用LocalTime.toDateTimeToday() 或LocalDate.toDateTime() 或DateTime.toLocalTime() 或其他东西)。严格来说,无论如何,由于 DST(和时区),警报不应该处理“确切”时间 - 你应该从“本地”值构建它们。如果闹钟在“失踪”时间响起怎么办?
  • 优点@Clockwork-Muse。我要研究切换类型。我不确定这将如何帮助我推理/避免这些类型的错误。执行LocalDate localDate = new LocalDate().withMonthOfYear(3).withDayOfMonth(10); LocalTime localTime = new LocalTime().withHourOfDay(2); DateTime dateTime = localDate.toDateTime(localTime); 之类的操作仍然会导致错误。
  • 构造一个LocalDateTime() 然后使用DateTimeZone.isLocalDateTimeGap(...) 应该能够找到它们。此外,DateTimeZone.getMillisKeepLocal(...) 似乎是“间隙安全”,因为它从给定的“本地”值返回时区的“下一个可用”时间。
  • @Clockwork-Muse 非常感谢。但是我如何从 LocalDateTime 获得一个瞬间传递给 getMillisKeepLo​​cal?
  • 另外,如果 isLocalDateTimeGap 返回 true,我如何才能确定转换的方向,即向后或向前?

标签: java datetime jodatime


【解决方案1】:

您可以对闹钟的日期/时区撒谎。例如:

LocalDate localDate = new LocalDate().withMonthOfYear(3).withDayOfMonth(10);
LocalTime localTime = new LocalTime().withHourOfDay(2);
DateTime dateTime = localDate.toDateTime(localTime, DateTimeZone.UTC);
DateTime dt = new DateTime(DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), dateTime.getMillis()));

System.out.println(dateTime);
System.out.println(dt);

在我的情况下打印出来:

2013-03-10T02:09:42.333Z
2013-03-10T03:09:42.333-07:00

(我住在华盛顿)

然而,我认为最好使用以下顺序的东西:

DateTime.now().toLocalDateTime().isBefore(new LocalDateTime(2013, 3, 10, 2, 0));

哪个更,呃,语义正确。

【讨论】:

  • 您对 isBeforeNow 部分有何看法?你想在那里说明什么?
  • .isBefore() 部分让我可以说,“嘿!是这个任意日期/时间组合之前的当前时刻(无论我在地球上的哪个地方)(不反映时区) )?”。从概念上讲,这就是您实际处理的内容:在我指定的“时区不可知”日期/时间组合之前,这个瞬间是否翻译为我所在的位置?
猜你喜欢
  • 2012-10-16
  • 1970-01-01
  • 2013-11-23
  • 2021-01-20
  • 2012-12-03
  • 2012-08-30
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多