日期不匹配

时间:2013-10-28 14:38:26

标签: java date time calendar

我有一个<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

5 个答案:

答案 0 :(得分:6)

您正在设置年,月和日 - 但这不会更改时间。内部时钟必须在两次调用Calendar.getInstance之间勾选,因此它们具有不同的“自Unix纪元以来的毫秒”值。

我个人建议使用Joda Time代替java.util.Calendarjava.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());