Расчет разницы в датах на Яве - PullRequest
17 голосов
/ 17 января 2009

Мне показалось забавным, что Java (или библиотека java.util) не имеет встроенной функции для вычисления разницы в датах. Я хочу вычесть одну дату из другой, чтобы получить прошедшее время между ними. Каков наилучший способ сделать это?

Я знаю, что простой способ - взять разницу времени в миллисекундах и затем преобразовать ее в дни. Однако я хотел знать, работает ли это во всех случаях (с переходом на летнее время и т. Д.).

Ответы [ 7 ]

8 голосов
/ 17 января 2009

Java не пропускает много, если вы посмотрите на открытый исходный код: попробуйте Joda-Time .

6 голосов
/ 17 января 2009

Я знаю, простой способ взять разница времени в миллисекундах и затем преобразовать это в дни. Тем не менее, я хотел знать, если это работает во всех случаях (при дневном свете сохранение и т. д.).

Если ваши времена получены из дат UTC или они представляют собой разницу между двумя вызовами System.getCurrentTimeMillis (), измеренными в одной и той же системе, вы получите действительное количество миллисекунд в качестве разницы, независимо от проблем с часовым поясом. , (именно поэтому все должны использовать UTC в качестве формата хранения - гораздо проще перейти с UTC-> по местному времени; если вы попытаетесь пойти другим путем, то вам нужно сохранить местный часовой пояс вместе с местным временем - или попытайся сделать вывод, гак!)

Что касается того, чтобы превратить это в число дней, вы должны просто иметь возможность разделить на 86400000 ... с оговоркой, что есть случайный скачок секунды через год или около того.

4 голосов
/ 03 июня 2014

Используйте Joda-Time или новый пакет java.time в Java 8.

Обе структуры используют подход Half-Open , где начало включительно , а окончание эксклюзив . Иногда обозначается как [). Как правило, это лучший подход для определения отрезков времени.

java.time

Среда java.time, встроенная в Java 8 и более поздние версии, имеет класс Period для представления промежутка времени в виде количества лет, количества месяцев и количества дней. Но этот класс ограничен целыми днями, без представления часов, минут и секунд.

Обратите внимание, что мы указываем часовой пояс, важный для определения даты. Например, новый день наступает раньше в Париже , чем в Монреале .

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate now = LocalDate.now( zoneId );
LocalDate then = LocalDate.of( 2001, 1, 1 );
Period period = Period.between( then, now );

Тогда: 2001-01-01. Сейчас: 2015-09-07. Период: P14Y8M6D. Дни: 5362

Для целых дней, тогда Летнее время (DST) не имеет значения.

Если вы хотите подсчитать общее количество дней, используйте перечисление ChronoUnit, которое включает некоторые методы расчета. Обратите внимание, что вычисления возвращают длинную.

long days = ChronoUnit.DAYS.between( then, now );  // "5362" seen above.

Я спросил о том, чтобы сделать полный период в java.time, включая часы, минуты, секунды. Невозможно для Java 8. Удивительный обходной путь с использованием связанных библиотек был предложен от Meno Hochschild : используйте класс Duration, найденный в пакет javax.xml.datatype .

Joda-Time

Вот пример кода в Joda-Time 2.3.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime start = new DateTime( 2014, 1, 2, 3, 4, 5, timeZone );
DateTime stop = new DateTime( 2014, 5, 2, 3, 4, 5, timeZone );
Period period = new Period( start, stop );

При вызове toString вы получите строковое представление в форме, определенной стандартом ISO 8601 , PnYnMnDTnHnMnS.

2 голосов
/ 13 февраля 2011

С библиотекой date4j :

int numDaysBetween = oneDate.numDaysFrom(anotherDate);
1 голос
/ 04 декабря 2013

Существует простой способ реализовать это. Мы можем использовать метод Calendar.add с циклом. Например, как показано ниже,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

Date beginDate = dateFormat.parse("2013-11-29");
Date endDate = dateFormat.parse("2013-12-4");

Calendar beginCalendar = Calendar.getInstance();
beginCalendar.setTime(beginDate);

Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);

Минус дней между beginDate и endDate и кодом, как показано ниже,

int minusDays = 0;
while (true) {
  minusDays++;

  // Day increasing by 1
  beginCalendar.add(Calendar.DAY_OF_MONTH, 1);

  if (dateFormat.format(beginCalendar.getTime()).
            equals(dateFormat.format(endCalendar).getTime())) {
    break;
  }
}
System.out.println("The substractation between two days is " + (minusDays + 1));

Веселись! @. @

0 голосов
/ 20 января 2009

Я не согласен с утверждением, что в Java нет механизма для вычисления разницы между датами.

Java была разработана для глобального использования. Он был разработан таким образом, чтобы не было понятия даты, а есть только понятие «время в миллисекундах». Любое толкование такого универсального времени, как время и дата в определенном месте в соответствии с конкретной конвенцией, является просто проекцией или представлением.

Класс календаря используется для преобразования такого рода абсолютного времени в даты. Вы также можете добавить или вычесть компоненты даты, если вам действительно нужно. Единственный способ обеспечить разницу между двумя компонентами - это сгенерированный календарь и конкретный. Таким образом, вы можете утверждать, что стандартная библиотека не содержит достаточно умного григорианского календаря, и я согласен, что он оставляет желать лучшего.

При этом существует множество реализаций такого рода функциональности, я вижу, что другие предоставили примеры.

0 голосов
/ 20 января 2009

Реализация дат в Java плохая. Если вы находите Joda-Time слишком сложным, попробуйте мой небольшой вклад в открытый исходный код: http://calendardate.sourceforge.net/javadoc/index.html

...