如何比较两个日历日期?

问题描述 投票:0回答:6

我遇到了一个 Java 问题,我需要检查某个项目是否已过期。这应该检查该项目是否至少有 x(x 是一个整数,可以设置为任何整数值)个月了。

澄清一下,假设我有一包鸡蛋,我想检查一下添加它们后是否已经过去了 1 个月 (

dateAdded
)。

我写了一个简单的比较,但它似乎没有给出正确的答案。 这是代码。

public Boolean isEndOfLine() {
    Calendar today = Calendar.getInstance();
    if(today.compareTo(dateAdded) >= END_OF_LINE) {
        return true;
    } else {
        return false;
    }
}

行尾的值为整数 12,即 12 个月。

java date calendar comparison
6个回答
2
投票

我脑子里没有javadoc,而是沿着以下路线:

dateAdded.add(Calendar.Month, END_OF_LINE).compareTo(today) > 0

1
投票

这里有一些类似的示例代码,但使用的是 Joda-Time 2.3 库。

仅供参考:

  • Joda-Time DateTime 实例知道自己的时区。
  • minusMonths
    方法很聪明,可以处理夏令时等问题。您可能需要阅读其源代码以验证其逻辑是否符合您的业务规则,即“x 个月前”的含义。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Better to specify a time zone explicitly rather than rely on default.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html  (not quite up-to-date, read page for details)
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );

int countMonths = 2;

DateTime now = new DateTime( timeZone );
// If you want to include the entire day, get first moment of the day by calling "withTimeAtStartOfDay".
DateTime someMonthsAgo = now.minusMonths( countMonths ).withTimeAtStartOfDay();
DateTime dateAdded = new DateTime( 2013, 5, 6, 7, 8, 9, timeZone  ); // Arbitrary values for example.

// If 'dateAdded' happened prior to our target date-time 'someMonthsAgo', the pack of eggs is expired.
Boolean isEndOfLine = dateAdded.isBefore( someMonthsAgo );

转储到控制台...

System.out.println( "now: " + now );
System.out.println( "someMonthsAgo: " + someMonthsAgo );
System.out.println( "dateAdded: " + dateAdded );
System.out.println( "isEndOfLine: " + isEndOfLine );

运行时...

now: 2014-01-08T21:36:11.179+01:00
someMonthsAgo: 2013-11-08T00:00:00.000+01:00
dateAdded: 2013-05-06T07:08:09.000+02:00
isEndOfLine: true

0
投票

日历文档中所述 您不应该依赖compareTo 返回的数字 - 您只知道如果它大于 0,则原始日期更大。

因此创建一个新日期(过去的 x 个月)并与该日期进行比较。


0
投票

如果参数表示的时间等于此 Calendar 对象表示的时间,则该方法返回 0;或小于 0 的值(如果此日历的时间早于参数表示的时间);或者如果此日历的时间晚于所表示的时间,则为大于 0 的值。

    import java.util.*;

    public class CalendarDemo {

       public static void main(String[] args) {

          // create two calendar at the different dates
          Calendar cal1 = new GregorianCalendar(2015, 8, 15);
          Calendar cal2 = new GregorianCalendar(2008, 1, 02);

          // compare the time values represented by two calendar objects.
          int i = cal1.compareTo(cal2);

          // return positive value if equals else return negative value
          System.out.println("The result is :"+i);

          // compare again but with the two calendars swapped
          int j = cal2.compareTo(cal);

          // return positive value if equals else return negative value
          System.out.println("The result is :" + j);

       }
    }

0
投票

这是可行的解决方案。使用 JUNIT 进行测试以确认结果。

public Boolean isEndOfLine() {
    Calendar today = Calendar.getInstance();
    today.add(Calendar.MONTH, -END_OF_LINE);
    return today.compareTo(dateAdded) >= 0;
}

我使用 add 方法减去了今天的

END_OF_LINE
。注意第 3 行的负号。然后我比较一下它是否大于 0。感谢您的所有建议。


0
投票

避免遗留类

您正在使用现在已成为遗留的糟糕的日期时间类。它们被 JSR 310 中定义的现代 java.time 类取代,并内置到 Java 8+ 中。

切勿使用

Calendar
Date
SimpleDateFormat

java.time

仅使用 java.time 类来进行日期时间工作。

要确定年龄,您需要获取今天的日期。要确定今天,您需要指定时区。对于任何给定时刻,全球各地的时间和日期都会因时区而异。

LocalDate
表示仅限日期的值。

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

获取相关日期。

LocalDate then = LocalDate.of( 2024 , Month.JANUARY , 23 ) ;

将年龄计算为

Period

Period period = Period.between ( then , today ) ;

或者只计算过去的月份

long months = ChronoUnit.MONTHS.between ( then , today ) ;
© www.soinside.com 2019 - 2024. All rights reserved.