Как получить количество дней между двумя экземплярами календаря?

Я хочу найти разницу между двумя объектами Calendar в количестве дней, если есть изменение даты, например, если часы, отмеченные с 23: 59-0: 00, должны иметь разницу в день.

Я написал это

 public static int daysBetween(Calendar startDate, Calendar endDate) { return Math.abs(startDate.get(Calendar.DAY_OF_MONTH)-endDate.get(Calendar.DAY_OF_MONTH)); } 

Но он не работает, поскольку он только дает разницу между днями, если разница в месяце составляет его бесполезную.

Попробуйте следующий подход:

 public static long daysBetween(Calendar startDate, Calendar endDate) { long end = endDate.getTimeInMillis(); long start = startDate.getTimeInMillis(); return TimeUnit.MILLISECONDS.toDays(Math.abs(end - start)); } 

Эта функция вычисляет количество дней между двумя календарями как количество календарных дней месяца, которые находятся между ними, что и требовался OP. Расчет выполняется путем подсчета количества кратных 86 400 000 миллисекунд между календарями после того, как оба они были установлены до полуночи их соответствующих дней.

Например, моя функция будет вычислять разницу в 1 день между Календарем 1 января, 23:59 и 2 января, 12:01.

 import java.util.concurrent.TimeUnit; /** * Compute the number of calendar days between two Calendar objects. * The desired value is the number of days of the month between the * two Calendars, not the number of milliseconds' worth of days. * @param startCal The earlier calendar * @param endCal The later calendar * @return the number of calendar days of the month between startCal and endCal */ public static long calendarDaysBetween(Calendar startCal, Calendar endCal) { // Create copies so we don't update the original calendars. Calendar start = Calendar.getInstance(); start.setTimeZone(startCal.getTimeZone()); start.setTimeInMillis(startCal.getTimeInMillis()); Calendar end = Calendar.getInstance(); end.setTimeZone(endCal.getTimeZone()); end.setTimeInMillis(endCal.getTimeInMillis()); // Set the copies to be at midnight, but keep the day information. start.set(Calendar.HOUR_OF_DAY, 0); start.set(Calendar.MINUTE, 0); start.set(Calendar.SECOND, 0); start.set(Calendar.MILLISECOND, 0); end.set(Calendar.HOUR_OF_DAY, 0); end.set(Calendar.MINUTE, 0); end.set(Calendar.SECOND, 0); end.set(Calendar.MILLISECOND, 0); // At this point, each calendar is set to midnight on // their respective days. Now use TimeUnit.MILLISECONDS to // compute the number of full days between the two of them. return TimeUnit.MILLISECONDS.toDays( Math.abs(end.getTimeInMillis() - start.getTimeInMillis())); } 

ОБНОВЛЕНИЕ Проект Joda-Time , теперь в режиме обслуживания , советует перейти на классы java.time . См. Ответ Anees A для использования ChronoUnit и других классов java.time.

Joda времени

Старые классы java.util.Date/.Calendar, как известно, хлопотны, и их следует избегать.

Вместо этого используйте библиотеку Joda-Time . Если у вас нет технологии Java 8, в этом случае используйте ее преемника, встроенную фреймворк java.time (а не в Android по состоянию на 2015 год).

Поскольку вас интересуют только «дни», определяемые как даты (а не 24-часовые периоды), давайте сосредоточимся на датах. Joda-Time предлагает классу LocalDate значение даты только без времени и времени.

Не имея часового пояса, обратите внимание, что часовой пояс имеет решающее значение для определения даты, такой как «сегодня». Новый день восходит раньше на восток, чем на запад. Таким образом, дата не одинакова во всем мире в один момент, дата зависит от вашего часового пояса.

 DateTimeZone zone = DateTimeZone.forID ( "America/Montreal" ); LocalDate today = LocalDate.now ( zone ); 

Давайте подсчитаем количество дней до следующей недели, и, конечно, должно быть семь.

 LocalDate weekLater = today.plusWeeks ( 1 ); int elapsed = Days.daysBetween ( today , weekLater ).getDays (); 

getDays на конце извлекает простой номер int из объекта Days возвращаемого daysBetween .

Дамп для консоли.

 System.out.println ( "today: " + today + " to weekLater: " + weekLater + " is days: " + days ); 

Сегодня: 2015-12-22 to weekLater: 2015-12-29 – это дни: 7

У вас есть объекты Calendar. Нам нужно преобразовать их в объекты Joda-Time. Внутренне объекты Calendar имеют long целое число, отслеживающее количество миллисекунд с момента первого момента 1970 года в UTC . Мы можем извлечь это число и передать его Joda-Time. Нам также необходимо назначить желаемый часовой пояс, по которому мы намерены определить дату.

 long startMillis = myStartCalendar.getTimeInMillis(); DateTime startDateTime = new DateTime( startMillis , zone ); long stopMillis = myStopCalendar.getTimeInMillis(); DateTime stopDateTime = new DateTime( stopMillis , zone ); 

Преобразование из объектов DateTime в LocalDate.

 LocalDate start = startDateTime.toLocalDate(); LocalDate stop = stopDateTime.toLocalDate(); 

Теперь сделаем тот же самый прошедший расчет, который мы видели ранее.

 int elapsed = Days.daysBetween ( start , stop ).getDays (); 

В Java 8 и более поздних версиях мы могли бы просто использовать классы java.time .

 hoursBetween = ChronoUnit.HOURS.between(calendarObj.toInstant(), calendarObj.toInstant()); daysBetween = ChronoUnit.DAYS.between(calendarObj.toInstant(), calendarObj.toInstant()); 

У меня аналогичный (не точный) подход, приведенный выше, https://stackoverflow.com/a/31800947/3845798 .

И написали тестовые примеры вокруг api, для меня это провалилось, если я прошел 8 марта 2017 года – в качестве даты начала и 8 апреля 2017 года в качестве даты окончания.

Есть несколько дат, где вы увидите разницу на 1 день. Поэтому я сделал некоторые небольшие изменения в моем api, и мой текущий api теперь выглядит примерно так

  public long getDays(long currentTime, long endDateTime) { Calendar endDateCalendar; Calendar currentDayCalendar; //expiration day endDateCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST")); endDateCalendar.setTimeInMillis(endDateTime); endDateCalendar.set(Calendar.MILLISECOND, 0); endDateCalendar.set(Calendar.MINUTE, 0); endDateCalendar.set(Calendar.HOUR, 0); endDateCalendar.set(Calendar.HOUR_OF_DAY, 0); //current day currentDayCalendar = Calendar.getInstance(TimeZone.getTimeZone("EST")); currentDayCalendar.setTimeInMillis(currentTime); currentDayCalendar.set(Calendar.MILLISECOND, 0); currentDayCalendar.set(Calendar.MINUTE, 0); currentDayCalendar.set(Calendar.HOUR,0); currentDayCalendar.set(Calendar.HOUR_OF_DAY, 0); long remainingDays = (long)Math.ceil((float) (endDateCalendar.getTimeInMillis() - currentDayCalendar.getTimeInMillis()) / (24 * 60 * 60 * 1000)); return remainingDays;} 

Я не использую TimeUnit.MILLISECONDS.toDays, которые вызывали у меня некоторые проблемы.

Календарь day1 = Calendar.getInstance ();

Календарь day2 = Calendar.getInstance ();

Int diff = day1.get (Calendar.DAY_OF_YEAR) – day2.get (Calendar.DAY_OF_YEAR);

Intereting Posts
Преобразование входного потока в растровое изображение Как скрыть клавиатуру, когда пользователь нажимает на текстовое поле в webview android Обезьяна сделала мое приложение мяуком Android программно меняет ширину панели ящика навигации Как добавить изображение в панель инструментов Как оживить переходы активности при просмотре списков / сеток / ресайклеров? Как выбрать данные между двумя диапазонами дат в android SQLite Поддерживается ли Intent.ACTION_CALL в Google Glass GDK? Как включить Android Download Manager Android: как обнаружить изменения в MediaStore при подключении через MTP График, видимый вне оси X и Y Отсутствие анимации при удалении элементов в RecyclerView Каков правильный способ расширения EditText, чтобы придать ему дополнительные функции «по умолчанию» Настройка SeekBar – как правильно позиционировать пользовательский «большой» образ? Получите время с помощью андроида