Подтвердить что ты не робот

Сравните только временную часть двух дат, игнорируя часть даты

Какой хороший метод, учитывая два объекта Date, сравнить разницу между их временной частью, полностью игнорируя Year, Month и Day?

Это совершенно противоположно этому вопросу.

ОБНОВЛЕНИЕ: Здесь последний код для справки в будущем:

private long differenceBetween(Date currentTime, Date timeToRun)
{
    Calendar currentCal = Calendar.getInstance();
    currentCal.setTime(currentTime);

    Calendar runCal = Calendar.getInstance();
    runCal.setTime(timeToRun);
    runCal.set(Calendar.DAY_OF_MONTH, currentCal.get(Calendar.DAY_OF_MONTH));
    runCal.set(Calendar.MONTH, currentCal.get(Calendar.MONTH));
    runCal.set(Calendar.YEAR, currentCal.get(Calendar.YEAR));

    return currentCal.getTimeInMillis() - runCal.getTimeInMillis();
}
4b9b3361

Ответ 1

ТЛ; др

Duration                                  // Span of time, with resolution of nanoseconds.
.between(                                 // Calculate elapsed time.
    LocalTime.now(                        // Get current time-of-day…
        ZoneId.of( "Pacific/Auckland" )   // … as seen in a particular time zone.
    )                                     // Returns a 'LocalTime' object.
    ,
    myJavaUtilDate                        // Avoid terrible legacy date-time classes such as 'java.util.Date'.
    .toInstant()                          // Convert from 'java.util.Date' to 'java.time.Instant', both representing a moment in UTC.
    .atZone(                              // Adjust from UTC to a particular time zone. Same moment, same point on the timeline, different wall-clock time.
        ZoneId.of( "Pacific/Auckland" )   // Specify time zone by proper naming in 'Continent/Region' format, never 2-4 letter pseudo-zones such as 'PST', 'CEST', 'CST', 'IST', etc.
    )                                     // Returns a 'ZonedDateTime' object.
    .toLocalTime()                        // Extract the time-of-day without the date and without a time zone.
)                                         // Returns a 'Duration' object.
.toMillis()                               // Calculate entire span-of-time in milliseconds. Beware of data-loss as 'Instant' uses a finer resolution the milliseconds, and may carry microseconds or nanoseconds.

Я предлагаю обойти типобезопасный и не требующий пояснений объект Duration, а не просто целое число миллисекунд.

java.time

Современный подход использует классы java.time, которые вытеснили ужасные унаследованные классы, такие как Date, Calendar, SimpleDateFormat.

Table of all date-time types in Java, both modern and legacy

Преобразуйте ваш java.util.Date (мгновение в UTC) в Instant. Используйте новые методы преобразования, добавленные к старым классам.

Instant instant = myJavaUtilDate.toInstant() ;

Это представляет момент в UTC. Для определения даты и времени суток требуется часовой пояс. В любой момент дата и время варьируются по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция - это новый день, который все еще "вчера" в Монреале-Квебеке.

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться. Лучше указать в качестве аргумента желаемый/ожидаемый часовой пояс.

Укажите правильное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4-буквенное сокращение, такое как EST или IST, поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

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

ZoneId z = ZoneId.systemDefault() ;  // Get JVMs current default time zone.

Назначьте ZoneId Instant для создания объекта ZonedDateTime.

ZonedDateTime zdt = instant.atZone( z ) ;

Извлеките часть времени суток без даты и без часового пояса.

LocalTime lt = zdt.toLocalTime() ;

сравнения. Подсчитайте прошедшее время с помощью Duration.

Duration d = Duration.between( ltStart , ltStop ) ;

Имейте в виду, что это несправедливое сравнение. Дни не всегда продолжительностью 24 часа, и не все значения времени суток действительны для всех дней во всех зонах. Например, в Соединенных Штатах во время перехода на летнее время может не быть часа 2 часа вообще. Таким образом, с 1 до 4 часов утра может быть 3 часа в одну дату, но только 2 часа в другую дату.


О java.time

Среда java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time, который теперь находится в режиме обслуживания, рекомендует выполнить переход на классы java.time.

Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите в Кару множество примеров и объяснений. Спецификация: JSR 310.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в классах java.sql.*.

Где взять классы java.time?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с встроенной реализацией ,
    • Java 9 добавляет некоторые мелкие функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport.
  • Android

Table of which java.time library to use with which version of Java or Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и еще more.

Ответ 2

Если вы хотите сравнить базовые двоичные (long int) значения дат, вы можете сделать это:

public int compareTimes(Date d1, Date d2)
{
    int     t1;
    int     t2;

    t1 = (int) (d1.getTime() % (24*60*60*1000L));
    t2 = (int) (d2.getTime() % (24*60*60*1000L));
    return (t1 - t2);
}

Добавление 1

Этот метод имеет преимущество скорости, потому что он использует базовое значение long для объектов Date напрямую, вместо преобразования между тиками и компонентами календаря (что довольно дорого и медленно). Это также намного проще, чем возиться с объектами Calendar.

Добавление 2

Приведенный выше код возвращает разницу во времени как int, которая будет правильной для любой пары раз, поскольку она полностью игнорирует части года/месяца/дня дат, а разница между любыми двумя временами не равна более 86 400 000 мс (= 1000 мсек/сек и раз 60 сек/мин и раз, 60 мин/час и раз, 24 ч/день).

Ответ 3

Вы можете использовать время Joda DateTimeComparator.getTimeOnlyInstance() для компаратора, который будет сравнивать две даты Джоды, основанные только на времени.

Например:

DateTimeComparator comparator = DateTimeComparator.getTimeOnlyInstance();
comparator.compare(date1, date2);

См. http://joda-time.sourceforge.net/api-release/org/joda/time/DateTimeComparator.html#getTimeOnlyInstance()

Ответ 4

Взгляните на класс Calendar. Он поддерживает извлечение часов, минут и секунд из заданных Date.

Calendar calendar = Calendar.getInstance();
calendar.setTime(yourDateObject);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);

Ответ 5

Если вы не можете использовать JODA,

создать 2 объекта календаря, установить год, месяц и день на 0.

Сравните их....

Ответ 6

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

DateFormat df = new SimpleDateFormat("HHmmssSZ");
df.format(date1).equals(df.format(date2));

Ответ 7

Не знаю, насколько хорош практический или эффективный этот, но я написал простую функцию, используя объект Date, который служит моим целям. Он возвращает true или false, это первое значение даты больше второго. Входы d1 && d2 - объекты Date.

function CompareTimes(d1, d2) {
             if (d1.getHours() < d2.getHours()) {
                 return false;
             }
             if (d1.getHours() > d2.getHours()) {
                 return true;

             } else {
                 return (d1.getMinutes() > d2.getMinutes());
             }
};

Ответ 8

если вы просто хотите сравнить временную часть дат, тогда это даст вам правильный результат -

public long compareTimes(Date d1, Date d2)
    {
        long     t1;
        long     t2;
        t1 = d1.getHours()*60*60+d1.getMinutes()*60+d1.getSeconds();
        t2 = d2.getHours()*60*60+d2.getMinutes()*60+d2.getSeconds();
        long diff = t1-t2;
        System.out.println("t1 - "+t1+", t2 - "+t2+",  diff - "+diff);

        return diff;
    }