расчет последнего дня месяца


у меня возникли проблемы с расчетом, когда следующий последний день месяца для уведомления, которое планируется отправить.

вот мой код:

RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();

это линия, вызывающая проблемы, я считаю:

nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(), 
                  recurrenceFrequency.getRecurrenceOffset());

Как я могу использовать календарь, чтобы правильно определить последний день месяца, следующего за уведомление?

8 107

8 ответов:

Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);

это возвращает фактический максимум за текущий месяц. Например, сейчас февраль високосного года, поэтому он возвращает 29 как int.

java.время

С помощью java.time библиотека, встроенная в Java 8, вы можете использовать TemporalAdjuster класса (или TemporalAdjusters служебный класс)

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

и получить последний день в качестве объекта даты:

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 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) метод объекта календаря.

Если вы установили объект календаря в том месяце, для которого вы ищете последнюю дату, то 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));