2010-04-07 10 views
299

Jak porównać daty w Java?Jak porównać daty w Javie?

przykład:

date1 jest 22-02-2010
data2 jest 07-04-2010 już
date3 jest 25-12-2010

date3 jest zawsze większa niż date1 i date2 zawsze jest obecnie. Jak sprawdzić, czy dzisiejsza data jest pomiędzy datą 1 a datą 3?

Odpowiedz

473

Date ma before i after metody i może być compared to each other następująco:

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

Dla porównania Inclusive:

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

Można również dać Joda-Time odchodzenie, ale należy pamiętać, że:

Joda-Time to de facto Standardowa biblioteka daty i czasu dla Java przed Java SE 8. Użytkownicy są teraz proszeni o migrację do java.time (JSR-310).

Porty zwrotne są dostępne dla wersji Java 6 i 7 oraz Androida.

+3

Czy to włącznie, lub wyłącznie dla granic? –

+1

@ DanielHári no its not inclusive. możesz użyć rozwiązania sugerowanego w pierwszym komentarzu lub użyj polecenia CompareTo()> = 0. – Mifmif

+0

Normalny zwykle "lewy włącznie, prawy wyłączny", dlatego uważam, że należy to dokładnie określić. Dzięki ramkom "left inclusive, right exclusive" możesz łatwo określić: miesiąc interwał: [2016/04/01, 2016/05/01], dlatego jest to normalne i używane jako domyślne w wielu przypadkach użycia. –

109

Zastosowanie compareTo:

date1.compareTo(date2);

+0

Działa idealnie z datą, bajtem, długością, integer ... –

20

porównanie dwóch terminach:

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"); 
+6

Myślę, że "nowa data (dzisiaj.getYear(), dzisiaj.getMonth() -1, today.getDay()); " jest przestarzałe. http://download.oracle.com/javase/6/docs/api/java/util/Date.html –

+0

@Muath: Chociaż nie jestem w 100% pewny, myślę, że jest tak, ponieważ komponent miesiąca w 'Date' jest zero-indeksowane. – Lii

+0

Myślę, że tam jeszcze część nie działa :) – SMW

5

Zastosowanie getTime(), aby uzyskać wartość liczbową daty, a następnie porównać z wykorzystaniem zwróconych wartości.

0

Ten kod określenia dzisiaj jest w jakiś czas .. na podstawie KOREA lokalizacji

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

obserwuję są najczęstszym sposobem porównywania dat. Ale mam wolą pierwsza

Podejście-1: Używanie 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"); 
      } 

Podejście-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"); 
      } 

podejście-3: Calender.before() Calender.after() i kalandrowe.jest równy()

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"); 
      } 
+0

FYI, kłopotliwe stare klasy czasu, takie jak ['java.util.Date'] (https://docs.oracle.com/javase/9/docs/ api/java/util/Date.html), ['java.util.Calendar'] (https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html) oraz' java.text.SimpleDateFormat' są teraz [starsze] (https://en.wikipedia.org/wiki/Legacy_system), wypierane przez [java.time] (https://docs.oracle.com/javase/9/ docs/api/java/time/package-summary.html) klasy wbudowane w Java 8 i Java 9. Zobacz [* Tutorial * od Oracle] (https://docs.oracle.com/javase/tutorial/datetime/TOC. html). –

20

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

albo lepiej, jeśli dodać ThreeTen-Extra bibliotekę do projektu.

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

podejście pół-otwartych, gdzie początek jest integracyjnego natomiast zakończenie jest wyłącznym.

zły wybór formatu

przy okazji, że jest to zły wybór formatu reprezentacji tekstowej daty lub wartości daty i czasu. Jeśli to możliwe, trzymaj się standardowych formatów ISO 8601. Formaty ISO 8601 są jednoznaczne, zrozumiałe dla kultur ludzkich i łatwe do analizy przez maszynę.

W przypadku wartości tylko dla daty standardowym formatem jest RRRR-MM-DD. Zwróć uwagę, że ten format ma tę zaletę, że jest chronologiczny w kolejności alfabetycznej.

LocalDate

Klasa LocalDate reprezentuje wartość data-tylko bez time-of-day i bez strefy czasowej.

Strefa czasowa ma kluczowe znaczenie przy ustalaniu daty. W danym momencie data zmienia się na całym świecie według strefy. Na przykład kilka minut po północy w Paris France jest nowy dzień, a jednocześnie "wczoraj" w Montréal Québec.

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

DateTimeFormatter

Jak struny wejściowe są w formacie niestandardowym, musimy określić wzór formatowania dopasować.

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

Służy do analizowania ciągów wejściowych.

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

W pracy daty i czasu, zazwyczaj najlepiej zdefiniować przedział czasu od podejścia półotwartych, gdzie początek jest włącznie natomiast zakończenie jest wyłącznym. Chcemy więc wiedzieć, czy dzisiaj jest to samo, czy później niż początek, a także przed przystankiem. Krótszy sposób powiedzenia "jest taki sam lub późniejszy niż początek" to "nie przed startem".

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

Zobacz listę metod porównywania, z którymi możesz się połączyć.


O java.time

Ramy java.time jest wbudowana w Java 8 i późniejszych. Klasy te zastępują kłopotliwe stare klasy z datami, takie jak java.util.Date, Calendar, & SimpleDateFormat.

Projekt Joda-Time, teraz w maintenance mode, zaleca migrację do klas java.time. Aby uzyskać więcej informacji, zobacz

. I wyszukaj Stack Overflow dla wielu przykładów i objaśnień. Specyfikacja to JSR 310.

Gdzie można uzyskać lekcje java.time?

Projekt ThreeTen-Extra rozciąga java.time z dodatkowych zajęć. Ten projekt jest poligonem wskazującym na możliwe przyszłe dodatki do java.time. Możesz znaleźć tutaj kilka użytecznych klas, takich jak Interval, YearWeek, YearQuarter i more.


AKTUALIZACJA: Ta sekcja "Joda-Time" poniżej pozostaje nienaruszona jako historia. Projekt Joda-Time, teraz w maintenance mode, doradza migrację do java.time klas.

Joda-Time

Inne odpowiedzi są prawidłowe w odniesieniu do klas wiązanych java.util.Date i java.util.Calendar. Ale te zajęcia są notorycznie kłopotliwe. Więc oto kilka przykładów kodu przy użyciu biblioteki Joda-Time 2.3.

Jeśli naprawdę chcesz mieć datę bez części czasu i bez strefy czasowej, użyj klasy LocalDate w Joda-Time. Że klasa udostępnia metody porównania w tym compareTo (używane z Java Comparators), isBefore, isAfter i isEqual.

Wejścia ...

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

Definiowanie formatowania opisywaniu ciągów wejściowych ...

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

Zastosowanie formater do analizowania ciągów w LOCALDATE obiektów ...

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

Dump pocieszyć ...

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

Po uruchomieniu ...

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

więc sprawdzić, czy drugi jest między dwa pozostałe (nie wyłącznie, czyli równa albo końcowym) ...

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

Praca z przęseł Czas

Jeśli pracujesz z biegiem czasu, proponuję zbadanie w Joda-Time klas: Duration, Interval i Period. Metody takie jak overlap i contains ułatwiają porównywanie.

Dla reprezentacji tekstowych, spójrz na standardowej za ISO 8601:

  • duration
    format: PnYnMnDTnHnMnS
    Przykład: P3Y6M4DT12H30M5S
    (czyli „trzy lata, sześć miesięcy, cztery dni dwanaście godzin, trzydzieści minut, a pięć sekund”)
  • interval
    Format: start/koniec
    przykład: 2007-03-01T13: 00: 00S/2008-05-11T15: 30: 00Z

Klasy Joda-Time mogą pracować z łańcuchami w obu tych formatach, zarówno jako dane wejściowe (parsowanie), jak i wyjściowe (generujące łańcuchy znaków).

Joda-Time dokonuje porównań z wykorzystaniem półotwartych podejście gdzie początek rozpiętości jest włącznie natomiast zakończenie jest wyłącznym. Takie podejście jest mądre w radzeniu sobie z rozpiętością czasu. Wyszukaj StackOverflow, aby uzyskać więcej informacji.

10

Można użyć Date.getTime() których:

Zwraca liczbę milisekund od 1 stycznia 1970, 00:00:00 GMT reprezentowanym przez ten obiekt Date.

Oznacza to, że można je porównać tylko jak numery:

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 < 
*/ 
15

Aktualizacja dla Javy 8 i później

Te metody istnieje w LocalDate, LocalTime i LocalDateTime klas.

Te klasy są wbudowane w środowisko Java 8 i nowsze. Większość funkcji java.time została przeniesiona z powrotem do Java 6 & 7 w ThreeTen-Backport i dodatkowo zaadaptowana do Android w ThreeTenABP (patrz How to use…).

+0

jak pobrać te trzy klasy – Punithapriya

+1

@Punithapriya Te klasy istnieją w bibliotece standardowej java 8. Tak więc pobierz java 8 – gstackoverflow

+0

tak, widziałem dzięki – Punithapriya

3

Spróbuj

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

Ta metoda działa dla mnie:

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; 
} 
+0

Nie odpowiada na pytanie.Pytanie obejmuje * trzy * daty, a nie dwie. "W jaki sposób mogę sprawdzić, czy dzisiejsza data przypada między datą 1 a datą 3?" Ponadto obliczenia te zwracają liczbę 24-godzinnych okresów, a nie liczbę dni kalendarzowych, które upłynęły. Jeszcze jeden problem: w tej odpowiedzi używa się wartości daty i czasu, natomiast pytanie dotyczy wartości tylko daty i nie ma porę dnia. –