Ответ 1
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
Это возвращает фактический максимум для текущего месяца. Например, это февраль високосного года, поэтому он возвращает 29 как int
.
У меня возникают проблемы с расчетом того, когда следующий последний день месяца отправляется для уведомления, которое планируется отправить.
Вот мой код:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
Это строка, вызывающая проблемы, которые я считаю:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
Как я могу использовать календарь, чтобы правильно установить последний день следующего месяца для уведомления?
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
Это возвращает фактический максимум для текущего месяца. Например, это февраль високосного года, поэтому он возвращает 29 как int
.
Используя библиотеку 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
И получить последний день как объект Date:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
Date lastDayOfMonth = cal.getTime();
Вы можете установить календарь в первый из следующего месяца, а затем вычесть день.
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
здесь - лучшее решение:
LocalDate date = LocalDate.now();
LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
В качестве альтернативы вы можете:
LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
Посмотрите на метод getActualMaximum(int field)
объекта 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));
Вы также можете использовать 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--.
Реализация продления даты в Kotlin с использованием java.util.Calendar
fun Date.toEndOfMonth(): Date {
return Calendar.getInstance().apply {
time = [email protected]
}.toEndOfMonth().time
}
fun Calendar.toEndOfMonth(): Calendar {
set(Calendar.DAY_OF_MONTH, getActualMaximum(Calendar.DAY_OF_MONTH))
return this
}
Вы можете вызывать функцию toEndOfMonth
для каждого объекта Date().toEndOfMonth()
например Date().toEndOfMonth()