У меня возникают проблемы с вычислением того, когда в следующий последний день месяца будет отправлено уведомление, которое планируется отправить.
Вот мой код:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
Я считаю, что эта строка вызывает проблемы:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
Как я могу использовать Календарь, чтобы правильно установить последний день следующего месяца для уведомления?
Ответы:
Это возвращает фактический максимум за текущий месяц. Например, сейчас февраль високосного года, поэтому он возвращает 29 как
int
.источник
ActualMaximum
на каждое свидание - не проблема . Просто перед звонком сверните экземпляр календаря на нужную датуgetActualMaximum
. Первое свидание может быть полученоgetActualMinimum()
nextNotification.setReadyDateTime(nextNotifTime.getTime());
поэтому я не должен делать это вместо:nextNotifTime.roll(Calendar.MONTH, true); nextNotifTime.getActualMaximum(Calendar.DAY_OF_MONTH); nextNotifTime.setTime(Calendar.DAY_OF_MONTH);
?java.time.temporal.TemporalAdjusters.lastDayOfMonth ()
Используя
java.time
встроенную в Java 8 библиотеку, вы можете использоватьTemporalAdjuster
интерфейс. Мы считаем , реализация готова к использованию вTemporalAdjusters
классе полезности:lastDayOfMonth
.import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; LocalDate now = LocalDate.now(); //2015-11-23 LocalDate lastDay = now.with(TemporalAdjusters.lastDayOfMonth()); //2015-11-30
Если вам нужно добавить информацию о времени, вы можете использовать любую доступную
LocalDate
дляLocalDateTime
преобразования, напримерlastDay.atStartOfDay(); //2015-11-30T00:00
источник
LocalDateTime
. В этом классе отсутствует понятие часового пояса или смещения от UTC. Таким образом, он не может определить, когда на самом деле начинается конкретный день в конкретном месте. Этот класс работает только для обычных 24-часовых дней, а не для реальных дней. Для настоящих дней, указать часовой пояс:ZonedDateTime zdt = now.atStartOfDay( ZoneId.of( "Asia/Tokyo" ) ) ;
. Некоторые дни в некоторых местах могут начинаться в другое время, например, 01:00, из-за аномалий, таких как переход на летнее время (DST).И чтобы получить последний день как объект Date:
источник
Вы можете установить календарь на первое число следующего месяца, а затем вычесть день.
Calendar nextNotifTime = Calendar.getInstance(); nextNotifTime.add(Calendar.MONTH, 1); nextNotifTime.set(Calendar.DATE, 1); nextNotifTime.add(Calendar.DATE, -1);
После запуска этого кода nextNotifTime будет установлен на последний день текущего месяца. Имейте в виду, что если сегодня последний день месяца, чистый эффект этого кода заключается в том, что объект Calendar остается неизменным.
источник
Следующие действия всегда будут давать правильные результаты:
Calendar cal = Calendar.getInstance(); cal.set(Calendar.MONTH, ANY_MONTH); cal.set(Calendar.YEAR, ANY_YEAR); cal.set(Calendar.DAY_OF_MONTH, 1);// This is necessary to get proper results cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE)); cal.getTime();
источник
java.time
Лучшее решение - использовать последнюю версию библиотеки:В качестве альтернативы вы можете:
источник
Вы также можете использовать YearMonth.
Подобно:
YearMonth.of(2019,7).atEndOfMonth() YearMonth.of(2019,7).atDay(1)
См. Https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html#atEndOfMonth--
источник
Посмотрите на
getActualMaximum(int field)
метод объекта Calendar.Если вы установите объект Calendar в том месяце, для которого вы ищете последнюю дату, тогда
getActualMaximum(Calendar.DAY_OF_MONTH)
вы получите последний день.источник
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); Date date = sdf.parse("11/02/2016"); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); System.out.println("First Day Of Month : " + calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); System.out.println("Last Day of Month : " + calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
источник
Реализация расширения даты Kotlin с использованием
java.util.Calendar
fun Date.toEndOfMonth(): Date { return Calendar.getInstance().apply { time = this@toEndOfMonth }.toEndOfMonth().time } fun Calendar.toEndOfMonth(): Calendar { set(Calendar.DAY_OF_MONTH, getActualMaximum(Calendar.DAY_OF_MONTH)) return this }
Вы можете вызвать
toEndOfMonth
функцию для каждого объекта Date, напримерDate().toEndOfMonth()
источник