Android Calendar.getInstance () не выходит сегодня после полуночи - PullRequest
0 голосов
/ 12 октября 2019

У меня есть следующий код:

Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
Calendar cal = Calendar.getInstance();

long diff = nextSchedule.getTimeInMillis() - cal.getTimeInMillis();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;

Как и ожидалось, около 11:00 это дало мне 13/12 часов, но при выполнении следующих действий в виджете:

Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextSchedule.getTimeInMillis(), pendingIntent);

Около 1:30:00, это было все еще не обновлено. Только когда-то между 2 и 9 часами утра (я спал) он обновился.

Подобная странная вещь случается в другом месте. У меня есть представление календаря (applandeo) со следующим кодом: cvCalendar.setOnDayClickListener(eventDay -> showDateItems(eventDay,lvCalendar));

private void showDateItems(EventDay eventDay, ListView lvCalendar) {
    Calendar cal = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    cal.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),eventDay.getCalendar().get(Calendar.DATE));
    cal2.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),1);
    cal2.add(Calendar.MONTH, -1);
    ArrayList<String> items = new ArrayList<>();
    String line;
    for (ItemsHistoryItem item: Utils.getInstance().itemsHistory) {
        if (item.getxDay() < Utils.getInstance().calenderToEpoch(cal2) && item.getyDay() < Utils.getInstance().calenderToEpoch(cal2)) break;
        if (item.getxDay() != Utils.getInstance().calenderToEpoch(cal) && item.getyDay() != Utils.getInstance().calenderToEpoch(cal)) continue;
        line = item.getItemId() + ": $" + item.getAmount();
        if (item.getxDay() == Utils.getInstance().calenderToEpoch(cal))
            line += " (x day)";
        else
            line += " (y day)";
        items.add(line);
    }
    ArrayAdapter<String> lcAdapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_list_item_1, items);
    lvCalendar.setAdapter(lcAdapter);
}

long calenderToEpoch(Calendar cal2) {
    return TimeUnit.MILLISECONDS.toDays(cal2.getTimeInMillis());
}

По сути, приведенный выше код сканирует даты элементов, и когда пользователь выбирает определенную дату, он получает список элементов, которыедаты (х и у) относятся к этой дате. Делая это днем, это работает. При этом в 1:30 (например), он сдвигается на один день вперед, поэтому, если пользователь нажимает 12-окт, он получает элементы 11-окт. Когда-то между 2 и 9 часами утра он «сдвигается» назад и работает как положено.

Есть идеи, что здесь не так?

Ответы [ 2 ]

0 голосов
/ 13 октября 2019

По-видимому, часовой пояс по умолчанию для Calendar.getInstance () в моем случае был GMT + 3, поэтому в 3 часа ночи элементы были показаны для их дат, а виджет был обновлен. чтобы исправить это, я просто сделал следующее:

Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
0 голосов
/ 12 октября 2019

У меня есть предложение для правильного использования AlarmManager, если вы хотите, чтобы он срабатывал точно в то время, когда вы хотите, иначе он не срабатывает вовремя, когда устройство находится в режиме глубокого сна и задерживается:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // use setAlarmClock function of AlarmManager
        // but this function will show an alarm icon on statusbar
        // if you dont want to show that icon you can use
        // setExactAndAllowWhileIdle function but that will not be 
        // perfectly exact
    }
    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // use setExact function of AlarmManager
    }
    else {
        // use set function of AlarmManager
    }
...