Проблема с григорианским календарем

Мы используем приведенный ниже фрагмент кода, чтобы получить количество дней для указанного месяца и года. Для 02 и 2011 он возвращает количество дней как 31 (что не так). для 02 и 2016 он возвращает количество дней как 29.

Любые подсказки.

package Processes.BSAInvoiceInquiry.ExternalCall.PaymentStatusInquiry;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class PaymentStatusInquiryJavaCode {

    protected int year = 0;
    protected int month = 0;
    protected int days = 0;

    public void invoke() throws Exception {

        PaymentStatusInquiryJavaCode a = new PaymentStatusInquiryJavaCode();

        System.out.println("Year  " + year);
        System.out.println("Month  " + month);

        Calendar calObj = new GregorianCalendar();
        calObj.set(Calendar.YEAR, year);
        calObj.set(Calendar.MONTH, month - 1);
        System.out.println("Month  " + Calendar.MONTH);
        int numDays = calObj.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("No of the days in the month is   " + numDays);
        days = numDays;

    }
}

person Abdul Kader    schedule 29.04.2018    source источник
comment
Для 02 и 2011 он возвращает количество дней как 31 (что не так).   -  person Abdul Kader    schedule 29.04.2018
comment
Вы обязательно должны изучить пакет Java 8 java.time. Надежные удобные неизменяемые инструменты.   -  person Dreamspace President    schedule 29.04.2018
comment
@DreamspacePresident наш инструмент все еще зависит от Java 1.7   -  person Abdul Kader    schedule 29.04.2018
comment
Нет большой проблемы @AbdulKader. java.time был перенесен на Java 6 и 7. Получите ThreeTen Backport, добавьте его в свой проект и начните используя современный API даты и времени Java. И наслаждаться! Учитывая проблемы, с которыми вы столкнулись со старомодным классом Calendar, это будет большим облегчением.   -  person Ole V.V.    schedule 29.04.2018
comment
@AbdulKader Я написал новый ответ на связанный вопрос. Параграф «Если бы вам нужно было только посчитать дни в каком-то месяце…» — для вас. Взгляни, пожалуйста.   -  person Ole V.V.    schedule 29.04.2018


Ответы (3)


Это еще одно неожиданное поведение Calendar, см. это, вы можете исправить это с помощью clear после творчество:

Calendar calendar = new GregorianCalendar();
calendar.clear();
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.MONTH, 1);
System.out.println(calendar.getActualMaximum(calendar.DAY_OF_MONTH)); //28

Следует избегать использования устаревшего Calendar. В java8 это можно сделать:

YearMonth yearMonth = YearMonth.of(2011, 2);
int lengthOfMonth = yearMonth.lengthOfMonth();
System.out.println(lengthOfMonth); //28
person xingbin    schedule 29.04.2018
comment
@ user66902200 не помогло, та же проблема - person Abdul Kader; 29.04.2018
comment
@AbdulKader Тогда, пожалуйста, опубликуйте свой тестовый код. Код теста в ответе работает нормально. - person xingbin; 29.04.2018

Чтобы завершить ответ user6690200 он возвращает 29 для 2016 года, потому что сегодня 29-е, а 2016 год был високосным и имел 29 февраля. 2011 год не был високосным, поэтому он фактически возвращает номер следующего месяца (март, в котором 31 день).

person Oleg    schedule 29.04.2018
comment
в идеале не должно быть 28 - person Abdul Kader; 29.04.2018
comment
Не знаю, так они это реализовали. - person Oleg; 29.04.2018

пытаться

// month 1 based    
new Calendar.Builder().setDate(year, month-1, 1).build().getActualMaximum(DAY_OF_MONTH)

проблема ни в чем

calObj.set(DAY_OF_MONTH, 1);
person Giacomo    schedule 29.04.2018
comment
DAY_OF_MONTH отсчитывается от 1, 0 – день минус - person Giacomo; 29.04.2018
comment
2011:2-1:0 — это 2011:1:31, затем 31, 2016:2-1:0 — это 2016:1:29, затем 29. - person Giacomo; 29.04.2018