Добавить год в календарь Java не работает
пожалуйста, просветите меня на этом:
Я просто пытаюсь добавить 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 ответов
у вас есть проблема с преобразованием 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 );
}
свой расчет 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();
вот простой пример того, что должно работать.
Calendar cal = new GregorianCalendar();
cal.setTime(new Date());
cal.add(Calendar.YEAR, yearsToAdd);
Date retDate = cal.getTime();
просто не забудьте использовать длинный, чтобы получить время в миллисекундах!
календарь ленив, поэтому он может не пересчитать все остальные поля, пока вы не попросите их. Это сбило меня с толку в отладчике раньше. Что произойдет, если вы System.out.println(ten_year_later);
?
я отметил в комментарии, что у вас есть неправильный расчет количества МС в год (по фигу инт/длинный вопрос).
поскольку у вас есть два календаря, каждый из которых может содержать год, почему бы вам не написать свой код так (не скомпилирован, поэтому может содержать опечатки):
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);
предполагая, что это то, что вы действительно хотите ...
количество миллисекунд в году находится далеко за пределами диапазона int, поэтому оба int бросают ten_year_later.getTimeInMillis() - expiration.getTimeInMillis()
и расчет 365 * 24 * 60 * 60 * 1000
будет возвращать неверные значения.
на ten_year_later
должно быть правильным. Нет необходимости вызывать computeFields, как писал Р. Бемроуз.