Cum se compară datele în Java? [duplicat] (Programare, Java, Data, Comparație)

Ant a intrebat.

Cum se compară datele între ele în Java?

Exemplu:

data1 este 22-02-2010
data2 este 07-04-2010 astăzi
data3 este 25-12-2010

date3 este întotdeauna mai mare decât date1 și date2 este întotdeauna astăzi. Cum pot verifica dacă data de astăzi este cuprinsă între data1 și data3?

11 răspunsuri
Bart Kiers

Data are înainte de și după și poate fi comparate între ele după cum urmează:

if(todayDate.after(historyDate) && todayDate.before(futureDate)) {
    // In between
}

Pentru o comparație globală:

if(!historyDate.after(todayDate) && !futureDate.before(todayDate)) {
    /* historyDate <= todayDate <= futureDate */ 
}

De asemenea, puteți da Joda-Time o încercare, dar rețineți că:

Joda-Time este de facto bibliotecă standard de date și ore pentru Java înainte de Java SE 8. Utilizatorii sunt acum rugați să migreze la java.time (JSR-310).

Sunt disponibile back-porturi pentru Java 6 și 7, precum și pentru Android.

Comentarii

  • Este aceasta inclusiv, sau exclusiv pentru granițe? –  > Por Daniel Hári.
  • @DanielHári nu, nu este inclusiv. puteți folosi soluția sugerată în primul comentariu , sau puteți folosi CompareTo()>=0 . –  > Por Mifmif.
  • Normalul este de obicei „left inclusive, right exclusive”, de aceea cred că ar trebui specificat exact acest lucru. Cu marginile „left inclusive, right exclusive”, puteți specifica cu ușurință fe: un interval de o lună: [2016/04/01, 2016/05/01], motiv pentru care acesta este normalul și este utilizat ca implicit în multe cazuri de utilizare. –  > Por Daniel Hári.
  • Pentru informarea dvs., vechile clase de date-timp problematice, cum ar fi java.util.Date sunt acum legacy, , înlocuite de clasele java.time construite în Java 8 & Java 9. A se vedea Tutorial de Oracle. –  > Por Basil Bourque.
  • @BasilBourque da, corect, de aici și observațiile despre Joda și java.time pentru Java 8, care este acum versiunea standard (spre deosebire de momentul în care am scris acest răspuns). Simțiți-vă liber să editați acest răspuns și să adăugați cod de exemplu mai recent, desigur! 😉 (EDIT: ah, văd că tu însuți ai furnizat deja un răspuns cu exemplele respective) – –  > Por Bart Kiers.
Chandra Sekar

Utilizați compareTo:

date1.compareTo(date2);

Comentarii

  • Funcționează perfect cu Date, Byte, Long, Integer… –  > Por Giancarlo Ventura Granados.
  • Uneori nu funcționează. Am declanșat de mai multe ori folosind într-o metodă principală pentru a verifica egalitatea. De cele mai multe ori spune egal, dar nu de fiecare dată. –  > Por Syed.
  • @Syed Poți să ne împărtășești codul tău? –  > Por Chandra Sekar.
  • @ChandraSekarS, încercați să executați codul ca metodă principală luând aceleași date și să vedeți rezultatul. Uneori, dă 0 și alteori 1. –  > Por Syed.
Sunil Kumar Sahoo

În continuare sunt cele mai comune modalități de comparare dates (preferința mea este Abordarea 1):

Abordarea 1: Utilizarea Date.before(), , Date.after() și Date.equals()

if (date1.after(date2)) {
    System.out.println("Date1 is after Date2");
}

if (date1.before(date2)) {
    System.out.println("Date1 is before Date2");
}

if (date1.equals(date2)) {
    System.out.println("Date1 is equal Date2");
}

Abordarea 2: Date.compareTo()

if (date1.compareTo(date2) > 0) {
    System.out.println("Date1 is after Date2");
} else if (date1.compareTo(date2) < 0) {
    System.out.println("Date1 is before Date2");
} else {
    System.out.println("Date1 is equal to Date2");
}

Abordarea 3: Calender.before(), , Calender.after() și Calender.equals()

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);

if (cal1.after(cal2)) {
    System.out.println("Date1 is after Date2");
}

if (cal1.before(cal2)) {
    System.out.println("Date1 is before Date2");
}

if (cal1.equals(cal2)) {
    System.out.println("Date1 is equal Date2");
}

Comentarii

Basil Bourque

tl;dr

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
Boolean isBetween = 
    ( ! today.isBefore( localDate1 ) )  // “not-before” is short for “is-equal-to or later-than”.
    &&
    today.isBefore( localDate3 ) ; 

Sau, mai bine, dacă adăugați ThreeTen-Extra la proiectul dumneavoastră.

LocalDateRange.of(
    LocalDate.of( … ) ,
    LocalDate.of( … )
).contains(
    LocalDate.now()
)

Abordare semi-deschisă, în care începutul este inclusiv în timp ce sfârșitul este exclusivă.

Alegere greșită a formatului

Apropo, aceasta este o alegere proastă a formatului pentru o reprezentare text a unei date sau a unei valori de dată și oră. Ori de câte ori este posibil, folosiți formatul standard ISO 8601 standard ISO 860101. Formatele ISO 8601 sunt lipsite de ambiguitate, ușor de înțeles în toate culturile umane și ușor de analizat de către o mașină.

Pentru o valoare care conține doar o dată, formatul standard este AAAA-MM-DD. Observați că acest format are avantajul de a fi cronologic atunci când este sortat alfabetic.

LocalDate

LocalDate reprezintă o valoare exclusivă de dată, fără ora zilei și fără fus orar.

Un fus orar este esențial în determinarea unei date. Pentru un moment dat, data variază în funcție de fusul orar pe glob. De exemplu, la câteva minute după miezul nopții în Paris, Franța este o nouă zi, în timp ce în Franța este încă „ieri”. Montréal Québec.

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

DateTimeFormatter

Deoarece șirurile de intrare au un format non-standard, trebuie să definim un model de formatare care să corespundă.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );

Folosiți acest model pentru a analiza șirurile de intrare.

LocalDate start = LocalDate.parse( "22-02-2010" , f );
LocalDate stop = LocalDate.parse( "25-12-2010" , f );

În lucrul cu data-timp, de obicei, cel mai bine este să definiți un interval de timp prin abordarea Half-Open (jumătate de deschidere), unde începutul este inclusiv în timp ce sfârșitul este exclusivă. Așadar, dorim să știm dacă ziua de astăzi este aceeași sau mai târzie decât începutul și, de asemenea, înainte de sfârșit. Un mod mai scurt de a spune „este la fel sau mai târziu decât începutul” este „nu înainte de început”.

Boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ;

Vedeți răspunsul dat de gstackoverflow care arată lista de metode de comparație pe care le puteți apela.


Despre java.time

java.time este încorporat în Java 8 și în versiunile ulterioare. Aceste clase înlocuiesc vechea și problematică moștenire clase de date-timp, cum ar fi java.util.Date, , Calendar, , , & SimpleDateFormat.

Pentru a afla mai multe, consultați pagina Tutorial Oracle. Și căutați în Stack Overflow pentru multe exemple și explicații. Specificația este JSR 310.

Joda-Time în prezent în modul de întreținere, , recomandă migrarea la java.time clase.

Puteți schimba java.time direct cu baza de date. Folosiți un driver JDBC compatibil cu JDBC 4.2 sau o versiune ulterioară. Nu este nevoie de șiruri de caractere, nu este nevoie de java.sql.* clase. Hibernate 5 & suport JPA 2.2 java.time.

De unde se pot obține clasele java.time?

  • Java SE 8, , Java SE 9, , Java SE 10, , Java SE 11, , și ulterior – Parte a API Java standard cu o implementare la pachet.
    • Java 9 a adus câteva caracteristici și corecturi minore.
  • Java SE 6 și Java SE 7
    • Cele mai multe dintre java.time este readusă în Java 6 & 7 în ThreeTen-Backport.
  • Android
    • Versiunile ulterioare ale Android (26+) includ implementări ale funcției java.time clase.
    • Pentru Android mai vechi (<26), un proces cunoscut sub numele de API desugaring aduce un subset al java.time care nu a fost încorporată inițial în Android.
      • În cazul în care desugaring-ul nu oferă ceea ce aveți nevoie, aplicația ThreeTenABP adaptează ThreeTen-Backport (menționat mai sus) la Android. A se vedea Cum se utilizează ThreeTenABP….

Site-ul ThreeTen-Extra extinde java.time cu clase suplimentare. Acest proiect este un teren de testare pentru posibilele viitoare adăugiri la java.time. Puteți găsi aici câteva clase utile, cum ar fi Interval, , YearWeek, , YearQuarter, , și mai multe.


UPDATE: Această secțiune „Joda-Time” de mai jos este lăsată intactă ca istorie. The Joda-Time acum în modul de întreținere, , recomandă migrarea către java.time clase.

Joda-Time

Celelalte răspunsuri sunt corecte în ceea ce privește clasele incluse java.util.Date și java.util.Calendar. Dar aceste clase sunt cunoscute ca fiind problematice. Așadar, iată un exemplu de cod care utilizează clasa Joda-Time 2.3.

Dacă doriți cu adevărat o dată fără nicio porțiune de timp și fără fus orar, atunci folosiți clasa LocalDate din Joda-Time. Clasa respectivă oferă metode de comparație, inclusiv compareTo (utilizată cu Java Comparators), isBefore, , isAfter, , și isEqual.

Intrări…

String string1 = "22-02-2010";
String string2 = "07-04-2010";
String string3 = "25-12-2010";

Definiți un formator care să descrie șirurile de intrare…

DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );

Utilizați formatorul pentru a analiza șirurile de caractere în obiecte LocalDate…

LocalDate localDate1 = formatter.parseLocalDate( string1 );
LocalDate localDate2 = formatter.parseLocalDate( string2 );
LocalDate localDate3 = formatter.parseLocalDate( string3 );

boolean is1After2 = localDate1.isAfter( localDate2 );
boolean is2Before3 = localDate2.isBefore( localDate3 );

Aruncă în consolă…

System.out.println( "Dates: " + localDate1 + " " + localDate2 + " " + localDate3 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );

Când se execută…

Dates: 2010-02-22 2010-04-07 2010-12-25
is1After2 false
is2Before3 true

Pentru a vedea dacă al doilea este între celelalte două (exclusiv, adică nu este egal cu niciunul dintre punctele finale)…

boolean is2Between1And3 = ( ( localDate2.isAfter( localDate1 ) ) && ( localDate2.isBefore( localDate3 ) ) );

Lucrul cu intervale de timp

Dacă lucrați cu intervale de timp, vă sugerez să explorați în Joda-Time clasele: Duration, , Interval, și Perioada. Metode cum ar fi overlap și contains facilitează comparațiile.

Pentru reprezentări de text, consultați standardul ISO 8601:

  • durata
    Format: PnYnMnDTnHnMnS
    Exemplu: P3Y6M4DT12H30M5S
    (Înseamnă „trei ani, șase luni, patru zile, douăsprezece ore, treizeci de minute și cinci secunde”)
  • interval
    Format: start/end
    Example: 2007-03-01T13:00:00Z/2008-05-11T15:30:00Z

Clasele Joda-Time pot lucra cu șiruri de caractere în aceste două formate, atât ca intrare (parsare), cât și ca ieșire (generare de șiruri de caractere).

Joda-Time efectuează comparații utilizând metoda Half-Open abordare în care începutul intervalului este inclusiv în timp ce finalul este exclusivă. Această abordare este una înțeleaptă pentru gestionarea intervalelor de timp. Căutați pe StackOverflow pentru mai multe informații.

Comentarii

  • Acest lucru ar trebui să fie în partea de sus a tuturor celorlalte răspunsuri –  > Por Hemil.
sam

Comparați cele două date:

  Date today = new Date();                   
  Date myDate = new Date(today.getYear(),today.getMonth()-1,today.getDay());
  System.out.println("My Date is"+myDate);    
  System.out.println("Today Date is"+today);
  if (today.compareTo(myDate)<0)
      System.out.println("Today Date is Lesser than my Date");
  else if (today.compareTo(myDate)>0)
      System.out.println("Today Date is Greater than my date"); 
  else
      System.out.println("Both Dates are equal"); 

Comentarii

  • Cred că „new Date(today.getYear(),today.getMonth()-1,today.getDay());” este depreciat. download.oracle.com/javase/6/docs/api/java/java/util/Date.html –  > Por Dr. No.
  • @Muath: Deși nu sunt 100% sigur, cred că se datorează faptului că componenta lună din Date este indexată cu zero. –  > Por Lii.
  • cred că acolo altundeva partea nu funcționează 🙂 –  > Por Sachith.
gstackoverflow

Actualizare pentru Java 8 și ulterior

Aceste metode există în LocalDate, , LocalTime, , și LocalDateTime clase.

Aceste clase sunt integrate în Java 8 și versiunile ulterioare. O mare parte din funcționalitatea java.time este readusă în Java 6 & 7 în ThreeTen-Backport și adaptate în continuare la Android în ThreeTenABP (a se vedea Cum se utilizează…).

Comentarii

  • cum să descărcați aceste trei clase –  > Por Punithapriya.
  • @Punithapriya Aceste clase există în biblioteca java 8 standart. Astfel, doar descărcați java 8 –  > Por gstackoverflow.
  • da, am văzut, mulțumesc –  > Por Punithapriya.
Salman A

Puteți utiliza Date.getTime() care:

Returnează numărul de milisecunde de la 1 ianuarie 1970, 00:00:00:00 GMT reprezentat de acest obiect Date.

Acest lucru înseamnă că le puteți compara ca pe niște numere:

if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) {
    /*
     * date is between date1 and date2 (both inclusive)
     */
}

/*
 * when date1 = 2015-01-01 and date2 = 2015-01-10 then
 * returns true for:
 * 2015-01-01
 * 2015-01-01 00:00:01
 * 2015-01-02
 * 2015-01-10
 * returns false for:
 * 2014-12-31 23:59:59
 * 2015-01-10 00:00:01
 * 
 * if one or both dates are exclusive then change <= to <
 */

Garambe

Încercați acest lucru

public static boolean compareDates(String psDate1, String psDate2) throws ParseException{
        SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy");
        Date date1 = dateFormat.parse(psDate1);
        Date date2 = dateFormat.parse(psDate2);
        if(date2.after(date1)) {
            return true;
        } else {
            return false;
        }
    }

Toată lumea

Utilizați getTime() pentru a obține valoarea numerică a datei, apoi comparați folosind valorile returnate.

Brownsoo Han

Acest cod determină că ziua de astăzi este într-o anumită durată… bazat pe KOREA locale

    Calendar cstart = Calendar.getInstance(Locale.KOREA);
    cstart.clear();
    cstart.set(startyear, startmonth, startday);


    Calendar cend = Calendar.getInstance(Locale.KOREA);
    cend.clear();
    cend.set(endyear, endmonth, endday);

    Calendar c = Calendar.getInstance(Locale.KOREA);

    if(c.after(cstart) && c.before(cend)) {
        // today is in startyear/startmonth/startday ~ endyear/endmonth/endday
    }

Iman Marashi

Această metodă a funcționat pentru mine:

 public static String daysBetween(String day1, String day2) {
    String daysBetween = "";
    SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try {
        Date date1 = myFormat.parse(day1);
        Date date2 = myFormat.parse(day2);
        long diff = date2.getTime() - date1.getTime();
        daysBetween = ""+(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return daysBetween;
}

Comentarii

  • Nu răspunde la întrebare. Întrebarea implică trei date, nu două. „Cum pot verifica dacă data de astăzi este cuprinsă între data1 și data 3?” În plus, acest calcul returnează numărul de perioade de 24 de ore, nu numărul de zile calendaristice scurse. Încă o problemă: acest răspuns utilizează valori de dată-timp, în timp ce întrebarea se referă doar la valori de dată fără ora zilei. –  > Por Basil Bourque.