我将当前日期存储在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!!!");
我可以在日志中看到日历实例值,如日,月,年等。
它出了什么问题?
答案 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());
}
所以你需要检查:
正如您所见,equals方法在comaprable对象中需要相同的TimeZone
。
答案 2 :(得分:0)
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类。
使用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/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?