【问题标题】:Localdatetime to epoch/calendar.getTimeInMillis() for alarmmanagerLocaldatetime 到 epoch/calendar.getTimeInMillis() for alarmmanager
【发布时间】:2018-05-22 13:59:31
【问题描述】:

我得到了警报管理器设置重复警报的毫秒数,但我得到了奇怪的结果 -

我把闹钟定在早上 8:55

LocalDateTime Earliest Day : 2018-05-22T08:55
Instant : 2018-05-22T08:55:00Z

然后我用这个方法来获取自纪元(1970)以来的毫秒数 -

LogUtils.LOGD(TAG, instant.toEpochMilli() + " : instant.toEpochMilli()");

我立即收到警报,所以我检查了从日历与 java 时间获取毫秒的旧方法 -

1526996659862 : System.currentTimeMillis() : 
1526979300000 : instant.toEpochMilli()
1526997319862 : calendar.getTimeInMillis()

我得到了由此构建的 localdatetime -

LocalDateTime earliestDay = LocalDateTime.of(
        now.getYear(), now.getMonth().getValue(), now.getDayOfMonth(),
        localTime.getHour(), localTime.getMinute(), localTime.getSecond());

然后我将其转换为 Instant 并使用 ZoneOffset - UTC -

Instant instant = earliestDay.toInstant(ZoneOffset.UTC);

我不确定为什么 toEpochMilliseconds 没有按预期工作?

日历输入 -

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, earliestDay.getHour());
calendar.set(Calendar.MINUTE, earliestDay.getMinute());

【问题讨论】:

  • 您希望在哪个时区设置 8:55 的闹钟?您的Instant 是您所要求的 UTC 时间 8:55。你Calendar 似乎在 13:55 UTC,这表明它是在区域偏移量 -05:00 创建的。
  • 闹钟时间应该是CST。我想在这里看到你的意思......我需要在调用 instant.toEpochMilli() 之前包含时区。
  • np,谢谢你的方法名,让我看看我能做什么
  • 你说得对 - 我需要 ZoneId : America/Chicago 也是 -5:00。警报正确响起。您能否在下面发布简短的答案,以便我给您竖起大拇指,谢谢!

标签: android alarmmanager milliseconds java.time.instant


【解决方案1】:
    ZoneId zone = ZoneId.of("America/Chicago");
    LocalTime alarmTime = LocalTime.of(8, 55);

    LocalDate today = LocalDate.now(zone);
    LocalDateTime earliestDay = today.atTime(alarmTime);
    Instant instant = earliestDay.atZone(zone).toInstant();

    System.out.println(instant.toEpochMilli() + " : instant.toEpochMilli()");

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, earliestDay.getHour());
    calendar.set(Calendar.MINUTE, earliestDay.getMinute());

    System.out.println(calendar.getTimeInMillis() + " : calendar.getTimeInMillis()");

我也将 JVM 的时区设置为 America/Chicago 并运行此代码。然后打印出来:

1527083700000 : instant.toEpochMilli()
1527083700796 : calendar.getTimeInMillis()

相差 0.8 秒。 Calendar 是不准确的,因为它的毫秒数还没有被清除。

当您想要在美国/芝加哥时区的 08:55 发出警报时,您应该说明这一点,而不是使用 ZoneOffset.UTC 来定义 Instant

只要您的时区是美国/芝加哥,您就可以考虑使用ZoneId.systemDefault() 作为时区。您的程序的其他部分或在同一 JVM 中运行的其他程序可能随时更改默认设置,这可能会导致意外。

【讨论】:

  • 是的,出于某种原因,有很多关于 ZoneOffset.UTC for android AlarmManager 的 cmets,感谢您的总结/澄清。
猜你喜欢
  • 2020-05-07
  • 1970-01-01
  • 2019-02-12
  • 2018-06-02
  • 2021-04-12
  • 2015-05-30
  • 2019-03-22
  • 1970-01-01
  • 2017-12-19
相关资源
最近更新 更多