0

I'm getting the milliseconds for the alarmmanager to set repeating alarm and I'm getting strange results -

I set alarm at 8:55 am

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

Then I used this method to get the milliseconds since epoch (1970) -

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

I got the alarm came in instantly so I checked the old way of getting milliseconds from Calendar vs java time -

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

I got the localdatetime built by this -

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

Then I get it to convert to Instant and uses ZoneOffset - UTC -

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

I'm not sure why toEpochMilliseconds isn't working as it is intended?

Calendar inputs -

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, earliestDay.getHour());
calendar.set(Calendar.MINUTE, earliestDay.getMinute());
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Meep
  • 501
  • 6
  • 24
  • In which time zone do you want your alarm at 8:55? Your `Instant` is at 8:55 UTC as you had asked for. You `Calendar` seems to be at 13:55 UTC, which suggests that it was created at zone offset -05:00. – Ole V.V. May 23 '18 at 05:03
  • 1
    The alarm time should be in CST. I'm trying to see your point here... I need to get the timezone included before I call instant.toEpochMilli(). – Meep May 23 '18 at 11:45
  • np, thank you for the method name, let me see what I can do – Meep May 23 '18 at 11:53
  • You got it right - I needed ZoneId : America/Chicago which is -5:00 as well. The alarm went up correctly. Can you post the brief answer below so I can give you thumbs up and thanks! – Meep May 23 '18 at 12:26

1 Answers1

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()");

I set my JVM’s time zone to America/Chicago too and ran this code. Then it printed:

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

The difference is 0.8 second. And it’s the Calendar that’s inaccurate since it hasn’t had its milliseconds cleared.

When you want an alarm at 08:55 in America/Chicago time zone, you should state that and not use ZoneOffset.UTC for defining the Instant.

As long as your time zone is America/Chicago, you may consider using ZoneId.systemDefault() for the zone. The default setting may be changed at any time from other parts of your program or other programs running in the same JVM, which might lead to surprises.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Yes, for some reason, there are lot of comments about ZoneOffset.UTC for android AlarmManager and thanks for the summary/clarifications. – Meep May 23 '18 at 20:13