В классе GregorianCalendar есть метод:
публичный недействительный бросок (целое поле, целое количество)
Это задокументировано здесь:
http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#roll%28int,%20int%29
Существует два метода добавления и вычитания некоторого периода времени в календаре с установленной датой: add() и roll(). Вы используете или другой в зависимости от этой ситуации. Когда вы используете roll(), это дает пример:
Рассмотрим GregorianCalendar, первоначально установленный на воскресенье 6 июня 1999 года. Вызов roll(Calendar.WEEK_OF_MONTH, -1) устанавливает календарь на вторник 1 июня 1999 года.
Это связано с тем, что правило прокрутки накладывает дополнительное ограничение: МЕСЯЦ не должен меняться, когда прокручивается WEEK_OF_MONTH. В сочетании с правилом добавления 1 результирующая дата должна быть между вторником 1 июня и субботой 5 июня.
Согласно правилу добавления 2, DAY_OF_WEEK, инвариант при изменении WEEK_OF_MONTH, устанавливается на вторник, ближайшее возможное значение к воскресенью (где воскресенье — первый день недели).
Я сам вчера пробовал это:
Calendar cal = GregorianCalendar.getInstance();
cal.set(1999,5,6);
System.out.println(cal.getTime().toString());
Это печатает: Sun Jun 06 18:15:30 BST 1999
Пока все хорошо.
А теперь попробуем метод ролла:
cal.roll(Calendar.WEEK_OF_MONTH, -1);
System.out.println(cal.getTime().toString());
Это печатает: Wed Jun 30 18:15:30 BST 1999 Время откатывается на 1 неделю, но месяц остается прежним.
Нет, как предполагалось в документации: вторник, 1 июня 1999 г.
Это ошибка в документации или я что-то не так делаю?