如何在Java中比较日期?

例子:

日期为22-02-2010 日期2是今天07-04-2010 Date3是25-12-2010

Date3总是大于date1,而date2总是今天。如何验证今天的日期是否在日期1和日期3之间?


Date有前后两种方法,它们之间的比较如下:

if(todayDate.after(historyDate) && todayDate.before(futureDate)) {
    // In between
}

要进行包容性比较:

if(!historyDate.after(todayDate) && !futureDate.before(todayDate)) {
    /* historyDate <= todayDate <= futureDate */ 
}

你也可以试试Joda-Time,但请注意:

Joda-Time是Java SE 8之前的Java事实上的标准日期和时间库。现在要求用户迁移到java。时间(jsr - 310)。

后端端口可用于Java 6和7以及Android。


使用compareTo:

date1.compareTo (date2);


比较这两个日期:

  Date today = new Date();                   
  Date myDate = new Date(today.getYear(),today.getMonth()-1,today.getDay());
  System.out.println("My Date is"+myDate);    
  System.out.println("Today Date is"+today);
  if (today.compareTo(myDate)<0)
      System.out.println("Today Date is Lesser than my Date");
  else if (today.compareTo(myDate)>0)
      System.out.println("Today Date is Greater than my date"); 
  else
      System.out.println("Both Dates are equal"); 

使用getTime()获取日期的数值,然后使用返回值进行比较。


这段代码确定今天是在一段时间内。基于韩国地区

    Calendar cstart = Calendar.getInstance(Locale.KOREA);
    cstart.clear();
    cstart.set(startyear, startmonth, startday);


    Calendar cend = Calendar.getInstance(Locale.KOREA);
    cend.clear();
    cend.set(endyear, endmonth, endday);

    Calendar c = Calendar.getInstance(Locale.KOREA);

    if(c.after(cstart) && c.before(cend)) {
        // today is in startyear/startmonth/startday ~ endyear/endmonth/endday
    }

以下是比较日期的最常用方法(我的首选方法1):

方法1:使用Date.before(), Date.after()和Date.equals()

if (date1.after(date2)) {
    System.out.println("Date1 is after Date2");
}

if (date1.before(date2)) {
    System.out.println("Date1 is before Date2");
}

if (date1.equals(date2)) {
    System.out.println("Date1 is equal Date2");
}

方法2:Date.compareTo()

if (date1.compareTo(date2) > 0) {
    System.out.println("Date1 is after Date2");
} else if (date1.compareTo(date2) < 0) {
    System.out.println("Date1 is before Date2");
} else {
    System.out.println("Date1 is equal to Date2");
}

方法3:calendar .before(), calendar .after()和calendar .equals()

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);

if (cal1.after(cal2)) {
    System.out.println("Date1 is after Date2");
}

if (cal1.before(cal2)) {
    System.out.println("Date1 is before Date2");
}

if (cal1.equals(cal2)) {
    System.out.println("Date1 is equal Date2");
}

博士tl;

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
Boolean isBetween = 
    ( ! today.isBefore( localDate1 ) )  // “not-before” is short for “is-equal-to or later-than”.
    &&
    today.isBefore( localDate3 ) ; 

或者,如果您将ThreeTen-Extra库添加到您的项目中,情况会更好。

LocalDateRange.of(
    LocalDate.of( … ) ,
    LocalDate.of( … )
).contains(
    LocalDate.now()
)

半开放的方法,开始是包容的,结束是排外的。

格式选择不当

顺便说一下,对于日期或日期-时间值的文本表示来说,这是一个糟糕的格式选择。只要可能,坚持使用标准的ISO 8601格式。ISO 8601格式是明确的,在人类文化中都是可以理解的,并且很容易被机器解析。

对于只有日期的值,标准格式为YYYY-MM-DD。请注意,这种格式在按字母顺序排序时是按时间顺序排列的。

LocalDate

LocalDate类表示一个只包含日期的值,不包含日期和时区。

时区是决定日期的关键。对于任何给定的时刻,全球各地的日期都因地区而异。例如,法国巴黎午夜过后几分钟就是新的一天,但在Montréal Québec上仍然是“昨天”。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

DateTimeFormatter

由于您的输入字符串是非标准格式,我们必须定义一个格式模式来匹配。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );

使用它来解析输入字符串。

LocalDate start = LocalDate.parse( "22-02-2010" , f );
LocalDate stop = LocalDate.parse( "25-12-2010" , f );

在日期时间工作中,通常最好使用半开放方法定义时间跨度,其中开始是包含的,而结束是独占的。所以我们想知道今天是否与起点相同或晚于终点,同时也在终点之前。“与开始相同或晚于开始”的简短说法是“不在开始之前”。

Boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ;

请参阅gstackoverflow的答案,其中显示了您可以调用的比较方法列表。


关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

你可以交换java。Time对象直接使用数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java。sql。*类。Hibernate 5和JPA 2.2支持java.time。

从哪里获取java。时间类?

Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation. Java 9 brought some minor features and fixes. Java SE 6 and Java SE 7 Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport. Android Later versions of Android (26+) bundle implementations of the java.time classes. For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android. If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。


更新:下面的“Joda-Time”部分作为历史完整保留。Joda-Time项目现在处于维护模式,建议迁移到java。时间类。

乔达时间

关于绑定的java.util.Date和java.util.Calendar类,其他答案是正确的。但这些课程是出了名的麻烦。下面是一些使用Joda-Time 2.3库的示例代码。

如果你真的想要一个没有任何时间部分和时区的日期,那么使用Joda-Time中的LocalDate类。该类提供了比较方法,包括compareTo(与Java Comparators一起使用)、isBefore、isAfter和isEqual。

输入……

String string1 = "22-02-2010";
String string2 = "07-04-2010";
String string3 = "25-12-2010";

定义一个描述输入字符串的格式化程序…

DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );

使用格式化程序将字符串解析为LocalDate对象…

LocalDate localDate1 = formatter.parseLocalDate( string1 );
LocalDate localDate2 = formatter.parseLocalDate( string2 );
LocalDate localDate3 = formatter.parseLocalDate( string3 );

boolean is1After2 = localDate1.isAfter( localDate2 );
boolean is2Before3 = localDate2.isBefore( localDate3 );

转储到控制台…

System.out.println( "Dates: " + localDate1 + " " + localDate2 + " " + localDate3 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );

运行时……

Dates: 2010-02-22 2010-04-07 2010-12-25
is1After2 false
is2Before3 true

所以看看第二个端点是否在另外两个端点之间(独占性,意味着不等于任何一个端点)…

boolean is2Between1And3 = ( ( localDate2.isAfter( localDate1 ) ) && ( localDate2.isBefore( localDate3 ) ) );

有时间跨度的工作

如果您使用的是时间跨度,我建议您在Joda-Time中探索以下类:Duration、Interval和Period。重叠和包含等方法使比较变得容易。

对于文本表示,请参阅ISO 8601标准:

durationFormat: PnYnMnDTnHnMnSExample: P3Y6M4DT12H30M5S(意思是“三年,六个月,四天,十二小时,三十分,五秒”) intervalFormat: start/ endeexample: 2007-03-01T13:00:00Z/2008-05-11T15:30:00Z

Joda-Time类可以同时处理这两种格式的字符串,既可以作为输入(解析),也可以作为输出(生成字符串)。

Joda-Time使用半开放方法执行比较,其中跨度的开始是包容性的,而结束是排他性的。对于处理时间跨度来说,这种方法是明智的。搜索StackOverflow查看更多信息。


你可以使用Date.getTime():

返回从格林尼治标准时间1970年1月1日00:00:00开始的毫秒数 由这个Date对象表示。

这意味着你可以像比较数字一样比较它们:

if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) {
    /*
     * date is between date1 and date2 (both inclusive)
     */
}

/*
 * when date1 = 2015-01-01 and date2 = 2015-01-10 then
 * returns true for:
 * 2015-01-01
 * 2015-01-01 00:00:01
 * 2015-01-02
 * 2015-01-10
 * returns false for:
 * 2014-12-31 23:59:59
 * 2015-01-10 00:00:01
 * 
 * if one or both dates are exclusive then change <= to <
 */

针对Java 8及更高版本进行更新

isAfter () isBefore () isEqual () compareTo ()

这些方法存在于LocalDate、LocalTime和LocalDateTime类中。

这些类内置于Java 8及更高版本中。大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7,并在ThreeTenABP中进一步适应Android(参见如何使用…)


试试这个

public static boolean compareDates(String psDate1, String psDate2) throws ParseException{
        SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy");
        Date date1 = dateFormat.parse(psDate1);
        Date date2 = dateFormat.parse(psDate2);
        if(date2.after(date1)) {
            return true;
        } else {
            return false;
        }
    }

这个方法对我很管用:

 public static String daysBetween(String day1, String day2) {
    String daysBetween = "";
    SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try {
        Date date1 = myFormat.parse(day1);
        Date date2 = myFormat.parse(day2);
        long diff = date2.getTime() - date1.getTime();
        daysBetween = ""+(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return daysBetween;
}