Найкращий спосіб порівняти дати в 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.