Разница в днях между двумя датами в Java?
Мне нужно найти количество дней между двумя датами: один из отчетов, а другой - текущая дата. Мой фрагмент:
int age=calculateDifference(agingDate, today);
Здесь calculateDifference
это частный метод, agingDate
а today
это Date
объекты, просто для вашего пояснения. Я просмотрел две статьи с форума Java, тема 1 / Тема 2.
Это отлично работает в автономной программе, хотя, когда я включаю это в свою логику для чтения из отчета, я получаю необычную разницу в значениях.
Почему это происходит и как я могу это исправить?
Редактировать :
Я получаю большее количество дней по сравнению с фактическим количеством дней.
public static int calculateDifference(Date a, Date b)
{
int tempDifference = 0;
int difference = 0;
Calendar earlier = Calendar.getInstance();
Calendar later = Calendar.getInstance();
if (a.compareTo(b) < 0)
{
earlier.setTime(a);
later.setTime(b);
}
else
{
earlier.setTime(b);
later.setTime(a);
}
while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
{
tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
{
tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
return difference;
}
Примечание :
К сожалению, ни один из ответов не помог мне решить проблему. Я решил эту проблему с помощью библиотеки Joda-time.
Переведено автоматически
Ответ 1
Я бы посоветовал вам использовать отличную библиотеку Joda Time вместо ущербной java.util .Date и friends . Вы могли бы просто написать
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;
Date past = new Date(110, 5, 20); // June 20th, 2010
Date today = new Date(110, 6, 24); // July 24th
int days = Days.daysBetween(new DateTime(past), new DateTime(today)).getDays(); // => 34
Ответ 2
Возможно, я опоздал присоединиться к игре, но какого черта, а? :)
Вы думаете, это проблема с потоками? Например, как вы используете выходные данные этого метода? или
Можем ли мы изменить ваш код, чтобы сделать что-то такое простое, как:
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(<your earlier date>);
calendar2.set(<your current date>);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("\nThe Date Different Example");
System.out.println("Time in milliseconds: " + diff
+ " milliseconds.");
System.out.println("Time in seconds: " + diffSeconds
+ " seconds.");
System.out.println("Time in minutes: " + diffMinutes
+ " minutes.");
System.out.println("Time in hours: " + diffHours
+ " hours.");
System.out.println("Time in days: " + diffDays
+ " days.");
}
Ответ 3
Diff / (24 * и т.д.) Не учитывает часовой пояс, поэтому, если в вашем часовом поясе по умолчанию указано летнее время, это может привести к сбою расчета.
Эта ссылка имеет небольшую приятную реализацию.
Вот источник приведенной выше ссылки на случай, если ссылка отключится:
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
//assert: startDate must be before endDate
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
и
/** Using Calendar - THE CORRECT (& Faster) WAY**/
public static long daysBetween(final Calendar startDate, final Calendar endDate)
{
//assert: startDate must be before endDate
int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
long endInstant = endDate.getTimeInMillis();
int presumedDays =
(int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);
Calendar cursor = (Calendar) startDate.clone();
cursor.add(Calendar.DAY_OF_YEAR, presumedDays);
long instant = cursor.getTimeInMillis();
if (instant == endInstant)
return presumedDays;
final int step = instant < endInstant ? 1 : -1;
do {
cursor.add(Calendar.DAY_OF_MONTH, step);
presumedDays += step;
} while (cursor.getTimeInMillis() != endInstant);
return presumedDays;
}
Ответ 4
java.time
В Java 8 и более поздних версиях используйте java.time framework (Учебное пособие).
Duration
Класс Duration
представляет промежуток времени в виде количества секунд плюс доли секунды. Он может считать дни, часы, минуты и секунды.
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println(duration.toDays());
ChronoUnit
Если все, что вам нужно, это количество дней, в качестве альтернативы вы можете использовать ChronoUnit
enum . Обратите внимание, что методы вычисления возвращают long
, а не int
.
long days = ChronoUnit.DAYS.between( then, now );