Я сделал простой тест в классе Calendar. Код:
public static void main(String[] args) {
TimeZone tz = TimeZone.getTimeZone("Asia/Kathmandu");
System.out.println(tz.getDisplayName());
Calendar cal1 = Calendar.getInstance();
cal1.set(2014, 8, 31);
System.out.println(cal1.getTimeZone().getDisplayName());
Calendar cal2 = Calendar.getInstance();
cal2.set(2014,9,1);
int diff = cal2.get(Calendar.MONTH)-cal1.get(Calendar.MONTH);
System.out.println(diff);
System.out.println(cal2.get(Calendar.MONTH));
System.out.println(cal1.get(Calendar.MONTH));
}
В результате получилось:
Nepal Time
Nepal Time
0
9
9
Почему я получаю MONTH как "9" для cal1 вместо "8"?
Поскольку нумерация месяца начинается с 0
, так что 8
й месяц - September
, у которого 30
дней.
Но вы назначили день 31
. Дополнительный 1
день добавляется к следующему месяцу October
, номер месяца 9
. Так как cal1
и cal2
имеет месяц - October
.
Вот почему в обоих случаях он показывает 9
.
В календаре массив месяцев начинается с нуля, поэтому январь равен 0. Вводя в 8/31, система думает, что вы говорите 31 сентября, что будет 9-м месяцем, поэтому 8-й в массиве. 31 сентября не существует, поэтому система ударяет месяц до октября, поэтому 9-й в массиве.
Я бы предложил использовать константы календаря вместо чисел за месяцы.
Calendar.AUGUST
Calendar.SEPTEMBER
Если вы посмотрите внутри исходного кода (находящегося в src.zip в вашей папке JDK) класса java.util.Calendar
вы увидите следующий код:
/**
* Value of the {@link #MONTH} field indicating the
* first month of the year in the Gregorian and Julian calendars.
*/
public final static int JANUARY = 0;
/**
* Value of the {@link #MONTH} field indicating the
* second month of the year in the Gregorian and Julian calendars.
*/
public final static int FEBRUARY = 1;
/**
* Value of the {@link #MONTH} field indicating the
* third month of the year in the Gregorian and Julian calendars.
*/
public final static int MARCH = 2;
/**
* Value of the {@link #MONTH} field indicating the
* fourth month of the year in the Gregorian and Julian calendars.
*/
public final static int APRIL = 3;
/**
* Value of the {@link #MONTH} field indicating the
* fifth month of the year in the Gregorian and Julian calendars.
*/
public final static int MAY = 4;
/**
* Value of the {@link #MONTH} field indicating the
* sixth month of the year in the Gregorian and Julian calendars.
*/
public final static int JUNE = 5;
/**
* Value of the {@link #MONTH} field indicating the
* seventh month of the year in the Gregorian and Julian calendars.
*/
public final static int JULY = 6;
/**
* Value of the {@link #MONTH} field indicating the
* eighth month of the year in the Gregorian and Julian calendars.
*/
public final static int AUGUST = 7;
/**
* Value of the {@link #MONTH} field indicating the
* ninth month of the year in the Gregorian and Julian calendars.
*/
public final static int SEPTEMBER = 8;
/**
* Value of the {@link #MONTH} field indicating the
* tenth month of the year in the Gregorian and Julian calendars.
*/
public final static int OCTOBER = 9;
/**
* Value of the {@link #MONTH} field indicating the
* eleventh month of the year in the Gregorian and Julian calendars.
*/
public final static int NOVEMBER = 10;
/**
* Value of the {@link #MONTH} field indicating the
* twelfth month of the year in the Gregorian and Julian calendars.
*/
public final static int DECEMBER = 11;
Почему я получаю MONTH как "9" для cal1 вместо "8"?
Потому что месяцы начинаются с 0.
0 for January
1 for February
...
11 for December
Я рекомендую использовать поля константы Calendar в течение нескольких месяцев, например Calendar.JANUARY
, Calendar.FEBRUARY
... Calendar.DECEMBER
чтобы избежать путаницы.
Это потому, что cal1.set(2014, 8, 31);
инициировать календарь с 31-м днем сентября (на основе нуля). потому что сентябрь имеет только 30 дней, это будет первый октябрь, и именно поэтому вы получаете 9
в месяц, что такое октябрь в индексе с нулевым индексом.
java.time
если можете. Там гораздо меньше сюрпризов.