Добавить год в Java календарь не работает - PullRequest
7 голосов
/ 07 октября 2010

Пожалуйста, напишите мне об этом:

Я просто пытаюсь добавить 10 лет к текущей дате, а затем вычесть из нее дату окончания срока действия, чтобы получить количество лет:

public int getMaxYears() {
  int max = 0;
  Calendar ten_year_later = Calendar.getInstance();
  ten_year_later.setTime(new Date());
  ten_year_later.add(Calendar.YEAR, 10);
  Calendar expiration = Calendar.getInstance();
  expiration.setTime(expiration_date);
  max = (int) (ten_year_later.getTimeInMillis() - expiration.getTimeInMillis())/(365 * 24 * 60 * 60 * 1000);
  return max;
}

Когда я отлаживаю это, календарь всегда остается в текущем году.

Кто-нибудь?

Ответы [ 6 ]

11 голосов
/ 07 октября 2010

У вас проблема с конвертацией int / long: 365 * 24 * 60 * 60 * 1000 Который оценивается в 31536000000 и, следовательно, превышает Integer.MAX_VALUE 2147483647 Это работает:

public static void main(String[] args) {
          Calendar ten_year_later = Calendar.getInstance();
          System.out.println( ten_year_later.getTime() );
          ten_year_later.setTime(new Date()); 
          ten_year_later.add(Calendar.YEAR, 10);
          System.out.println( ten_year_later.getTime() );
          Calendar expiration = Calendar.getInstance(); 
          expiration.setTime(expiration.getTime()); 
          long max = (ten_year_later.getTimeInMillis() - expiration.getTimeInMillis())/(365 * 24 * 60 * 60 * 1000L); 
          System.out.println( "max " + max );
        } 
5 голосов
/ 07 октября 2010

Ваш расчет max неверен. int не может содержать год в миллис.

Скорее замените его на

max = ten_year_later.get(Calendar.YEAR) - expiration.get(Calendar.YEAR);

Или лучше, используйте JodaTime :

DateTime tenYearsLater = new DateTime().plusYears(10);
DateTime expiration = new DateTime(expiration_date.getTime());
Period period = new Period(expiration, tenYearsLater);
return period.getYears();
4 голосов
/ 07 октября 2010

Вот простой пример того, что должно работать.

Calendar cal = new GregorianCalendar();
cal.setTime(new Date());
cal.add(Calendar.YEAR, yearsToAdd);
Date retDate = cal.getTime();

Просто не забудьте использовать long, чтобы получить время в миллисекундах!

1 голос
/ 07 октября 2010

Я заметил в комментарии, что у вас неверный расчет количества миллис в году (не говоря уже о выпуске int / long).

Поскольку у вас есть два календаря, каждый из которых может хранить год, почему бы вам не написать свой код следующим образом (не скомпилированный, поэтому может содержать опечатки):

Calendar cal1 = Calendar.newInstance();   // this will use current time
cal1.add(Calendar.YEAR, 10);
Calendar cal2 = Calendar.newInstance();
cal2.setDate(expiration);
return cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);

Предполагая, что вы действительно хотите ...

1 голос
/ 07 октября 2010

Календарь ленив, поэтому он может не пересчитать все остальные поля, пока вы не попросите их.Это отбросило меня в отладчике раньше.Что произойдет, если вы System.out.println(ten_year_later);?

0 голосов
/ 07 октября 2010

Число миллисекунд в году находится за пределами диапазона целого числа, поэтому как целое число ten_year_later.getTimeInMillis() - expiration.getTimeInMillis(), так и вычисление 365 * 24 * 60 * 60 * 1000 приведут к неправильным значениям.

Значение ten_year_later должно быть правильным. Нет необходимости вызывать computeFields, как писал Р. Бемроуз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...