Java GregorianCalendar и Календарь не соответствуют выходным, дням месяца в августе и сентябре 2010 года.

Я пытаюсь использовать календарь или григорианский календарь для итерации и создания сетки дат. Тем не менее, они оба считают, что в августе 2010 года 30 дней, а 2 и 3 сентября - выходные. Это как если бы в календаре был неправильный год, но я трижды проверил этот параметр. Вот некоторые выдержки.

startDate.set(2010, 8, 28);

SchedulerCalendar currentDate = (SchedulerCalendar) startDate.clone(); 
  for(int i = 0; i<daysDisplayed; i++){ 
   newDate = new TextView(this); 
   String dateString = currentDate.get(Calendar.MONTH)+"/"+currentDate.get(Calendar.DATE);
   //+"/"+currentDate.get(Calendar.YEAR);
   newDate.setText(dateString);
   newDate.setId(i+1);
   newDate.setWidth(blockWidth);
   newDate.setHeight(DATE_HEIGHT);
   dateBar.addView(newDate);
   currentDate.add(Calendar.DATE, 1);
  }


 private class SchedulerCalendar extends GregorianCalendar {
  @Override
  public void add(int field, int value) {
   super.add(field, value);
   if(this.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY) {
    if(value>=0) super.add(Calendar.DATE, 2);
    if(value<0) super.add(Calendar.DATE, -1);
   }
   if(this.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY) {
    if(value>=0) super.add(Calendar.DATE, 1);
    if(value<0) super.add(Calendar.DATE, -2);
   }
  }
 }

3 ответа

Я сильно подозреваю, что вы не принимаете во внимание тот факт, что месяц основан на 0. Итак, это:

startDate.set(2010, 8, 28);

устанавливает его на 28 сентября 2010 года. Вы не сказали, что ожидаете, но я подозреваю, что вы хотели август (который равен 7 месяцу в java.util.Calendar).

Я подозреваю, что это проблема, учитывая, что 2 и 3 октября - суббота и воскресенье.

Могу ли я настоятельно рекомендовать вам использовать Joda Time в качестве API даты и времени вместо java.util.{Date,Calendar}? Встроенные классы имеют много подобных ошибок.

Если вы хотите продолжать использовать java.util.CalendarВы, вероятно, должны также использовать Calendar.JANUARY, Calendar.FEBRUARYи т. д. константы.

Как уже упоминали другие, это может быть одна из распространенных ошибок "off by one", которые помогает делать дизайн библиотеки. Java API - это более или менее некоторая упаковка метки времени UNIX, в значительной степени вдохновленная некоторой C-библиотекой.

Вы должны по крайней мере использовать соответствующие перечисления для улучшения читабельности и не передавать объекты Date/Calendar другим методам, которые могут работать с некоторым неизменным представлением (String, Long, ...) данных в зависимости от варианта использования.

Если вы активно участвуете в Times, Dates и Calendars, вам следует рассмотреть возможность использования JodaTime и изучить JSR 310, API даты и времени, который может появиться в будущем выпуске Java.

Другие вопросы по тегам