如何比较Java中的日期? [复制]

Posted

技术标签:

【中文标题】如何比较Java中的日期? [复制]【英文标题】:How to compare dates in Java? [duplicate] 【发布时间】:2011-02-05 06:09:23 【问题描述】:

如何在 Java 中比较两者之间的日期?

例子:

date1 是22-02-2010 date2 是 07-04-2010 今天 date3 是25-12-2010

date3 总是大于date1 并且date2 总是今天。如何验证今天的日期是否在 date1 和 date 3 之间?

【问题讨论】:

【参考方案1】:

Date有before和after方法,可以是compared to each other,如下:

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.time (JSR-310)。

Back-ports 可用于 Java 6 和 7 以及 android

【讨论】:

这是包含边界的,还是边界专有的? @DanielHári 不,它不包括在内。您可以使用第一条评论中建议的解决方案,或使用 CompareTo()>=0 。 正常的通常是“左包右排”​​,这就是为什么我认为应该准确指定的原因。使用“左包含,右排除”边界,您可以轻松指定 fe:一个月间隔:[2016/04/01, 2016/05/01],这就是为什么这是正常的并在许多用例中用作默认值。 仅供参考,麻烦的旧日期时间类,例如 java.util.Date 现在是 legacy,被 Java 8 和 Java 9 中内置的 java.time 类所取代。请参阅 Tutorial by Oracle。跨度> @BasilBourque 是的,正确,因此关于 Java 8 的 Joda 和 java.time 的评论,现在是标准版本(与我写这个答案的时间相反)。当然,请随意编辑此答案并添加更多最新示例代码! ;)(编辑:啊,我看到你自己已经用上述例子提供了答案)【参考方案2】:

使用compareTo:

date1.compareTo(date2);

【讨论】:

与日期、字节、长整数、整数完美搭配... 有时它不起作用。我在 main 方法中多次触发以检查相等性。大多数时候它说相等,但不是所有时候。 @Syed 你能分享你的代码吗? @ChandraSekarS,尝试通过采用相同的日期作为主要方法代码执行并查看输出。有时,它给出 0,有时给出 1。【参考方案3】:

以下是比较dates 最常用的方法(我的偏好是方法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");

方法二: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:Calender.before()Calender.after() 和 Calender.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");

【讨论】:

仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle。【参考方案4】:

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 类表示没有时间和时区的仅日期值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 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 ) ;

请参阅the Answer by g***,其中显示了您可以调用的比较方法列表。


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

从哪里获取 java.time 类?

Java SE 8Java SE 9Java SE 10Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。 Java 9 带来了一些小功能和修复。 Java SE 6Java SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android java.time 类的更高版本的 Android (26+) 捆绑实现。 对于早期的 Android (API desugaring 的进程带来了最初未内置于 Android 中的 subset of the java.time 功能。 如果脱糖不能满足您的需求,ThreeTenABP 项目会将ThreeTen-Backport(如上所述)适配到 Android。见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。


更新:下面的“Joda-Time”部分保留为历史记录。 Joda-Time 项目现在位于 maintenance mode,建议迁移到 java.time 类。

乔达时间

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

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

输入…

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。 overlapcontains 等方法可以轻松进行比较。

对于文本表示,请查看 ISO 8601 标准:

duration格式:PnYnMnDTnHnMnS示例:P3Y6M4DT12H30M5S(表示“三年零六个月零四天十二小时三十分钟五秒”) interval格式:开始/结束示例:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z

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

Joda-Time 使用 半开 方法执行比较,其中跨度的开始是包含,而结束是独占。这种方法是处理时间跨度的明智方法。搜索 *** 了解更多信息。

【讨论】:

【参考方案5】:

比较两个日期:

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

【讨论】:

我认为“new Date(today.getYear(),today.getMonth()-1,today.getDay());”它已被弃用。 download.oracle.com/javase/6/docs/api/java/util/Date.html @Muath:虽然我不是 100% 确定,但我认为这是因为 Date 中的月份组件是零索引的。 我认为其他部分不起作用:)【参考方案6】:

Java 8 及更高版本的更新

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

这些方法存在于LocalDateLocalTimeLocalDateTime 类中。

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

【讨论】:

这三个类怎么下载 @Punithapriya 这些类存在于 java 8 标准库中。因此只需下载 java 8 是的,我已经看到了,谢谢【参考方案7】:

您可以使用Date.getTime()

返回自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数 由此 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 <
 */

【讨论】:

【参考方案8】:

试试这个

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;
        
    

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

此代码确定今天是在一段时间内.. 基于韩国语言环境

    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
    

【讨论】:

【参考方案11】:

这个方法对我有用:

 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;

【讨论】:

不回答问题。问题涉及三个日期,而不是两个。 “我如何验证今天的日期是否在 date1 和 date 3 之间?”此外,此计算返回 24 小时周期数,而不是经过的日历天数。还有一个问题:这个答案使用日期时间值,而问题是关于没有时间的仅日期值。

以上是关于如何比较Java中的日期? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

比较Python中的数据框日期时间列值? [复制]

如何比较Java中日期的时间部分

Java中如何比较 String型 日期 ??

JS 如何比较时间大小?

java 日期怎么比较大小?

我想从 Java 日期中获取年、月、日等,以与 Java 中的公历日期进行比较。这可能吗?