Количество дней между двумя датами в Joda-Time



Как я могу найти разницу в днях между двумя Joda ВремениDateTime экземпляров?
С "разницей в днях" я имею в виду, если начало в понедельник и конец во вторник я ожидаю возвращаемое значение 1 независимо от часа/минуты/секунды даты начала и окончания.



Days.daysBetween(start, end).getDays() дает мне 0, если начало вечером и конец утром.



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

619   6  

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

    Ничего не найдено.