Найкращий спосіб порівняти дати в Android


102

Я намагаюся порівняти дату у форматі String з поточною датою. Ось як я це зробив (не перевіряв, але повинен працювати), але використовую застарілі методи. Будь-яка гарна пропозиція щодо альтернативи? Дякую.

PS Я дуже ненавиджу робити речі з датами на Java. Існує так багато способів зробити те саме, що ти справді не впевнений, який з них є правильним, звідси і моє запитання.

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

4
У 2018 році найкращий спосіб не передбачає Calendar, SimpleDateFormat, Dateабо будь-який з інших довгих застарілих дати і часу Java класів. Замість цього використовуйте java.timeсучасний API дати та часу Java . Так, ви можете використовувати його на Android. Для старих Android див. Як використовувати ThreeTenABP в Android Project .
— Оле ВВ

Відповіді:


219

Ваш код можна зменшити до

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

або

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

це працює точно, я розмістив таке ж рішення в іншій темі, але не тут, тому що колега був швидшим O_o.
— Саймон Дорочак

просто хотів переконатися, перш ніж приймати. Дякую. він працював ідеально і є лаконічним і простим, як хотілося.
— nunos

16
Я думаю, що слід використовувати формат dd / MM / yyyy замість dd / mm / yyyy, тому що "m" означає хвилини, а "M" - місяць.
— Демвіс

Чи не буде краще використовувати метод CompareTo ()?
— клас Android

25

Ви можете використовувати CompareTo ()

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

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

1
FYI, клопітно старі класи дати і часу , такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер спадщина, витісняється java.time класів. Більшість функцій java.time повертається назад до Java 6 та Java 7 у проекті ThreeTen-Backport . Крім того, адаптований до попереднього Android (<26) у ThreeTenABP . Див. Як користуватися ThreeTenABP… .
— Василь Бурк

10

Ви можете безпосередньо створити Calendarз Date:

Calendar validDate = new GregorianCalendar();
validDate.setTime(strDate);
if (Calendar.getInstance().after(validDate)) {
    catalog_outdated = 1;
}

10

Зауважте, що правильний формат ("dd / MM / yyyy") перед тим, як код працює. "мм" означає мінути!

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

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

 }

FYI, клопітно старі класи дати і часу , такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер спадщина, витісняється java.time класів. Більшість функцій java.time повертається назад до Java 6 та Java 7 у проекті ThreeTen-Backport . Крім того, адаптований до попереднього Android (<26) у ThreeTenABP . Див. Як користуватися ThreeTenABP… .
— Василь Бурк

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

він повертається істинним .. і ви також можете перевірити перед і зрівнятись за допомогою date.before and date.equal ..


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

Порівняє час, представлений цим Календарем, та час, представлений цим Календарем.

Повертає 0, якщо час двох календарів дорівнює, -1 якщо час цього календаря передує іншому, 1 якщо час цього календаря закінчується іншим.


1
Дякую .. Його допоможіть мені.
— pRaNaY

2

конвертуйте дату в Календар і зробіть там свої розрахунки. :)

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)

Або:

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

if (strDate.after(new Date()) {
    catalog_outdated = 1;
}

2

Час для сучасної відповіді.

java.time та 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");
    }

Коли я запустив цей код саме зараз, вихід:

Каталог застарів

Оскільки це не завжди однакова дата у всіх часових поясах, дайте чіткий часовий пояс LocalDate.now. Якщо ви хочете, щоб каталог закінчувався одночасно у всіх часових поясах, ви можете датиZoneOffset.UTC , якщо ви повідомляєте користувачів, що використовуєте UTC.

Я використовую java.time, сучасний API дати та часу Java. Класи дати і час , які ви використовували, Calendar, SimpleDateFormatі Date, все погано розроблені і до щастя , давно застаріли. Також, незважаючи на назву, а Dateне є дата, а момент часу. Одним із наслідків цього є: хоча сьогодні 15 лютого 2019 року, новостворений Dateоб’єкт вже після (тобто не рівний) Dateоб’єкта від розбору 15/02/2019. Це декого бентежить. Всупереч цьому, сучасною LocalDateє дата без часу доби (і без часового поясу), тому два, LocalDateщо представляють сьогоднішню дату, завжди будуть рівними.

Питання: Чи можна використовувати java.time на Android?

Так, java.time чудово працює на старих та новіших пристроях Android. Для цього просто потрібно принаймні Java 6 .

  • У Java 8 і новіших пристроях Android (від рівня API 26) вбудований сучасний API.
  • У Java 6 та 7 отримайте ThreeTen Backport, опору сучасних класів (ThreeTen для JSR 310; див. Посилання внизу).
  • На (старшому) Android використовують Android-версію ThreeTen Backport. Це називається ThreeTenABP. І переконайтеся, що ви імпортуєте дати та часові класи org.threeten.bpз підпакетів.

Посилання


1

Ви можете спробувати це

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

і ви можете використовувати today.getTime()для отримання значення та порівняння.


1

Іноді нам потрібно скласти список із датами, наприклад

сьогодні з годиною

вчора з вчора

інші дні з 23.06.2017

Для цього нам потрібно порівняти поточний час з нашими даними.

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

Також ви можете перевірити цей приклад у GitHub та цій публікації .


1

Оновлення: Бібліотека Joda-Time зараз перебуває в режимі обслуговування та рекомендує перейти на рамку java.time, яка її вдається. Дивіться відповідь на Ole VV .


Joda-Time

Класи java.util.Date та .Calendar, як відомо, непросто. Уникайте їх. Використовуйте або Joda-Time, або новий пакет java.time на Java 8.

LocalDate

Якщо ви хочете лише за датою без часу, використовуйте клас LocalDate.

Часовий пояс

Отримання поточної дати залежить від часового поясу. У Парижі перед Монтреалом відбулася нова дата. Вкажіть бажаний часовий пояс, а не залежайте від замовчування JVM.

Приклад у 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 );


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

0

Kotlin підтримує перевантаження операторів

У Котліні ви можете легко порівняти дати з операторами порівняння. Тому що Kotlin вже підтримує операторів, що перевантажують. Отже, для порівняння об’єктів дати:

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

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

і якщо ви використовуєте об’єкти календаря, ви можете легко порівняти так:

if(cal1.time < cal2.time){
// cal1 date is before cal2 date
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.