【问题标题】:Java same Dates containing different time in milli seconds [duplicate]Java相同的日期包含以毫秒为单位的不同时间[重复]
【发布时间】:2014-05-19 10:23:18
【问题描述】:

我有两个日历对象,它们似乎包含相同的日期,但 compareTo() 方法返回 -1 结果,谁能解释这背后的原因。

调试两个日历对象,结果如下:

2014-06-01T00:00:00.000Z

对于两个日历对象,但 compareTo() 返回 -1。甚至两个日期的毫秒数也不同。

【问题讨论】:

  • 你能显示一些代码吗?
  • 可能是时区问题,但是这两个日期的毫秒是多少?
  • 日期 1 毫秒:1401561000000 日期 2 毫秒:1401595200000
  • 查看我的回答,了解如何忽略毫秒
  • @Hitesh 使用相关事实编辑您的问题,而不是附加为 cmets。

标签: java


【解决方案1】:

好吧,看看Calendar 代码(这是来自 JDK 1.7.0-13):

public int compareTo(Calendar anotherCalendar) {
    return compareTo(getMillisOf(anotherCalendar));
}

private int compareTo(long t) {
    long thisTime = getMillisOf(this);
    return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
}

很明显,如果两个Calendar 有不同的millis,那么按照第二种方法它们是不同的。

在任何情况下,您示例中的millis 不应同时代表2014-06-01T00:00:00.000Z,因此您的代码中还有另一个问题。试试这个:

Timestamp ts1 = new Timestamp( 1401561000000L );
Timestamp ts2 = new Timestamp( 1401595200000L );
System.err.println( ts1 );
System.err.println( ts2 );

输出:

2014-05-31 20:30:00.0
2014-06-01 06:00:00.0

干杯,

【讨论】:

  • 我从 UI 中获取了一个值并存储在 Date 对象中,其他值作为 Date 对象从 DB 中获取,并且两个日期对象都转换为日历对象。
  • 你是如何得到输出2014-06-01T00:00:00.000Z的?
  • 看起来像Date.toString
  • @staticx 不,它会以时区和年份结尾 (dow mon dd hh:mm:ss zzz yyyy)。我猜是Timestamp.toString() 之类的。
【解决方案2】:

毫秒数是 Java 中的“官方”时间。但是,由于各种原因,具有相同日期/时间的数字具有不同的毫秒数。那么正常的原因是时钟调整。例如。有时你必须增加一两秒来解释地球轨道的不规则性。另一个重要来源是当地区第一次进入 UTC 时,然后一些时区移动了几个小时。

这些东西还有一个共同的来源:DST。 当您转向夏令时时,这将每年发生两次,一方面有日期/时间不存在,因为它们被“跳过”,还有其他时间发生了两次,因为时钟在午夜,所以晚上 11 点到午夜在同一天发生两次。

【讨论】:

    【解决方案3】:

    如果您只想比较分钟而忽略毫秒或秒,请执行以下操作:

    你需要使用

    cal.set(Calendar.MILLISECOND, 0);
    

    也许还有

    cal.set(Calendar.SECOND, 0);
    

    如果你只需要分钟来匹配。


    快速解释发生了什么:

    JavaDoc for Calendar 声明:

    比较时间值(从纪元开始的毫秒偏移量) 由两个 Calendar 对象表示。

    所以您承认“.. 两个日期的长时间以毫秒为单位是不同的..”

    @JonSkeet 在这个question 中说:

    Calendar.setTime 采用 java.util.Date,它只是一个包装器 大约一个 long 表示自 Jan 午夜以来的毫秒数 1970 年 1 月,UTC。它不是“格式为 MM/dd/yyy” - 那是一个字符串 表示,而不是 java.util.Date。如果它碰巧打印一些东西 以 MM/dd/yyyy 格式输出,这正是 Date.toString 正在做的事情 对你来说 - 它本质上不是格式的一部分。

    这应该回答你关于发生了什么的问题。

    注意:java.util.Date 也有同样的问题。

    PS。很多人说使用 Joda Time,我听说它会在 Java 8 中使用,但我没有亲自尝试过。如果您要使用大量日期代码,我建议您使用它。

    【讨论】:

      【解决方案4】:

      我在 Date 而不是 Calendar 上调用了 compareTo 并得到了正确的结果。这可能是因为 Calendar 存储时区信息而 Date 对象没有。

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 1970-01-01
        • 1970-01-01
        • 2015-07-20
        • 2017-05-10
        • 1970-01-01
        • 2013-01-28
        相关资源
        最近更新 更多