Najlepszy sposób na porównywanie dat w Androidzie

102

Próbuję porównać datę w formacie String z datą bieżącą. Tak to zrobiłem (nie testowałem, ale powinno działać), ale używam przestarzałych metod. Jakieś dobre sugestie dotyczące alternatywy? Dzięki.

PS Naprawdę nienawidzę robić randek w Javie. Jest tak wiele sposobów na zrobienie tego samego, że naprawdę nie jesteś pewien, który z nich jest właściwy, stąd moje pytanie.

String valid_until = "1/1/1990";

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
Date strDate = sdf.parse(valid_until);

int year = strDate.getYear(); // this is deprecated
int month = strDate.getMonth() // this is deprecated
int day = strDate.getDay(); // this is deprecated       

Calendar validDate = Calendar.getInstance();
validDate.set(year, month, day);

Calendar currentDate = Calendar.getInstance();

if (currentDate.after(validDate)) {
    catalog_outdated = 1;
}
nunos
źródło
4
W roku 2018 najlepszy sposób nie wiąże Calendar, SimpleDateFormat, Datelub którykolwiek z pozostałych długich przestarzałych klas daty i czasu Java. Zamiast tego użyj java.timenowoczesnego API daty i czasu Java . Tak, możesz go używać na Androidzie. W przypadku starszego Androida zobacz Jak używać ThreeTenABP w Android Project .
Ole VV

Odpowiedzi:

221

Twój kod może zostać zredukowany do

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (new Date().after(strDate)) {
    catalog_outdated = 1;
}

lub

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (System.currentTimeMillis() > strDate.getTime()) {
    catalog_outdated = 1;
}
JB Nizet
źródło
to działa pewnie, w innym wątku zamieściłem to samo rozwiązanie ale nie tutaj bo kolega był szybszy O_o.
Simon Dorociak
chciałem się tylko upewnić, zanim zaakceptujesz. dzięki. działało idealnie i jest zwięzłe i proste, jak było to oczekiwane.
nunos
16
Myślę, że zamiast dd / mm / rrrr należy użyć formatu dd / MM / rrrr, ponieważ „m” oznacza minuty, a „M” miesiąc.
Demwis
Czy nie byłoby lepiej użyć metody compareTo ()?
zajęcia z Androidem
25

Możesz użyć compareTo ()

CompareTo musi zwracać liczbę ujemną, jeśli bieżący obiekt jest mniejszy niż inny obiekt, liczbę dodatnią, jeśli bieżący obiekt jest większy niż inny obiekt i zero, jeśli oba obiekty są sobie równe.

// Get Current Date Time
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm aa");
String getCurrentDateTime = sdf.format(c.getTime());
String getMyTime="05/19/2016 09:45 PM ";
Log.d("getCurrentDateTime",getCurrentDateTime); 
// getCurrentDateTime: 05/23/2016 18:49 PM

if (getCurrentDateTime.compareTo(getMyTime) < 0)
{

}
else
{
 Log.d("Return","getMyTime older than getCurrentDateTime "); 
}
IntelliJ Amiya
źródło
1
FYI, kłopotliwego starych klas date-time, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz Legacy, wyparta przez java.time klas. Większość funkcji java.time jest przenoszona z powrotem do Java 6 i Java 7 w projekcie ThreeTen-Backport . Dalsze dostosowanie do wcześniejszego Androida (<26) w ThreeTenABP . Zobacz Jak używać ThreeTenABP… .
Basil Bourque
10

Możesz bezpośrednio utworzyć Calendarz Date:

Calendar validDate = new GregorianCalendar();
validDate.setTime(strDate);
if (Calendar.getInstance().after(validDate)) {
    catalog_outdated = 1;
}
asylias
źródło
10

Zauważ, że właściwy format to („dd / MM / rrrr”), zanim kod zadziała. „mm” oznacza minuty!

String valid_until = "01/07/2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = null;
try {
    strDate = sdf.parse(valid_until);
} catch (ParseException e) {
    e.printStackTrace();
}
if (new Date().after(strDate)) {
    catalog_outdated = 1;
}
Rocologo
źródło
7
Calendar toDayCalendar = Calendar.getInstance();
Date date1 = toDayCalendar.getTime();


Calendar tomorrowCalendar = Calendar.getInstance();
tomorrowCalendar.add(Calendar.DAY_OF_MONTH,1);
Date date2 = tomorrowCalendar.getTime();

// date1 is a present date and date2 is tomorrow date

if ( date1.compareTo(date2) < 0 ) {

  //  0 comes when two date are same,
  //  1 comes when date1 is higher then date2
  // -1 comes when date1 is lower then date2

 }
Śiwa Kryszna
źródło
FYI, kłopotliwego starych klas date-time, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz Legacy, wyparta przez java.time klas. Większość funkcji java.time jest przenoszona z powrotem do Java 6 i Java 7 w projekcie ThreeTen-Backport . Dalsze dostosowanie do wcześniejszego Androida (<26) w ThreeTenABP . Zobacz Jak używać ThreeTenABP… .
Basil Bourque
6
String date = "03/26/2012 11:00:00";
    String dateafter = "03/26/2012 11:59:00";
    SimpleDateFormat dateFormat = new SimpleDateFormat(
            "MM/dd/yyyy hh:mm:ss");
    Date convertedDate = new Date();
    Date convertedDate2 = new Date();
    try {
        convertedDate = dateFormat.parse(date);
        convertedDate2 = dateFormat.parse(dateafter);
        if (convertedDate2.after(convertedDate)) {
            txtView.setText("true");
        } else {
            txtView.setText("false");
        }
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

zwraca prawdę .. i możesz również sprawdzić przed i równe za pomocą date.before i date.equal ..

Dilavar Malek
źródło
3
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();

Date date1 = dateFormat.parse("2013-01-01");
Date date2 = dateFormat.parse("2013-01-02");

calendar1.setTime(date1);
calendar2.setTime(date2);

System.out.println("Compare Result : " + calendar2.compareTo(calendar1));
System.out.println("Compare Result : " + calendar1.compareTo(calendar2));

Porównuje czas reprezentowany przez ten kalendarz z czasem reprezentowanym przez dany kalendarz.

Zwraca 0, jeśli czasy dwóch Kalendarzy są równe, -1, jeśli czas w tym kalendarzu jest wcześniejszy niż inny, 1, jeśli czas w tym kalendarzu jest po drugim.

Kirit Vaghela
źródło
1
Dzięki ... Pomóż mi.
pRaNaY
2

przekonwertuj datę na kalendarz i wykonaj tam obliczenia. :)

Calendar cal = Calendar.getInstance();
cal.setTime(date);

int year = cal.get(Calendar.YEAR);
int month = cal.geT(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH); //same as cal.get(Calendar.DATE)

Lub:

SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
Date strDate = sdf.parse(valid_until);

if (strDate.after(new Date()) {
    catalog_outdated = 1;
}
Nuno Gonçalves
źródło
2

Czas na nowoczesną odpowiedź.

java.time i ThreeTenABP

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");
    String validUntil = "1/1/1990";
    LocalDate validDate = LocalDate.parse(validUntil, dateFormatter);
    LocalDate currentDate = LocalDate.now(ZoneId.of("Pacific/Efate"));
    if (currentDate.isAfter(validDate)) {
        System.out.println("Catalog is outdated");
    }

Kiedy właśnie uruchomiłem ten kod, wynik wyglądał następująco:

Katalog jest nieaktualny

Ponieważ nigdy nie jest to ta sama data we wszystkich strefach czasowych, podaj wyraźną strefę czasową na LocalDate.now. Jeśli chcesz, aby katalog wygasał w tym samym czasie we wszystkich strefach czasowych, możesz podać, ZoneOffset.UTCo ile poinformujesz użytkowników, że korzystasz z UTC.

Używam java.time, nowoczesnego API daty i czasu Java. Klasy data-czas, że używany Calendar, SimpleDateFormati Date, są źle zaprojektowane i na szczęście dawno nieaktualne. Również pomimo nazwy a Datenie oznacza daty, ale punkt w czasie. Jedną z konsekwencji tego jest: chociaż dzisiaj jest 15 lutego 2019 r., Nowo utworzony Dateobiekt jest już po (a więc nie równy) Dateobiektowi z parsowania 15/02/2019. To dezorientuje niektórych. W przeciwieństwie do tego współczesna LocalDatedata to data bez pory dnia (i bez strefy czasowej), więc dwie LocalDates reprezentujące dzisiejszą datę zawsze będą równe.

Pytanie: Czy mogę używać java.time na Androidzie?

Tak, java.time działa dobrze na starszych i nowszych urządzeniach z Androidem. Wymaga tylko co najmniej Javy 6 .

  • W Javie 8 i nowszych oraz na nowszych urządzeniach z Androidem (od poziomu API 26) wbudowane jest nowoczesne API.
  • W Javie 6 i 7 pobierz ThreeTen Backport, zaplecze nowoczesnych klas (ThreeTen dla JSR 310; patrz linki na dole).
  • Na (starszym) systemie Android użyj wersji ThreeTen Backport na Androida. Nazywa się ThreeTenABP. I upewnij się, że importujesz klasy daty i godziny org.threeten.bpz podpakietami.

Spinki do mankietów

Ole VV
źródło
1

Możesz tego spróbować

Calendar today = Calendar.getInstance (); 
today.add(Calendar.DAY_OF_YEAR, 0); 
today.set(Calendar.HOUR_OF_DAY, hrs); 
today.set(Calendar.MINUTE, mins ); 
today.set(Calendar.SECOND, 0); 

i możesz użyć today.getTime()do pobrania wartości i porównania.

Anurag Ramdasan
źródło
1

Czasami musimy zrobić listę z datami, na przykład

dzisiaj z godz

wczoraj z wczoraj

inne dni z 23.06.2017

Aby to zrobić, musimy porównać aktualny czas z naszymi danymi.

Public class DateUtil {

    Public static int getDateDayOfMonth (Date date) {
        Calendar calendar = Calendar.getInstance ();
        Calendar.setTime (date);
        Return calendar.get (Calendar.DAY_OF_MONTH);
    }

    Public static int getCurrentDayOfMonth () {
        Calendar calendar = Calendar.getInstance ();
        Return calendar.get (Calendar.DAY_OF_MONTH);
    }

    Public static String convertMillisSecondsToHourString (long millisSecond) {
        Date date = new Date (millisSecond);
        Format formatter = new SimpleDateFormat ("HH: mm");
        Return formatter.format (date);
    }

    Public static String convertMillisSecondsToDateString (long millisSecond) {
        Date date = new Date (millisSecond);
        Format formatter = new SimpleDateFormat ("dd / MM / yyyy");
        Return formatter.format (date);
    }

    Public static long convertToMillisSecond (Date date) {
        Return date.getTime ();
    }

    Public static String compare (String stringData, String yesterday) {

        String result = "";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH: mm: ss");
        Date date = null;

        Try {
            Date = simpleDateFormat.parse (stringData);
        } Catch (ParseException e) {
            E.printStackTrace ();
        }

        Long millisSecond = convertToMillisSecond (date);
        Long currencyMillisSecond = System.currentTimeMillis ();

        If (currencyMillisSecond> millisSecond) {
            Long diff = currencyMillisSecond - millisSecond;
            Long day = 86400000L;

            If (diff <day && getCurrentDayOfMonth () == getDateDayOfMonth (date)) {
                Result = convertMillisSecondsToHourString (millisSecond);

            } Else if (diff <(day * 2) && getCurrentDayOfMonth () -1 == getDateDayOfMonth (date)) {
                Result = yesterday;
            } Else {
                Result = convertMillisSecondsToDateString (millisSecond);
            }
        }

        Return result;
    }
}

Możesz również sprawdzić ten przykład w GitHub i ten post .

Cabezas
źródło
1

Aktualizacja: Joda-Time biblioteka jest teraz w trybie konserwacji i zaleca migracji do java.time ramy, które ma je zastąpić. Zobacz odpowiedź Ole VV .


Joda-Time

Klasy java.util.Date i .Calendar są notorycznie kłopotliwe. Unikaj ich. Użyj Joda-Time lub nowego pakietu java.time w Javie 8.

LocalDate

Jeśli chcesz, aby tylko data nie zawierała godziny, użyj klasy LocalDate.

Strefa czasowa

Uzyskanie aktualnej daty zależy od strefy czasowej. W Paryżu przed Montrealem nadchodzi nowy termin. Określ żądaną strefę czasową zamiast zależeć od domyślnej maszyny JVM.

Przykład w Joda-Time 2.3.

DateTimeFormat formatter = DateTimeFormat.forPattern( "d/M/yyyy" );
LocalDate localDate = formatter.parseLocalDate( "1/1/1990" );
boolean outdated = LocalDate.now( DateTimeZone.UTC ).isAfter( localDate );
Basil Bourque
źródło
0
SimpleDateFormat sdf=new SimpleDateFormat("d/MM/yyyy");
Date date=null;
Date date1=null;
try {
       date=sdf.parse(startDate);
       date1=sdf.parse(endDate);
    }  catch (ParseException e) {
              e.printStackTrace();
    }
if (date1.after(date) && date1.equals(date)) {
//..do your work..//
}
kartik_g
źródło
0

Kotlin wspiera przeciążanie operatorów

W Kotlinie możesz łatwo porównać daty z operatorami porównywania. Ponieważ Kotlin już obsługuje przeciążenia operatorów. Aby porównać obiekty daty:

firstDate: Date = // your first date
secondDate: Date = // your second date

if(firstDate < secondDate){
// fist date is before second date
}

a jeśli używasz obiektów kalendarza, możesz łatwo porównać w ten sposób:

if(cal1.time < cal2.time){
// cal1 date is before cal2 date
}
Khaled Qasem
źródło