如何在Java中确定一个日期是否在两个日期之间?

118

如何检查一个日期是否在另外两个日期之间,在这种情况下,所有三个日期都由java.util.Date的实例表示?

11个回答

290

这可能会更易读一些:

Date min, max;   // assume these are set to something
Date d;          // the date in question

return d.after(min) && d.before(max);

3
非常健康,比原来快了9秒,先生。 - Tetsujin no Oni
78
区间可以包含端点,在这种情况下,您可以使用 return !d.before(min) && !d.after(max);。 (注:该句为程序代码语言,意思为判断一个日期d是否在一个区间[min, max]内,如果该区间包含端点,则返回!d.before(min) && !d.after(max)) - Patrick McDonald
1
@Tetsujin no Oni 哥们,很庆幸我现在没有一个重要的项目要在几周内交付,而且Stack Overflow对它既有帮助又有限制。:) - Nathan Feger
@NathanFeger,我还想说一点关于after()before()的问题,它们都是排除类型,这意味着after()不会给出d天的结果。我有一个相同的场景,需要在报告中包含minmax日期,使用if((date.after(fromDate) || date.compareTo(fromDate)==0) && (date.before(toDate) || date.compareTo(toDate)==0 ))没有任何结果,请建议好的方法。 - MegaBytes
3
这比“选定的已解答”更好吗? - Christian Moen
显示剩余2条评论

150

如果您不知道最小/最大值的顺序

Date a, b;   // assume these are set to something
Date d;      // the date in question

return a.compareTo(d) * d.compareTo(b) > 0;

如果你想要范围是包含的

return a.compareTo(d) * d.compareTo(b) >= 0;

你可以使用以下方法将null视为无限制:


You can treat null as unconstrained with
if (a == null) {
    return b == null || d.compareTo(b) < 0;
} else if (b == null) {
    return a.compareTo(d) < 0;
} else {
    return a.compareTo(d) * d.compareTo(b) > 0;
}

41
可以工作,但不易读。无论如何还是感谢你。 - Bruno De Freitas Barros
1
@BrunoDeFreitasBarros 你所说的“不可读”是什么意思? - Peter Lawrey
5
Peter Lawrey说,如果没有注释,代码很难理解。Bruno的意思是没有注释的代码难以理解。 - Mirimas
2
如果 (d == a || d == b) 那么它不起作用。 - junsid
2
@junsid 对于包含范围,我已经添加了更新。谢谢。 - Peter Lawrey
显示剩余2条评论

50

就像这样:

Date min, max;   // assume these are set to something
Date d;          // the date in question

return d.compareTo(min) >= 0 && d.compareTo(max) <= 0;

您可以使用>代替>=,并使用<代替<=,以从“之间”概念中排除端点。


感谢您的即时回复。 - Gnaniyar Zubair
1
这并不总是有效的。我在使用compareTo处理日期对象时遇到了问题。在我的一个程序中,2006年1月1日显然在2006年4月1日之后。 - KitsuneYMG
@KitsuneYMG:我尝试了以下代码,结果如预期:Date date1 = new Date(2006, 1, 1); // Jan 1,2006 Date date2 = new Date(2006, 4, 1); // Apr 1, 2006 System.out.println(date1.compareTo(date2)); // -1 System.out.println(date2.compareTo(date1)); // 1。你能在这里分享一下你遇到的不工作的问题吗? - Gnanam
1
这是 between 的确切答案,其他答案是针对日期的 within - Mr. Mak

17

包含两个端点的日期区间可以写作:

public static boolean isDateInBetweenIncludingEndPoints(final Date min, final Date max, final Date date){
    return !(date.before(min) || date.after(max));
}

注意:正如@Ponmudi在评论中指出的那样,如果日期在毫秒级别上有所不同,则此解决方案可能无法正常工作。


1
请注意,当日期匹配时,after()和before()可能无法按预期工作。 - Ponmudi VN
我该如何在Java8过滤器中使用这个? - Coding world

12

以下是使用Joda-Time 2.3库完成此操作的几种方法。

一种方法是在DateTime实例上使用简单的isBeforeisAfter方法。顺便说一句,在Joda-Time中,DateTime与java.util.Date(宇宙时间轴上的一个时刻)的概念类似,但包括时区。

另一种方式是在Joda-Time中构建一个Interval对象。 contains方法测试给定的DateTime是否在Interval所覆盖的时间范围内。 Interval的开始是包含的,但端点是排除的。这种方法被称为“半开放”,符号为[)

请参见以下代码示例中的两种方法。

将java.util.Date实例转换为Joda-TimeDateTime实例。只需将Date实例传递给DateTime的构造函数即可。在实践中,您应该传递特定的DateTimeZone对象,而不是依赖于JVM的默认时区。

DateTime dateTime1 = new DateTime( new java.util.Date() ).minusWeeks( 1 );
DateTime dateTime2 = new DateTime( new java.util.Date() );
DateTime dateTime3 = new DateTime( new java.util.Date() ).plusWeeks( 1 );

通过测试比较before/after...

boolean is1After2 = dateTime1.isAfter( dateTime2 );
boolean is2Before3 = dateTime2.isBefore( dateTime3 );

boolean is2Between1And3 = ( ( dateTime2.isAfter( dateTime1 ) ) && ( dateTime2.isBefore( dateTime3 ) ) );

使用间隔(Interval)方法代替isAfter/isBefore方法...

Interval interval = new Interval( dateTime1, dateTime3 );
boolean intervalContainsDateTime2 = interval.contains( dateTime2 );

将内容输出到控制台...

System.out.println( "DateTimes: " + dateTime1 + " " + dateTime1 + " " + dateTime1 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );
System.out.println( "is2Between1And3 " + is2Between1And3 );
System.out.println( "intervalContainsDateTime2 " + intervalContainsDateTime2 );

当运行时,程序将从指定的起始点开始执行,并按照编写的顺序一步步地执行每个语句,直到程序结束或遇到错误。

DateTimes: 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00
is1After2 false
is2Before3 true
is2Between1And3 true
intervalContainsDateTime2 true

10

另一个选项

min.getTime() <= d.getTime() && d.getTime() <= max.getTime()

这是唯一的最优解,其他方案似乎对于简单的事情过于复杂了。 - delpo

4

请看下面:

public static void main(String[] args) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

        String oeStartDateStr = "04/01/";
        String oeEndDateStr = "11/14/";

        Calendar cal = Calendar.getInstance();
        Integer year = cal.get(Calendar.YEAR);

        oeStartDateStr = oeStartDateStr.concat(year.toString());
        oeEndDateStr = oeEndDateStr.concat(year.toString());

        Date startDate = sdf.parse(oeStartDateStr);
        Date endDate = sdf.parse(oeEndDateStr);
        Date d = new Date();
        String currDt = sdf.format(d);


        if((d.after(startDate) && (d.before(endDate))) || (currDt.equals(sdf.format(startDate)) ||currDt.equals(sdf.format(endDate)))){
            System.out.println("Date is between 1st april to 14th nov...");
        }
        else{
            System.out.println("Date is not between 1st april to 14th nov...");
        }
    }

2

以下是如何判断今天是否在两个月之间的方法:

private boolean isTodayBetween(int from, int to) {
    if (from < 0 || to < 0 || from > Calendar.DECEMBER || to > Calendar.DECEMBER) {
        throw new IllegalArgumentException("Invalid month provided: from = " + from + " to = " + to);
    }
    Date now = new Date();
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTime(now);
    int thisMonth = cal.get(Calendar.MONTH);
    if (from > to) {
        to = to + Calendar.DECEMBER;
        thisMonth = thisMonth + Calendar.DECEMBER;
    }
    if (thisMonth >= from && thisMonth <= to) {
        return true;
    }
    return false;
}

然后像这样调用:

isTodayBetween(Calendar.OCTOBER, Calendar.MARCH)

2
import java.util.Date;

public class IsDateBetween {

public static void main (String[] args) {

          IsDateBetween idb=new IsDateBetween("12/05/2010"); // passing your Date
 }
 public IsDateBetween(String dd) {

       long  from=Date.parse("01/01/2000");  // From some date

       long to=Date.parse("12/12/2010");     // To Some Date

       long check=Date.parse(dd);

       int x=0;

      if((check-from)>0 && (to-check)>0)
      {
             x=1;
      }

 System.out.println ("From Date is greater Than  ToDate : "+x);
}   

}

2

你可以使用 getTime() 并比较返回的长整型UTC值。

如果你确定不需要处理1970年之前的日期,可以编辑代码,但不确定在这种情况下会发生什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接