Лучший способ сравнить даты в Android

102

Я пытаюсь сравнить дату в формате String с текущей датой. Вот как я это сделал (не тестировал, но должен работать), но использую устаревшие методы. Есть хорошие предложения по альтернативе? Спасибо.

PS Я действительно ненавижу делать Date на 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 .
Ole VV

Ответы:

221

Ваш код может быть сокращен до

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;
}
JB Nizet
источник
он работает, я опубликовал такое же решение в другом потоке, но не здесь, потому что коллега был быстрее O_o.
Саймон Дорочак
просто хотел убедиться, прежде чем принять. Спасибо. он сработал отлично, лаконичен и прост, как и хотелось.
nunos
16
Я считаю, что вместо дд / мм / гггг следует использовать формат дд / мм / гггг, потому что «м» означает минуты, а «M» - месяц.
Demwis
Не лучше ли использовать метод 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 "); 
}
IntelliJ Amiya
источник
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… .
Basil
10

Вы можете напрямую создать Calendarиз Date:

Calendar validDate = new GregorianCalendar();
validDate.setTime(strDate);
if (Calendar.getInstance().after(validDate)) {
    catalog_outdated = 1;
}
ассилий
источник
10

Обратите внимание, что правильный формат («дд / ММ / гггг») до того, как код заработает. «мм» означает минуты!

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

он возвращает true .. и вы также можете проверить до и равно с помощью date.before и 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));

Сравнивает время, представленное этим Calendar, со временем, представленным данным Calendar.

Возвращает 0, если времена двух календарей равны, -1, если время этого календаря опережает время другого, 1, если время этого календаря следует за другим.

Кирит Вагела
источник
1
Спасибо .. Помогите мне.
pRaNaY 02
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дата - это дата без времени суток (и без часового пояса), поэтому два LocalDates, представляющие сегодняшнюю дату, всегда будут равны.

Вопрос: Могу ли я использовать 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 время библиотека сейчас находится в режиме технического обслуживания, и рекомендует мигрировать в java.time рамки, преуспевает его. Смотрите ответ на Ole VV .


Джода-Тайм

Классы 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..//
}
kartik_g
источник
0

Kotlin поддерживает перегрузку операторов

В 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
}
Халед Касем
источник