在Android中比较日期的最佳方法


102

我正在尝试将字符串格式的日期与当前日期进行比较。这就是我的做法(尚未测试,但应该可以工作),但是我使用的是不赞成使用的方法。有什么好的建议吗?谢谢。

PS:我真的很讨厌用Java做Date的事情。做同一件事的方法有很多,以至于您真的不确定哪一种是正确的,因此我在这里提出问题。

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年最好的办法不涉及CalendarSimpleDateFormatDate或任何其他早已过时的Java日期和时间类的。取而代之的是使用java.time现代Java日期和时间API。是的,您可以在Android上使用它。对于较旧的Android,请参见如何在Android Project中使用ThreeTenABP
Ole VV

Answers:


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速度较快而未在此处发布。
Simon Dorociak 2012年

只是想确定一下,然后再接受。谢谢。它工作完美,简洁而简单。
努诺斯(

16
我认为应该使用dd / MM / yyyy格式而不是dd / mm / yyyy,因为“ m”表示分钟,“ M”表示月。
Demwis

使用compareTo()方法会更好吗?
Android类,2016年

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
仅供参考,麻烦的旧日期,时间类,如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在的遗产,由取代java.time类。在ThreeTen-Backport项目中,大多数java.time功能都被反向移植到Java 6和Java 7 。在ThreeTenABP中进一步适用于早期的Android(<26)。请参阅如何使用ThreeTenABP…
罗勒·布尔克

10

您可以直接Calendar从创建一个Date

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

10

请注意,在代码起作用之前,正确的格式是(“ dd / MM / yyyy”)。“ mm”表示分钟!

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

 }

仅供参考,麻烦的旧日期,时间类,如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在的遗产,由取代java.time类。在ThreeTen-Backport项目中,大多数java.time功能都被反向移植到Java 6和Java 7 。在ThreeTenABP中进一步适用于早期的Android(<26)。请参阅如何使用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();
    }

它返回true ..并且您还可以在date.before和date.equal的帮助下检查before和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
谢谢..它可以帮助我。
2013年

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,现代的Java日期和时间API。您使用的日期时间类CalendarSimpleDateFormatDate都设计不当,幸运的是过时了。同样,尽管名称a Date并不代表日期,但代表时间点。这样的结果是:即使今天是2019年2月15日,一个新创建的Date对象已经Date解析对象之后(因此不等于)15/02/2019。这使一些人困惑。与此相反,现代LocalDate是没有日期(也没有时区)的日期,所以两个LocalDate的日期代表今天的日期的 s将始终相等。

问题:我可以在Android上使用java.time吗?

是的,java.time在旧的和更新的Android设备上都能很好地工作。它至少需要Java 6

  • 在Java 8和更高版本以及更新的Android设备(来自API级别26)中,内置了现代API。
  • 在Java 6和7中,获取ThreeTen Backport,这是现代类的backport(JSR 310的ThreeTen;请参见底部的链接)。
  • 在旧版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

更新:乔达时间,现在图书馆处于维护模式,并建议迁移到java.time框架,成功的话。请参阅Ole VV答案


乔达时代

众所周知,java.util.Date和.Calendar类很麻烦。避免他们。在Java 8中使用Joda-Time或新的java.time包。

本地日期

如果您希望仅使用日期而不使用日期,则可以使用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中,您可以轻松地与比较运算符比较日期。因为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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.