Количество дней между двумя датами в Joda-Time
Как я могу найти разницу в днях между двумя Joda ВремениDateTime экземпляров?
С "разницей в днях" я имею в виду, если начало в понедельник и конец во вторник я ожидаю возвращаемое значение 1 независимо от часа/минуты/секунды даты начала и окончания.
Days.daysBetween(start, end).getDays() дает мне 0, если начало вечером и конец утром.
у меня также есть такая же проблема с другими полями даты, поэтому я надеялся, что будет общий способ "игнорировать" поля меньшей значимости.
6 ответов:
досадно, что ответ withTimeAtStartOfDay неверен, но только иногда. Вы хотите:
Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()оказывается, что "полночь / начало дня" иногда означает 1am (переход на летнее время происходит таким образом в некоторых местах), в какие дни.daysBetween не справляется должным образом.
// 5am on the 20th to 1pm on the 21st, October 2013, Brazil DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo"); DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL); DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL); System.out.println(daysBetween(start.withTimeAtStartOfDay(), end.withTimeAtStartOfDay()).getDays()); // prints 0 System.out.println(daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()); // prints 1переход через a
LocalDateобходит весь вопрос.
DaysклассС помощью
DaysклассwithTimeAtStartOfDayметод работы:Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()
можно использовать
LocalDate:Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()
tl; dr
java.time.temporal.ChronoUnit.DAYS.between( earlier.truncatedTo( ChronoUnit.DAYS ) , later.truncatedTo( ChronoUnit.DAYS ) )...и...
java.time.temporal.ChronoUnit.HOURS.between( earlier.truncatedTo( ChronoUnit.HOURS ) , later.truncatedTo( ChronoUnit.HOURS ) )java.время
к вашему сведению,Joda Времени сейчас режим обслуживания, с командой, консультирующей миграцию в java.время классы.
эквивалент Joda времени
DateTimeиZonedDateTime.ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; ZonedDateTime now = ZonedDateTime.now( z ) ;видимо, вы хотите считать дни по датам, то есть вы хотите игнорировать время суток. Например, начиная с минуты до полуночи и заканчивая минуту после полуночи должно привести к одному дню. За такое поведение, извлеките
LocalDateиз своегоZonedDateTime. ЭлементLocalDateкласс представляет значение только для даты без времени суток и без часового пояса.LocalDate localDateStart = zdtStart.toLocalDate() ; LocalDate localDateStop = zdtStop.toLocalDate() ;использовать
ChronoUnitперечисление для расчета прошедших дней или других единицах.long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;усечь
что касается вас, спрашивая о более общем способе сделать это подсчет, где вы находитесь если вас интересует Дельта часов как час часов, а не полные часы как промежутки времени в шестьдесят минут, используйте
truncatedToметод.вот ваш пример с 14: 45 до 15:12 в тот же день.
ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z ); ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z ); long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );1
для подсчета дней по датам, усечь до
ChronoUnit.DAYS. Вот пример, переходящий в полночь с пяти минут до пяти минут после, За истекшие дни1.ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 23 , 55 , 0 , 0 , z ); ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 18 , 00 , 05 , 0 , 0 , z ); long days = ChronoUnit.DAYS.between( start.truncatedTo( ChronoUnit.DAYS ) , stop.truncatedTo( ChronoUnit.DAYS ) );1
о java.время
The java.время фреймворк встроен в Java 8 и более поздние версии. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как
java.util.Date,Calendar,&SimpleDateFormat.The Joda-Time, теперь ремонт режим, советует миграцию в java.время классы.
чтобы узнать больше, смотрите Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация является JSR 310.
вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте - драйвера соответствуют JDBC 4.2 или позже. Нет необходимости в струнах, нет необходимости ибо
java.sql.*классы.где получить java.время занятий?
- Java SE 8, Java SE 9, Java SE 10, и позже
- встроенный.
- часть стандартного Java API с комплектной реализацией.
- Java 9 добавляет некоторые незначительные функции и зафиксировать.
- Java SE 6 и Java SE 7
- большая часть java.функциональность time обратно портирована на Java 6 & 7 в ThreeTen-Backport.
- Android
- более поздние версии Android bundle реализации java.время занятия.
- для более ранних Android ( ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). Смотрите как использовать ThreeTenABP....
The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к Ява.время. Вы можете найти некоторые полезные классы, такие как
Interval,YearWeek,YearQuarterи больше.The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как
Interval,YearWeek,YearQuarterи больше.
принятый ответ строит два
LocalDateобъекты, которые довольно дороги, если Вы читаете много данных. Я использую это:public static int getDaysBetween(DateTime earlier, DateTime later) { return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis()); }по телефону
getMillis()вы используете уже существующие переменные.MILLISECONDS.toDays()затем использует простой арифметический расчет, не создает какого-либо объекта.
public static int getDifferenceIndays(long timestamp1, long timestamp2) { final int SECONDS = 60; final int MINUTES = 60; final int HOURS = 24; final int MILLIES = 1000; long temp; if (timestamp1 < timestamp2) { temp = timestamp1; timestamp1 = timestamp2; timestamp2 = temp; } Calendar startDate = Calendar.getInstance(TimeZone.getDefault()); Calendar endDate = Calendar.getInstance(TimeZone.getDefault()); endDate.setTimeInMillis(timestamp1); startDate.setTimeInMillis(timestamp2); if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) { int day1 = endDate.get(Calendar.DAY_OF_MONTH); int day2 = startDate.get(Calendar.DAY_OF_MONTH); if (day1 == day2) { return 0; } else { return 1; } } int diffDays = 0; startDate.add(Calendar.DAY_OF_MONTH, diffDays); while (startDate.before(endDate)) { startDate.add(Calendar.DAY_OF_MONTH, 1); diffDays++; } return diffDays; }
Comments