расчет последнего дня месяца - PullRequest
122 голосов
/ 22 февраля 2012

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

Вот мой код:

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

Я считаю, что эта строка вызывает проблемы:

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

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

Ответы [ 10 ]

310 голосов
/ 22 февраля 2012
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);

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

42 голосов
/ 23 ноября 2015

java.time

Используя библиотеку 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
31 голосов
/ 22 октября 2012

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

Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));

Date lastDayOfMonth = cal.getTime();
20 голосов
/ 22 февраля 2012

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

Calendar nextNotifTime = Calendar.getInstance();
nextNotifTime.add(Calendar.MONTH, 1);
nextNotifTime.set(Calendar.DATE, 1);
nextNotifTime.add(Calendar.DATE, -1);

После запуска этого кода nextNotifTime будет установлен на последний день текущего месяца. Имейте в виду, что если сегодня последний день месяца, чистый эффект этого кода в том, что объект Calendar остается неизменным.

15 голосов
/ 31 марта 2014

Следование всегда даст правильные результаты:

    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();
7 голосов
/ 12 апреля 2017

Использование новейшей библиотеки java.time является лучшим решением:

LocalDate date = LocalDate.now();
LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());

В качестве альтернативы вы можете сделать:

LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
2 голосов
/ 12 сентября 2017
        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)); 
2 голосов
/ 22 февраля 2012

Посмотрите на метод getActualMaximum(int field) объекта Calendar.

Если вы установите объект календаря на месяц, для которого вы ищете последнюю дату, то getActualMaximum(Calendar.DAY_OF_MONTH) даст вам последний день.

1 голос
/ 03 июля 2019

Вы также можете использовать 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--

0 голосов
/ 14 марта 2019

Реализация продления даты 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()

...