Не удается добавить одну неделю с помощью java.util.Calendar.add () - PullRequest
4 голосов
/ 02 декабря 2010

Я пытаюсь выполнить итерацию в моей Java-программе все недели между двумя датами (конечная дата - сегодня).Сначала я получаю начальную дату:

Calendar start = Calendar.getInstance();
start = data.getFirstDate(users, threads);

Пока все хорошо.Дата начала правильная, и я могу работать с ней.Теперь я повторюсь:

Calendar current = start;
while(current.before(Calendar.getInstance()) {
    // Do something
    current.add(Calendar.DATE, 7);
}

Ну, этот вид работ.Я начинаю в 2002/8/23, затем наступает 2002/8/30, затем в 2002/9/7 ... ДО 2002/11/30.Дата после этого 2003/0/6, которая не является ни правильной, ни даже действительной датой!

Что я делаю не так?Я пробовал current.add(Calendar.DATE, 7), current.add(Calendar.WEEK_OF_YEAR, 1), current.add(Calendar.DAY_OF_YEAR, 7) и два других способа.Использование current.roll(Calendar.DATE, 7) не работает, потому что я остаюсь в том же месяце.Использование GregorianCalendar также не имеет никакого эффекта.

Будем благодарны за любые предложения!

Спасибо, Джулиан

Ответы [ 4 ]

11 голосов
/ 02 декабря 2010

Поле месяца в Calendar API основано на 0, а не на 1.Так что 0 означает январь.Не спрашивай меня почему.

1 голос
/ 02 декабря 2010

Я думаю, что ваша интерпретация дат неверна.Поле месяца начинается с нуля, т. Е. ЯНВАРЬ равен 0. Итак, 2002/11/30 - 30 ДЕКАБРЯ.

1 голос
/ 02 декабря 2010

Если вы видите 0 как месяц, то это январь, поскольку месяцы основаны на индексе 0.0 - январь, а 11 - декабрь.

0 голосов
/ 22 января 2018

ТЛ; др

LocalDate.now().plusWeeks( 1 ).isBefore( stopDate )

java.time

Современный ответ использует java.time классов, а не Calendar.

LocalDate

Класс LocalDate представляет значение только для даты без времени суток и без часового пояса.

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, а еще «вчера» в Монреаль Квебек .

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, например EST или IST, так как они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
LocalDate weekLater = today.plusWeeks( 1 ) ;

Получите дату начала. Вы можете указать месяц с помощью числа со здравой нумерацией 1–12 для января-декабря, в отличие от сумасшедшей нумерации с нуля в унаследованном классе.

LocalDate start = LocalDate.of( 2017 , 2 , 23 ) ;  // Month is 1-12 for January-December.

Или, лучше, использовать предварительно определенные объекты перечисления Month, по одному на каждый месяц года.

LocalDate start = LocalDate.of( 2017 , Month.FEBRUARY , 23 ) ;

Отсюда зацикливание - это просто базовая Java, использующая методы сравнения объектов LocalDate: isBefore, isAfter и isEqual.

LocalDate ld = start ;
while( ld.isBefore( today ) ) {
    ld = ld.plusWeeks( 1 ) ;
    …
}

О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют старые классные устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , который теперь находится в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Где получить классы java.time?

  • Java SE 8 , Java SE 9 и выше
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функций java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Backport (упоминалось выше). См. Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

...