日历比较

时间:2014-03-03 11:33:08

标签: java android calendar

我将当前日期存储在SQLite DB中

created_at DATETIME DEFAULT CURRENT_TIMESTAMP

当我尝试比较Calendar对象时,它总是将对象显示为不相等。

这是我的代码。

  

从数据库字符串创建日历

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendarDB = Calendar.getInstance();
String date = "extracted only date (2014-03-03 for ex) from DB value ignoring time";
calendarDB.setTime(sdf.parse(date));
  

当前日历实例

Calendar calendarCurrent = Calendar.getInstance();
  

比较......我认为所有实例都不相同。

if(calendarDB.equals(calendarCurrent))
    Log.i(TAG, "equal!!!");
else
    Log.i(TAG, "Not equal!!!");

我可以在日志中看到日历实例值,如日,月,年等。

它出了什么问题?

3 个答案:

答案 0 :(得分:4)

Calendar.getInstance()不是单身人士。每次基于java.util.Calendar

创建Locale的不同实现的新实例

其次,如果你检查Calendar的等于方法,它会检查更多,而不仅仅是日期

public boolean equals(Object obj) {
    if (this == obj)
        return true;
try {
    Calendar that = (Calendar)obj;
    return compareTo(getMillisOf(that)) == 0 &&
    lenient == that.lenient &&
    firstDayOfWeek == that.firstDayOfWeek &&
    minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
    zone.equals(that.zone);
} catch (Exception e) {
    // Note: GregorianCalendar.computeTime throws
    // IllegalArgumentException if the ERA value is invalid
    // even it's in lenient mode.
}
return false;
}

如果你想比较2个日期,你可以做

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date one = new Date(); // one = calOne.getTime();
Date two = new Date(); //two = calTwo.getTime();
sdf.format(one).equals(sdf.format(two));

答案 1 :(得分:1)

这是因为Calendar等于方法与下一个字段比较:

@Override
public boolean equals(Object object) {
    if (this == object) {
        return true;
    }
    if (!(object instanceof Calendar)) {
        return false;
    }
    Calendar cal = (Calendar) object;
    return getTimeInMillis() == cal.getTimeInMillis()
            && isLenient() == cal.isLenient()
            && getFirstDayOfWeek() == cal.getFirstDayOfWeek()
            && getMinimalDaysInFirstWeek() == cal.getMinimalDaysInFirstWeek()
            && getTimeZone().equals(cal.getTimeZone());
}

所以你需要检查:

  • 米利斯
  • isLenient
  • 一周的第一天
  • 第一周的最短日子
  • 和时区

正如您所见,equals方法在comaprable对象中需要相同的TimeZone

答案 2 :(得分:0)

TL;博士

LocalDate.now( ZoneId( "Pacific/Auckland" ) )        // Get today’s date in a particular time zone.
    .isEqual(                                        // Test for equality against a `LocalDate` object to be retrieved from database.
        myResultSet.getObject( … , Instant.class )   // Retrieve a moment in UTC from the database, an `Instant` object.
            .atZone( ZoneId( "Pacific/Auckland" ) )  // Produce a `ZonedDateTime` to represent the same moment in time but with the wall-clock time of a particular region’s time zone.
            .toLocalDate()                           // Extract a date-only value, without time-of-day and without time zone.
    )

java.time

现代方法使用java.time类。

使用JDBC 4.2及更高版本,您可以直接与数据库交换java.time对象。不需要麻烦的Calendar课程,不需要单纯的字符串。

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

ZoneId应用到Instant以获得ZonedDateTime

ZonedDateTime zdt = instant.atZone( z ) ;

如果您只关心日期部分而不关心时间,请提取LocalDate

LocalDate ld = zdt.toLocalDate() ;

与当前日期比较。

LocalDate today = LocalDate.now( z ) ;
Boolean isSameDateAsToday = ld.isEqual( today ) ;

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?