localdatetime到epoch / calendar.getTimeInMillis()用于alarmmanager

时间:2018-05-22 13:59:31

标签: android alarmmanager milliseconds java.time.instant

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

我在上午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);

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

日历输入 -

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

1 个答案:

答案 0 :(得分:0)

    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中运行的其他程序更改默认设置,这可能会导致意外。