Localdatetime 到 epoch/calendar.getTimeInMillis() for alarmmanager

Localdatetime to epoch/calendar.getTimeInMillis() for alarmmanager

我正在获取 alarmmanager 设置重复警报的毫秒数,但我得到了奇怪的结果 -

我在 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());
    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,因为它没有清除它的毫秒数。

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

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