Bagaimana cara membandingkan dua Tanggal tanpa porsi waktu?


203

Saya ingin memiliki metode compareTo yang mengabaikan porsi waktu java.util.Date. Saya kira ada sejumlah cara untuk menyelesaikan ini. Apa cara paling sederhana?

Jawaban:


212

Pembaruan: sementara Joda Time adalah rekomendasi yang baik pada saat itu, gunakan java.timeperpustakaan dari Java 8+ sebagai gantinya jika memungkinkan.


Preferensi saya adalah menggunakan Joda Time yang membuatnya sangat mudah:

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

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

return firstDate.compareTo(secondDate);

EDIT: Seperti yang tercantum dalam komentar, jika Anda menggunakannya DateTimeComparator.getDateOnlyInstance()lebih mudah :)

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

("Gunakan Joda Time" adalah dasar dari hampir semua pertanyaan SO yang menanyakan java.util.Dateatau java.util.Calendar. Ini adalah API yang sangat unggul. Jika Anda melakukan sesuatu yang signifikan dengan tanggal / waktu, Anda harus benar-benar menggunakannya jika Anda bisa.)

Jika Anda benar-benar terpaksa menggunakan API bawaan, Anda harus membuat instance Calendardengan tanggal yang sesuai dan menggunakan zona waktu yang sesuai. Anda kemudian dapat mengatur setiap bidang dalam setiap kalender dari jam, menit, detik dan milidetik ke 0, dan membandingkan waktu yang dihasilkan. Pasti jijik dibandingkan dengan solusi Joda :)

Zona waktu bagian penting: java.util.Dateyang selalu didasarkan pada UTC. Dalam kebanyakan kasus di mana saya tertarik pada suatu tanggal, itu adalah tanggal dalam zona waktu tertentu . Itu sendiri akan memaksa Anda untuk menggunakanCalendar atau Joda Time (kecuali jika Anda ingin memperhitungkan sendiri zona waktu, yang saya tidak rekomendasikan.)

Referensi cepat untuk pengembang android

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

Kode contoh (contoh)

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
Meskipun Jon mengatakan "Gunakan Joda Time" adalah dasar dari hampir semua pertanyaan SO yang bertanya tentang java.util.Date atau java.util.Calendar Saya selalu berpikir bahwa yang pertama adalah yang terbaik untuk memberikan jawaban yang konkret berdasarkan pertanyaan pengguna, pada Setidaknya untuk menunjukkan betapa sulitnya melakukan cara java. Dan setelah itu menyarankan menggunakan Joda ...
JuanZe

13
@ JiangZe: Itu membutuhkan kerja persis bagaimana melakukan sesuatu dengan benar di API yang menyakitkan, yang menurut definisi menyakitkan. Saya lebih suka menghabiskan waktu melakukan sesuatu yang lebih produktif :)
Jon Skeet

1
@ MetroidFan2002: LocalDate adalah pilihan yang lebih baik daripada DateMidnight, karena lebih ekspresif - dan tidak semua hari memiliki tengah malam ...
Jon Skeet

2
@dertoni: Tentu - di Brasil, ketika jam berjalan karena waktu musim panas, itu terjadi di awal hari ... jadi jam akan berbunyi 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 dll.
Jon Skeet

8
Bukankah lebih baik menggunakan DateTimeComparator.getDateOnlyInstance ()
Emil

125

Apache commons-lang hampir di mana-mana. Jadi bagaimana dengan ini?

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


2
Sedihnya tidak mentolerir tanggal nol
Pavel Niedoba

Guys, saat ini kami memiliki Java 8 stackoverflow.com/a/35411693/259237
André

Saya tidak merekomendasikan penggunaan sebelum cara ini karena jika objek Date pertama atau kedua disiarkan dari Timestamp dan memiliki mileseconds, dan yang lain adalah objek Date yang normal, Anda akan mengalami masalah karena, Date from datestamp store di bagian berbeda objek milidetik memberikan perbedaan bahkan ketika kedua tanggal sama.
Zini

Sayangnya, Apache bukan pada lebih dari 1,3 miliar perangkat Android, dan ini adalah perpustakaan yang sangat besar untuk hanya bergantung pada satu kasus penggunaan. Saya akan membutuhkan sesuatu yang lain: /
milosmns

58

Jika Anda benar-benar ingin menggunakan java.util.Date, Anda akan melakukan sesuatu seperti ini:

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();
  }
}

atau, menggunakan Kalender sebagai gantinya (lebih disukai, karena getYear () dan semacamnya sudah usang)

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
Pada metode kedua Anda lupa memperbarui beberapa referensi Anda, dari d1, d2 ke c1, c2.
stivlo

1
Setelah memperbaiki detail itu, kode Anda berfungsi dengan baik: Saya telah mengujinya secara luas. Saya telah menambahkan langkah untuk membuat Kalender dari tanggal, dan menggunakan kode Anda di proyek github saya yang baru dibuat org.obliquid.helpers , terima kasih.
stivlo

Manis, solusi yang bagus tanpa menggunakan perpustakaan eksternal.
4gus71n

1
Semua metode ini sudah usang. Bisakah ini memiliki dampak?
Pranav Mahajan

36

Preferensi saya adalah menggunakan insetad perpustakaan Jodajava.util.Date secara langsung, karena Joda membuat perbedaan antara tanggal dan waktu (lihat kelas YearMonthDay dan DateTime ).

Namun, jika Anda ingin menggunakan, java.util.Datesaya sarankan menulis metode utilitas; misalnya

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 tidak digunakan lagi untuk LocalDate. Juga, kode pada kalender akan memiliki masalah jika zona waktu tidak memiliki tengah malam 00:00 karena penghematan siang hari.
JodaStephen

1
Ini tidak berfungsi 100% dari waktu. Punya use case di mana saya melakukan itu dan calendar.getTime () masih akan mengembalikan waktu dengan jam yang ditetapkan sebagai tanggal parameter. Terbaik untuk menghapus bidang dan mengatur hanya tahun, bulan, dan hari.
Jonathan Drapeau

31

Adakah pendapat tentang alternatif ini?

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

1
Saya tidak berpikir itu akan berhasil, bahkan jika mengonversi ke Strings adalah ide yang bagus. The ==Operator tidak selalu kembali trueuntuk setara Strings (penggunaan equals()). Anda tentu saja tidak dapat menggunakan operator perbandingan lain yang Anda sebutkan.
harto

1
Ahh ya - batu delima saya merusak Jawa saya! Bisa mengkonversi string ke int meskipun untuk <,> dll
Robert Brown

Menggunakan Joda adalah cara yang bagus, tapi ini elegan!
Arne Evertsson

Ini tidak akan bekerja untuk semua orang, tetapi sangat sederhana dan ringan; alternatif yang baik ketika lib lain tidak tersedia.
Jacob Marble

Untuk mendapatkan urutan tanggal, Anda juga dapat menggunakan sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV

18

Jika Anda ingin membandingkan hanya dua bulan, hari, dan tahun dari dua tanggal, kode berikut berfungsi untuk saya:

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

Rob terima kasih.


13

Saya juga lebih suka Joda Time , tapi inilah alternatifnya:

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

EDIT

Saya menempatkan haly UTC di bawah jika Anda perlu membandingkan tanggal untuk zona waktu tertentu selain UTC. Jika Anda memang memiliki kebutuhan seperti itu, maka saya sangat menyarankan pergi untuk Joda.

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

Saya bilang saya lebih suka menggunakan Joda Time, tapi itu poin yang bagus. Saya hanya menggunakan taktik rendah seperti itu ketika saya tidak benar-benar tertarik pada TZ.
Daniel C. Sobral

Divisi dapat dihindari:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Vadzim

@Adzim Buatlah < oneDay.
Daniel C. Sobral

2
@Vadzim, yang hanya memeriksa jika tanggal kurang dari 1 hari terpisah. Tidak lantas berarti mereka berada di hari yang sama.
Arahant

@arahant, ya. ini mungkin cukup ketika kencan kedua selalu selaras tengah malam.
Vadzim

12

tl; dr

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

Hindari kelas tanggal waktu lama

Hindari kelas waktu lama warisan yang menyusahkan seperti Date&Calendar , sekarang digantikan oleh kelas java.time.

Menggunakan java.time

A java.util.Datemewakili momen pada timeline di UTC. Setara dengan java.time adalah Instant. Anda dapat mengonversi menggunakan metode baru yang ditambahkan ke kelas legacy.

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

Anda ingin membandingkan berdasarkan tanggal. Zona waktu sangat penting dalam menentukan tanggal. Untuk setiap momen tertentu, tanggalnya bervariasi di seluruh dunia berdasarkan zona. Sebagai contoh, beberapa menit setelah tengah malam di Paris, Perancis adalah hari yang baru ketika masih "kemarin" di Montréal Québec .

Tentukan nama zona waktu yang tepat dalam format continent/region, seperti America/Montreal, Africa/Casablanca, atau Pacific/Auckland. Jangan pernah menggunakan singkatan 3-4 huruf seperti ESTatau ISTkarena mereka bukan zona waktu yang sebenarnya, tidak terstandarisasi, dan bahkan tidak unik (!).

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

Terapkan ZoneIdke Instantuntuk mendapatkan ZonedDateTime.

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

The LocalDatekelas mewakili nilai tanggal-hanya tanpa waktu-of-hari dan tanpa zona waktu. Kita dapat mengekstrak LocalDatedari ZonedDateTime, secara efektif menghilangkan bagian waktu-hari.

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

Sekarang bandingkan, menggunakan metode seperti isEqual, isBefore, dan isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Lihat kode ini berjalan langsung di 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 [Amerika / Montreal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [Amerika / Montreal]

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

sameDate: false


Tentang java.time

The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date, Calendar, & SimpleDateFormat.

Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310 .

Di mana mendapatkan kelas java.time?

Proyek ThreeTen-Extra memperpanjang java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan masa depan ke java.time. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih .


7

Apache commons-utils yang telah disebutkan :

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

memberi Anda objek Tanggal yang hanya berisi tanggal, tanpa waktu, dan Anda dapat membandingkannya dengan Date.compareTo


6

Saya khawatir tidak ada metode membandingkan dua tanggal yang bisa disebut "mudah" atau "sederhana".

Saat membandingkan dua instance waktu dengan segala jenis presisi yang dikurangi (mis. Hanya membandingkan tanggal), Anda harus selalu memperhitungkan bagaimana zona waktu memengaruhi perbandingan.

Jika date1menentukan peristiwa yang terjadi di zona waktu +2 dan date2menentukan peristiwa yang terjadi di EST, misalnya, Anda harus berhati-hati untuk memahami implikasi perbandingan dengan benar.

Apakah tujuan Anda untuk mengetahui apakah kedua peristiwa tersebut terjadi pada tanggal kalender yang sama di zona waktu masing-masing? Atau apakah Anda perlu tahu apakah kedua tanggal tersebut jatuh ke tanggal kalender yang sama di zona waktu tertentu (UTC atau TZ lokal Anda, misalnya).

Setelah Anda mengetahui apa sebenarnya yang Anda coba bandingkan, itu hanya masalah mendapatkan triple tahun-bulan-tanggal di zona waktu yang tepat dan melakukan perbandingan.

Waktu Joda mungkin membuat operasi perbandingan yang sebenarnya terlihat jauh lebih bersih, tetapi semantik perbandingannya masih merupakan sesuatu yang Anda perlu pikirkan sendiri.



5

Jika Anda hanya ingin membandingkan dua tanggal tanpa waktu, maka kode berikut ini dapat membantu Anda:

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
}

Itu sama dengan jawaban Rob . Saya pikir solusi Jorn lebih baik karena tidak melibatkan perjalanan pulang-pergi ke string dan harus mencapai hal yang sama.
Rup

4

Berikut ini solusi dari blog ini: 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.");

yaitu Anda dapat melihat apakah perbedaan waktu dalam milidetik kurang dari panjang satu hari.


4
Sampel itu akan memeriksa apakah kedua tanggal berada dalam waktu 24 jam dari satu sama lain tetapi tidak harus jika mereka berdua pada tanggal yang sama, yaitu mungkin untuk rentang tengah malam. Lebih baik membagi dua set mili dengan MILLIS_IN_DAY dan membandingkan hasilnya, tetapi itu hanya akan tepat untuk UTC bukan waktu lokal.
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

Saya tidak tahu itu pemikiran baru atau yang lain, tetapi saya tunjukkan seperti yang saya lakukan

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

Cukup Periksa DAY_OF_YEAR dalam kombinasi dengan properti YEAR

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

EDIT:

Sekarang kita dapat menggunakan kekuatan fungsi ekstensi Kotlin

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
    }
}

Itu salah karena tanggal dengan tahun berbeda dapat memiliki hari yang sama tahun misalnya 2015-01-01 dan 2016-01-01
nelson eldoro

@nelsoneldoro terima kasih atas komentar Anda, lupa menambahkan cek untuk tahun ini, sekarang harusnya ok.
Simon K. Gerges

2

Di Java 8 Anda bisa menggunakan LocalDate yang sangat mirip dengan yang ada di 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();
}

Ini akan membantu Anda untuk membandingkan tanggal tanpa mempertimbangkan waktu.


1

Menggunakan getDateInstance dari SimpleDateFormat, kita dapat membandingkan hanya dua objek tanggal tanpa waktu. Jalankan kode di bawah ini.

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

Metode membandingkan sederhana lainnya berdasarkan jawaban di sini dan bimbingan mentor saya

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 : Menurut @Jonathan Drapeau, kode di atas gagal beberapa kasus (saya ingin melihat kasus-kasus itu) dan dia menyarankan yang berikut ini seperti yang saya mengerti:

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());
}

Harap perhatikan bahwa, kelas Date sudah usang karena tidak dapat menerima internasionalisasi. Kelas Kalender digunakan sebagai gantinya!


Ini tidak berfungsi 100% dari waktu. Punya use case di mana saya melakukan itu dan calendar.getTime () masih akan mengembalikan waktu dengan jam yang ditetapkan sebagai tanggal parameter. Terbaik untuk menghapus bidang dan mengatur hanya tahun, bulan, dan hari.
Jonathan Drapeau

@JonathanDrapeau, sepertinya bagi saya Anda mungkin mengalami konsekuensi karena tidak memilih zona waktu yang eksplisit. Tentunya lebih baik membuat zona waktu secara eksplisit daripada menggunakan getXxxmetode yang sudah usang Date.
Ole VV

1

Pertama, ketahuilah bahwa operasi ini tergantung pada zona waktu. Jadi pilih apakah Anda ingin melakukannya dalam UTC, di zona waktu komputer, di zona waktu favorit Anda atau di mana. Jika Anda belum yakin itu penting, lihat contoh saya di bagian bawah jawaban ini.

Karena pertanyaan Anda tidak begitu jelas tentang ini, saya berasumsi bahwa Anda memiliki kelas dengan bidang contoh yang mewakili titik waktu dan implementasi Comparable, dan Anda ingin urutan alami objek Anda berdasarkan tanggal, tetapi bukan waktu , dari bidang itu. Sebagai contoh:

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.timekelas

Saya telah mengambil kebebasan untuk mengubah jenis bidang instance Anda dari Datemenjadi Instant, kelas yang sesuai di Jawa 8. Saya berjanji untuk kembali ke perlakuan di Datebawah ini. Saya juga menambahkan konstanta zona waktu. Anda dapat mengaturnya ke ZoneOffset.UTCatau ZoneId.of("Europe/Stockholm")atau apa yang Anda anggap pantas (mengaturnya menjadi sebuah ZoneOffsetkarya karena ZoneOffsetmerupakan subkelas dariZoneId ).

Saya telah memilih untuk menunjukkan solusi menggunakan kelas Java 8. Anda meminta cara paling sederhana, bukan? :-) Inilah compareTometode yang Anda minta:

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

Jika Anda tidak pernah membutuhkan bagian waktu when, tentu saja lebih mudah untuk menyatakan whenaLocalDate dan melewatkan semua konversi. Maka kita tidak perlu khawatir tentang zona waktu lagi.

Sekarang anggaplah bahwa karena alasan tertentu Anda tidak dapat mendeklarasikan whenbidang InstantAnda atau Anda ingin menjadikannya kuno Date. Jika Anda masih dapat menggunakan Java 8, cukup konversikan ke Instant, lalu lakukan seperti sebelumnya:

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

Demikian pula untuk o.when.

Tidak ada Java 8?

Jika Anda tidak dapat menggunakan java 8, ada dua opsi:

  1. Selesaikan dengan menggunakan salah satu kelas lama, baik Calendaratau SimpleDateFormat.
  2. Gunakan backport kelas tanggal dan waktu Java 8 ke Java 6 dan 7, lalu lakukan seperti di atas. Saya menyertakan tautan di bagian bawah. Jangan gunakan JodaTime. JodaTime mungkin merupakan saran yang bagus ketika jawaban yang merekomendasikannya ditulis; tetapi JodaTime sekarang dalam mode pemeliharaan, sehingga backport ThreeTen adalah opsi yang lebih baik dan lebih futureproof.

Cara-cara kuno

Jawaban Adamski menunjukkan kepada Anda cara menghapus waktu bagian dari Datepenggunaan Calendarkelas. Saya sarankan Anda gunakan getInstance(TimeZone)untuk mendapatkan Calendarinstance untuk zona waktu yang Anda inginkan. Sebagai alternatif, Anda dapat menggunakan ide dari paruh kedua jawaban Jorn .

Menggunakan SimpleDateFormatbenar-benar cara penggunaan tidak langsung Calendarkarena SimpleDateFormatmengandung Calendarobjek. Namun, Anda mungkin merasa lebih sulit daripada menggunakan Calendarsecara langsung:

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));
}

Ini terinspirasi oleh jawaban Rob .

Ketergantungan zona waktu

Mengapa kita harus memilih zona waktu tertentu? Katakanlah kita ingin membandingkan dua kali dalam UTC 24 Maret 0:00 (tengah malam) dan 12:00 (siang). Jika Anda melakukannya di CET (katakanlah, Eropa / Paris), mereka jam 1 pagi dan 1 siang pada 24 Maret, yaitu, tanggal yang sama. Di New York (Eastern Daylight Time), mereka 20:00 pada 23 Maret dan 8:00 pada 24 Maret, yaitu, bukan tanggal yang sama. Jadi itu membuat perbedaan zona waktu yang Anda pilih. Jika Anda hanya mengandalkan default komputer, Anda mungkin akan terkejut ketika seseorang mencoba menjalankan kode Anda pada komputer di tempat lain di dunia global ini.

Tautan

Tautan ke ThreeTen Backport, backport kelas tanggal dan waktu Java 8 ke Java 6 dan 7: http://www.threeten.org/threetenbp/ .


0

Proposisi saya:

    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

Menggunakan Apache commons yang dapat Anda lakukan:

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   

ini adalah cara paling sederhana untuk menyelesaikan masalah ini.


0

Saya memecahkan masalah ini dengan membandingkan dengan cap waktu:

    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
    }

Saya menghindari menggunakan Joda Time karena pada Android menggunakan ruang yang sangat besar. Ukuran diperhitungkan. ;)


0

Solusi lain menggunakan Java 8 dan Instant, menggunakan metode truncatedTo

Mengembalikan salinan Instant ini terpotong ke unit yang ditentukan.

Contoh:

@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)
}

Terima kasih! Ada beberapa jawaban lain dengan pendekatan yang sama sudah - meskipun saya melihat sekarang Anda membandingkan objek Kalender secara langsung sedangkan mereka sebagian besar membandingkan getTime () s.
Rup

-2

Inilah yang bekerja untuk saya:

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
Perbandingan "normal" Anda bahkan tidak dapat dikompilasi di Jawa. Jika mau, itu akan membandingkan referensi objek, tetapi ini tidak diperbolehkan.
stivlo

Saya diedit untuk menambahkan penurunan harga, tetapi stivlo benar. Saya tidak tahu bagaimana kode itu "bekerja untuk Anda."
Pops

Ini mungkin js.
Andrey Luiz

-2

Bagaimana DateUtil.daysBetween(). Ini Java dan mengembalikan nomor (perbedaan hari).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.