我有一个<DDate, Integer>
的TreeMap。
DDate只包含月份和年份(月份为0索引,如Java,JAN = 0);
我的比较并没有回归正确的事情:
@Override
public int compareTo(DDDate o) {
Calendar cal1 = Calendar.getInstance();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.set(year, month, 1); // year is 2012, month is 1
Calendar cal2 = Calendar.getInstance();
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
cal2.set(o.getYear(), o.getMonth(), 1); // year is 2012, month is 1
Log.log("COMPARING: " + format.format(cal1.getTime())); // COMPARING: 20120101
Log.log("COMPARING: " + format.format(cal2.getTime())); // COMPARING: 20120101
Log.log((cal1.getTime().getTime())); // 1325413927678
Log.log((cal2.getTime().getTime())); // 1325413927679
Log.log("WILL RETURN: " + cal1.getTime().compareTo(cal2.getTime())); // WILL RETURN: -1
return cal1.getTime().compareTo(cal2.getTime());
}
为什么同一日期的两个Calendar对象存在差异? (1325413927678 vs 1325413927679)
谢谢!
仅供参考:这种方法可以使用一段时间,然后在某一点停止工作。
P.S。 - 我明白这是矫枉过正,我可以有一个更简单的比较,但请幽默我。
EDIT-FIX
使用JodaTime的LocalDate。
或者这样做:
Calendar cal1 = Calendar.getInstance();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.clear();
cal1.set(year, month, 1); // year is 2012, month is 1
答案 0 :(得分:6)
您正在设置年,月和日 - 但这不会更改时间。内部时钟必须在两次调用Calendar.getInstance
之间勾选,因此它们具有不同的“自Unix纪元以来的毫秒”值。
我个人建议使用Joda Time代替java.util.Calendar
和java.util.Date
- 这样您就可以代表您真正感兴趣的内容,例如LocalDate
。< / p>
答案 1 :(得分:2)
因为你是在两个不同的时间制作它们。
Calendar cal1 = Calendar.getInstance(); // time now
cal1.setTimeZone(TimeZone.getTimeZone("UTC")); // time ticking
cal1.set(year, month, 1); // year is 2012, month is 1 // time ticking
Calendar cal2 = Calendar.getInstance(); // time two ticks later
您已经更改了日期,月份和年份,但是小时分钟和秒数保持不变并继续移动和继续。
如此处所述
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#set(int,int,int,int,int)
保留其他字段值,您应该使用clear()将它们设置为零。另外,如果乔恩推荐,我会说使用Joda时间会好得多。
答案 2 :(得分:0)
您应该将日历正确地初始化为“没有时间”(0刻度),这应该可以解决问题。
cal1.setTime(new Date(0));
cal1.set(year, month, 1);
答案 3 :(得分:0)
在设置日期前尝试使用clear()方法:
final Calendar cal1 = Calendar.getInstance();
cal1.clear();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.set(2012, 1, 1); // year is 2012, month is 1
final Calendar cal2 = Calendar.getInstance();
cal2.clear();
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
cal2.set(2012, 1, 1); // year is 2012, month is 1
cal1.getTime().compareTo(cal2.getTime()); // Returns 0
答案 4 :(得分:0)
Jon Skeet的回答是正确的。
以下是一些示例代码,说明如何使用Joda-Time进行日期比较。在Joda-Time中更容易,而不是Java捆绑的日期/日历类。只需3行代码即可实例化和比较。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// New DateTime instance with default time zone. For specific zone, call "withZone()" method.
org.joda.time.DateTime dateTimeX = new org.joda.time.DateTime();
org.joda.time.DateTime dateTimeY = new org.joda.time.DateTime(2012, 1, 1, 0, 0); // First of January.
// To compare the date only while ignoring the time, set identical time component on both.
// Call withTimeAtStartOfDay() to set same time value.
Boolean isSameDate = dateTimeX.withTimeAtStartOfDay().isEqual(dateTimeY.withTimeAtStartOfDay());