Як порівняти дві дати без часового проміжку?


202

Я хотів би мати метод CompareTo, який ігнорує частину часу java.util.Date. Я думаю, існує ряд способів вирішити це. Який найпростіший спосіб?

Відповіді:


212

Оновлення: поки Joda Time був чудовою рекомендацією в той час, використовуйте java.timeбібліотеку з Java 8+ замість того, де це можливо.


Я вважаю за краще використовувати Joda Time, що робить це надзвичайно просто:

DateTime first = ...;
DateTime second = ...;

LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();

return firstDate.compareTo(secondDate);

EDIT: Як зазначалося в коментарях, якщо ви використовуєте, DateTimeComparator.getDateOnlyInstance()це ще простіше :)

// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);

("Використовуйте Joda Time" - це основа майже всіх запитань щодо запитань, про які задаються java.util.Dateабо java.util.Calendar. Це досконалий API). Якщо ви робите щось важливе з датами / часом, ви дійсно повинні використовувати його, якщо можливо. "

Якщо ви абсолютно змушені використовувати вбудований API, вам слід створити екземпляр Calendarіз відповідною датою та використовувати відповідний часовий пояс. Потім можна встановити кожне поле в кожному календарі з години, хвилини, секунди та мілісекунди на 0 і порівняти отриманий час. Безумовно, прискіпливо порівняно з рішенням Joda :)

Часовий пояс частина важлива: java.util.Dateце завжди заснований на UTC. У більшості випадків, коли мене цікавила дата, це дата в певному часовому поясі . Це самостійно змусить вас використовувати Calendarабо Joda Time (якщо ви самі не хочете рахувати часовий пояс, що я не рекомендую.)

Коротка довідка для розробників Android

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}

Приклад коду (приклад)

DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();

Date myDateOne = ...;
Date myDateTwo = ...;

int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);

if(retVal == 0)
   //both dates are equal
else if(retVal < 0)
   //myDateOne is before myDateTwo
else if(retVal > 0)
   //myDateOne is after myDateTwo

28
Хоча, як каже Джон, "Використовуйте час Joda" - це основа майже всіх питань, які задають питання щодо java.util.Date або java.util.Calendar. Я завжди думаю, що по-перше, найкраще дати конкретну відповідь на основі запитання користувача, на принаймні, щоб показати, як важко зробити java спосіб. А після цього пропоную використовувати Joda ...
JuanZe

13
@JuanZe: Це вимагає розробити саме те, як зробити щось правильно в болісному API, що за визначенням болісно. Я вважаю за краще провести цей час, роблячи щось більш продуктивне :)
Джон Скіт

1
@ MetroidFan2002: LocalDate - кращий варіант, ніж DateMidnight, оскільки він більш виразний - і не всі дні мають опівночі ...
Джон Скіт,

2
@dertoni: Безумовно - у Бразилії, коли годинник рухається вперед через літній час, це відбувається на початку дня ... так що годинник буде читати 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 тощо
Джон Скіт

8
Чи не було б краще використовувати DateTimeComparator.getDateOnlyInstance ()
Еміль

125

Apache commons-lang майже всюдисущий. Так що з цим?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}


2
На жаль, не терпить нульових дат
Павло Нієдоба

Хлопці, зараз у нас є Java 8 stackoverflow.com/a/35411693/259237
Андре,

Я не рекомендую використовувати цей спосіб раніше, тому що якщо перший або другий об'єкт Date був скинутий з Timestamp і має секунди секунди, а інший є звичайним об'єктом Date, у вас виникнуть проблеми, оскільки, Date from datestamp зберігайте в іншій частині об'єкта мілісекунди дають відмінності, навіть коли обидві дати рівні.
Зіні

На жаль, Apache не на більш ніж 1,3 мільярда пристроїв Android, і це величезна бібліотека, від якої залежатиме лише один випадок використання. Мені потрібно щось інше: /
milosmns

58

Якщо ви дійсно хочете використовувати java.util.Date, ви зробите щось подібне:

public class TimeIgnoringComparator implements Comparator<Date> {
  public int compare(Date d1, Date d2) {
    if (d1.getYear() != d2.getYear()) 
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth()) 
        return d1.getMonth() - d2.getMonth();
    return d1.getDate() - d2.getDate();
  }
}

або, використовуючи натомість Календар (бажано, оскільки getYear () і такі застарілі)

public class TimeIgnoringComparator implements Comparator<Calendar> {
  public int compare(Calendar c1, Calendar c2) {
    if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) 
        return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
    if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) 
        return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
    return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
  }
}

1
У другому методі ви забули оновити деякі свої посилання, від d1, d2 до c1, c2.
stivlo

1
Після виправлення цієї деталі ваш код працює добре: я широко його перевірив. Я додав крок для створення календаря з дат і використав ваш код у моєму новоствореному проекті github org.obliquid.helpers , дякую.
stivlo

Солодке, приємне рішення без використання жодної зовнішньої бібліотеки.
4gus71n

1
Усі ці методи застарілі. Чи може це мати якийсь вплив?
Пранав Махаджан

36

Моє перевага була б використовувати Joda бібліотеки insetad з java.util.Dateбезпосередньо, як Joda робить відмінність між датою і часом (див YearMonthDay і DateTime класи).

Однак, якщо ви хочете скористатися, java.util.Dateя б запропонував написати корисний метод; напр

public static Date setTimeToMidnight(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

1
Joda-Time YearMonthDay застарілий на користь LocalDate. Також код у календарі матиме проблеми, якщо в часовому поясі немає півночі 00:00 через економію денного світла.
JodaStephen

1
Це не працює 100% часу. Якби випадок використання, коли я це зробив, і Calendar.getTime () все одно поверне час із годинами, встановленими як дата параметра. Найкраще очистити поля та встановити лише рік, місяць та добу.
Джонатан Драпо

31

Якісь думки щодо цієї альтернативи?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

1
Я не думаю, що це спрацювало, навіть якби перехід до Strings було гарною ідеєю. ==Оператор не обов'язково повертати trueрівноцінні рядки (використання equals()). Ви, звичайно, також не можете використовувати інші згадані вами оператори порівняння.
harto

1
Ага так - мій рубін руйнує мою Яву! Не вдалося перетворити рядки в ints, хоч для <,> тощо.
Роберт Браун

Використання Joda - це здоровий спосіб, але це елегантно!
Арне Евертссон

Це не для всіх, але це дуже просто і легко; хороша альтернатива, коли інших губ немає.
Яків Мармур

Для отримання порядку замовлення дат ви також можете скористатися sdf.format(date1).compareTo(sdf.format(date2));.
Оле ВВ

18

Якщо ви хочете порівняти лише місяць, день і рік двох дат, наступний код працює для мене:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

Дякую Роб.


13

Я теж віддаю перевагу Joda Time , але ось альтернатива:

long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2

EDIT

Я ставлю нижче значення UTC, якщо вам потрібно порівняти дати для певного часового поясу, крім UTC. Якщо у вас є така потреба, то я дійсно раджу поїхати на Джоду.

long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2

Я сказав, що краще використовувати Joda Time, але це хороший момент. Я використовую такі низькі тактики лише тоді, коли мене не дуже цікавить ТЗ.
Даніель К. Собрал

Дивізії можна уникнути:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Вадим

@Vadzim Зроби < oneDay.
Даніель К. Собрал

2
@Vadzim, це перевіряє лише, якщо дати менше, ніж один день. Не обов'язково означає, що вони в один і той же день.
арахант

@arahant, так. цього може бути достатньо, коли друге побачення завжди вирівнюється опівночі.
Вадим

12

тл; д-р

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

Уникайте застарілих занять з датами

Уникайте старих класових дат, таких як Date&Calendar давно переходять у , тепер витіснених класами java.time.

Використання java.time

A java.util.Dateявляє собою момент на часовій шкалі в UTC. Еквівалент у java.time є Instant. Ви можете конвертувати за допомогою нових методів, доданих до старого класу.

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

Ви хочете порівняти за датою. Часовий пояс має вирішальне значення при визначенні дати. Для будь-якого моменту дата змінюється по всьому світу за зоною. Наприклад, через кілька хвилин після півночі у Парижі Франція - це новий день, а ще «вчора» в Монреалі Квебек .

Вкажіть правильний час ім'я зони в форматі continent/region, наприклад America/Montreal, Africa/Casablancaабо Pacific/Auckland. Ніколи не використовуйте абревіатуру з 3–4 літер, наприклад, ESTабо ISTяк вони не є справжніми часовими поясами, не стандартизовані та навіть не унікальні (!).

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

Застосуйте ZoneIdдо, Instantщоб отримати ZonedDateTime.

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

LocalDateКлас являє собою дату тільки значення без часу доби і без часового поясу. Ми можемо витягти LocalDateз ZonedDateTime, ефективно усуваючи порцію часу.

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

Тепер порівняйте, використовуючи методи , такі як isEqual, isBefore, і isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Дивіться цей код, який працює на сайті IdeOne.com .

instant1: 2017-03-25T04: 13: 10.971Z | instant2: 2017-03-24T22: 13: 10.972Z

zdt1: 2017-03-25T00: 13: 10.971-04: 00 [Америка / Монреаль] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [Америка / Монреаль]

localDate1: 2017-03-25 | localDate2: 2017-03-24

той самийДата: помилково


Про java.time

Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date, Calendar, і SimpleDateFormat.

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

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

Де отримати класи java.time?

  • Java SE 8 та SE 9 та новіші версії
    • Вбудований.
    • Частина стандартного Java API з пакетною реалізацією.
    • Java 9 додає деякі незначні функції та виправлення.
  • Java SE 6 і SE 7
    • Значна частина функцій java.time підтримується на Java 6 і 7 у ThreeTen-Backport .
  • Android

Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є доказом можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval, YearWeek, YearQuarter, і більш .


7

Вже згадані apache commons-utils :

org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)

дає вам об'єкт Date, що містить лише дату, без часу, і ви можете порівняти його Date.compareTo


6

Боюся, не існує методу порівняння двох дат, який можна було б назвати "легким" або "простим".

Порівнюючи два часові екземпляри з будь-якою зниженою точністю (наприклад, просто порівнюючи дати), ви завжди повинні враховувати, як часовий пояс впливає на порівняння.

Наприклад, якщо date1вказується подія, що сталася в часовому поясі +2, і date2вказується подія, що сталася в EST, наприклад, ви повинні подбати про те, щоб правильно зрозуміти наслідки порівняння.

Чи є ваша мета з’ясувати, чи відбулися дві події в одну і ту ж дату календаря у власних часових поясах? Або вам потрібно знати, чи впадають ці дати в одну і ту ж дату календаря у певному часовому поясі (наприклад, UTC або ваш місцевий TZ).

Як тільки ви зрозумієте, що насправді ви намагаєтеся порівняти, це лише питання про те, щоб потрійну дату року-місяця у відповідному часовому поясі провести і порівняння.

Час Joda може зробити фактичну операцію порівняння набагато чистішою, але семантика порівняння все-таки є те, що вам потрібно розібратися самостійно.



5

Якщо ви просто хочете порівняти лише дві дати без часу, то наступний код може допомогти вам:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
   add your logic
}

Це те саме , що відповідь Роб . Я думаю , що рішення Джорна є кращим, оскільки воно не передбачає зворотного переходу до струн і повинно здійснити те саме.
Rup

4

Ось рішення з цього блогу: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html

long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays  + " days.");

тобто ви можете бачити, чи різниця часу в мілісекундах менша за тривалість одного дня.


4
Цей зразок перевірить, чи знаходяться два дати протягом 24 годин один від одного, але необов'язково, якщо вони обоє в одну і ту ж дату, тобто можливо продовжити півночі. Краще було б замість цього розділити обидва набори мілісів на MILLIS_IN_DAY і порівняти результат, але це буде точно лише за UTC, а не за місцевим часом.
Rup

4

`

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

`


3

Я не знаю, що це по-новому думаю, але я показую вам, як я це зробив

SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date);    //First seted in String 
String second_date = "30/11/2020";          //Second date you can set hear in String

String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);

3

Просто перевірте DAY_OF_YEAR у поєднанні з YEAR властивістю

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

Редагувати:

Тепер ми можемо використовувати потужність функцій розширення Котліна

fun Calendar.isSameDay(second: Calendar): Boolean {

    return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}

fun Calendar.compareDatesOnly(other: Calendar): Int {

    return when {
        isSameDay(other) -> 0
        before(other) -> -1
        else -> 1
    }
}

Це неправильно, оскільки дати з різними роками можуть мати однаковий день року, наприклад 2015-01-01 та 2016-01-01.
nelson eldoro

@nelsoneldoro дякую за ваш коментар, забув додати чек за рік, тепер має бути гаразд.
Саймон К. Гергес

2

У Java 8 ви можете використовувати LocalDate, який дуже схожий на той, який від Joda Time.


2
public Date saveDateWithoutTime(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

Це допоможе вам порівняти дати, не враховуючи часу.


1

За допомогою getDateInstance SimpleDateFormat ми можемо порівняти лише два об'єкти дати без часу. Виконайте наведений нижче код.

public static void main(String[] args) {        
        Date date1  = new Date();
        Date date2  = new Date();
        DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
        String dateDtr1 = dfg.format(date1);
        String dateDtr2 = dfg.format(date2);
        System.out.println(dateDtr1+" : "+dateDtr2);
        System.out.println(dateDtr1.equals(dateDtr2));  

    }


1

Ще один простий метод порівняння, заснований на відповідях тут та моїх рекомендаціях наставника

public static int compare(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c1.set(Calendar.MILLISECOND, 0);
    c1.set(Calendar.SECOND, 0);
    c1.set(Calendar.MINUTE, 0);
    c1.set(Calendar.HOUR_OF_DAY, 0);
    c2.setTime(d2);
    c2.set(Calendar.MILLISECOND, 0);
    c2.set(Calendar.SECOND, 0);
    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR_OF_DAY, 0);
    return c1.getTime().compareTo(c2.getTime());
  }

EDIT : За словами @Jonathan Drapeau, наведений вище код не в деяких випадках (я хотів би побачити ці випадки, будь ласка), і він запропонував таке, наскільки я розумію:

public static int compare2(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.clear();
    c2.clear();
    c1.set(Calendar.YEAR, d1.getYear());
    c1.set(Calendar.MONTH, d1.getMonth());
    c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
    c2.set(Calendar.YEAR, d2.getYear());
    c2.set(Calendar.MONTH, d2.getMonth());
    c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
    return c1.getTime().compareTo(c2.getTime());
}

Зауважте, що клас Дата застарілий, оскільки він не підлягає інтернаціоналізації. Замість цього використовується клас Календар!


Це не працює 100% часу. Якби випадок використання, коли я це зробив, і Calendar.getTime () все одно поверне час із годинами, встановленими як дата параметра. Найкраще очистити поля та встановити лише рік, місяць та добу.
Джонатан Драпо

@JonathanDrapeau, мені здається, що ти, можливо, зіткнувся з наслідком того, що не вибрав явний часовий пояс. Безумовно, краще зробити часовий пояс явним, ніж використовувати застарілі getXxxметоди Date.
Оле ВВ

1

По-перше, пам’ятайте, що ця операція залежить від часового поясу. Тому виберіть, чи хочете ви це робити в UTC, у часовому поясі комп’ютера, у власному улюбленому часовому поясі чи де. Якщо ви ще не впевнені, що це має значення, дивіться мій приклад внизу цієї відповіді.

Оскільки ваше запитання щодо цього не зовсім зрозуміло, я припускаю, що у вас є клас із полем екземпляра, яке представляє момент часу та реалізацію Comparable, і ви хочете, щоб природне упорядкування ваших об'єктів було за датою, але не часом , цього поля. Наприклад:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

Java 8 java.timeкласів

Я взяв свободу змінити тип вашого поля екземпляра з Dateна Instant, відповідний клас на Java 8. Я обіцяю повернутися до обробки Dateнижче. Я також додав константу часового поясу. Ви можете встановити його ZoneOffset.UTCабо ZoneId.of("Europe/Stockholm")або те , що ви знайдете відповідним (встановити його до ZoneOffsetроботи , так як ZoneOffsetце підклас ZoneId).

Я вирішив показати рішення за допомогою класів Java 8. Ви просили найпростіший спосіб, правда? :-) Ось compareToметод, який ви просили:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

Якщо вам ніколи не потрібна частина часу when, звичайно, простіше оголосити whenа LocalDateта пропустити всі перетворення. Тоді нам більше не потрібно турбуватися про часовий пояс.

Тепер припустимо, що ви чомусь не можете оголосити своє whenполе Instantабо хочете зберегти його по-старому Date. Якщо ви все-таки можете використовувати Java 8, просто перетворіть її на Instant, зробіть так, як і раніше:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Аналогічно для o.when.

Немає Java 8?

Якщо ви не можете використовувати java 8, є два варіанти:

  1. Розв’яжіть це, використовуючи один із старих класів, Calendarабо SimpleDateFormat.
  2. Використовуйте підпорядкування класів дати та часу Java 8 для Java 6 та 7, тоді просто виконайте так, як зазначено вище. Я включаю посилання внизу. Не використовуйте JodaTime. JodaTime, мабуть, була гарною пропозицією, коли відповіді, які рекомендували його, були написані; але JodaTime зараз перебуває в режимі технічного обслуговування, тому підтримка ThreeTen - це кращий і більш надійний варіант.

Старомодні способи

Відповідь Адамського показує вам, як позбавити час від Dateвикористання Calendarкласу. Я пропоную вам скористатися getInstance(TimeZone)для отримання Calendarекземпляра для потрібного часового поясу. В якості альтернативи ви можете використовувати ідею з другої половини відповіді Джорна .

Використання SimpleDateFormat- це дійсно непрямий спосіб використання, Calendarоскільки SimpleDateFormatмістить Calendarоб'єкт. Однак вам може бути менш клопітно, ніж Calendarбезпосередньо використовувати :

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

Це надихнуло відповідь Роба .

Залежність від часового поясу

Чому нам потрібно вибрати конкретний часовий пояс? Скажімо, ми хочемо порівняти два рази, що в UTC 24 березня 0:00 (опівночі) та 12:00 (полудень). Якщо ви робите це в CET (скажімо, Європа / Париж), то вони беруть 1 годину ранку та 13 вечора 24 березня, тобто ту саму дату. У Нью-Йорку (східний літній час) вони 20:00 23 березня та 8:00 24 березня, тобто не одна і та ж дата. Тож має значення, який часовий пояс ви виберете. Якщо ви просто покладаєтесь на замовчування комп’ютера, вас можуть чекати сюрпризи, коли хтось намагається запустити ваш код на комп’ютері в іншому місці цього глобалізованого світу.

Посилання

Посилання на ThreeTen Backport, резервний список класів дати та часу Java 8 до Java 6 та 7: http://www.threeten.org/threetenbp/ .


0

Моя пропозиція:

    Calendar cal = Calendar.getInstance();
    cal.set(1999,10,01);   // nov 1st, 1999
    cal.set(Calendar.AM_PM,Calendar.AM);
    cal.set(Calendar.HOUR,0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    // date column in the Thought table is of type sql date
    Thought thought = thoughtDao.getThought(date, language);

    Assert.assertEquals(cal.getTime(), thought.getDate());

0

За допомогою Apache commons ви можете:

import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)

0
public static Date getZeroTimeDate(Date fecha) {
    Date res = fecha;
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( fecha );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    res = calendar.getTime();

    return res;
}

Date currentDate = getZeroTimeDate(new Date());// get current date   

це найпростіший спосіб вирішити цю проблему.


0

Я вирішив це, порівнюючи часову позначку:

    Calendar last = Calendar.getInstance();

    last.setTimeInMillis(firstTimeInMillis);

    Calendar current = Calendar.getInstance();

    if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
        //not the same day
    }

Я уникаю використовувати Joda Time, оскільки на Android використовується величезний простір. Розмір має значення. ;)


0

Ще одне рішення, що використовує Java 8 та Instant, - це використання методу усіченогоTo

Повертає копію цього Миттєвого усіченого до вказаного блоку.

Приклад:

@Test
public void dateTruncate() throws InterruptedException {
    Instant now = Instant.now();
    Thread.sleep(1000*5);
    Instant later = Instant.now();
    assertThat(now, not(equalTo(later)));
    assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}

0
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);

// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);

if (oneDayCal.compareTo(currentCal) == 0) {
    // Same day (excluding time)
}

Дякую! Хоча є ще кілька відповідей з тим самим підходом - хоча я бачу, ти зараз порівнюєш об'єкти Календаря, тоді як вони значною мірою порівнюють getTime () s.
Rup

-2

Це для мене працювало:

var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString()); 
//do a normal compare
if(Date1 > Date2){ //do something }

2
Ваше "звичайне" порівняння навіть не збирається на Java. Якби це було, воно порівнювало б посилання на об'єкт, але це заборонено.
stivlo

Я редагував, щоб додати Markdown, але stivlo - це правильно. Я поняття не маю, як цей код "працював на вас".
Попс

Це, мабуть, js.
Андрій Луїз

-2

Як щодо DateUtil.daysBetween(). Це Java, і вона повертає число (різниця в днях).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.