В этом нет ничего плохого, это зависит от интерпретации "добавление одного года", для java.util.Calendar#add
это:
add (f, delta) добавляет delta
в поле f
. Это эквивалентно вызову set(f, get(f) + delta)
с двумя настройками:
Добавить правило 1. Значение поля f после вызова минус значение поля f до вызова дельта, по модулю любое переполнение, которое произошло в поле f. Переполнение происходит, когда значение поля превышает его диапазон, и в результате следующее большее поле увеличивается или уменьшается, а значение поля возвращается в его диапазон.
Добавить правило 2. Если ожидается, что поле меньшего размера будет инвариантным, но для него невозможно быть равным его предыдущему значению из-за изменений его минимума или максимума после изменения поля f или других ограничений, таких как изменение смещения часового пояса, то его значение настроен так, чтобы быть как можно ближе к ожидаемому значению. Меньшее поле представляет меньшую единицу времени. HOUR - это поле меньше, чем DAY_OF_MONTH. Не вносятся изменения в меньшие поля, которые не должны быть инвариантными. Календарная система определяет, какие поля должны быть инвариантными.
Кроме того, в отличие от set (), add () вызывает немедленный пересчет миллисекунд календаря и всех полей.
Пример : рассмотрим GregorianCalendar, изначально установленный на 31 августа 1999 года. При вызове add (Calendar.MONTH, 13) календарь устанавливается на 30 сентября 2000 года. Правило добавления 1 устанавливает для поля MONTH значение сентября, а для добавления 13 месяцев - август дает сентябрь следующего года. Так как DAY_OF_MONTH не может быть 31 в сентябре в GregorianCalendar, правило добавления 2 устанавливает для DAY_OF_MONTH значение 30, наиболее близкое возможное значение. Хотя это поле меньшего размера, DAY_OF_WEEK не корректируется по правилу 2, поскольку ожидается, что оно изменится, когда месяц изменится в GregorianCalendar.
Звучит в соответствии с описанным поведением, что и почему вы ожидаете? Может быть, есть лучшие / более специализированные решения.