java - CompareTo(GregorianCalendar c) 的奇怪行为

标签 java compareto

你能告诉我为什么下面的代码:

int a = new GregorianCalendar(2015,3,31,7,45).compareTo(
        new GregorianCalendar(2015,4,1,7,45);
System.out.println(a);

打印出0?

有没有办法让它正常工作?

PS:我需要按日期对字符串进行排序,我使用这个比较器:

array.sort(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        GregorianCalendar cal1 = new GregorianCalendar(Integer.parseInt(o1.replaceAll(p, "$7")),
                Integer.parseInt(o1.replaceAll(p, "$6")), Integer.parseInt(o1.replaceAll(p, "$5")),
                Integer.parseInt(o1.replaceAll(p, "$8")), Integer.parseInt(o1.replaceAll(p, "$9")));
        GregorianCalendar cal2 = new GregorianCalendar(Integer.parseInt(o2.replaceAll(p, "$7")),
                Integer.parseInt(o2.replaceAll(p, "$6")), Integer.parseInt(o2.replaceAll(p, "$5")),
                Integer.parseInt(o2.replaceAll(p, "$8")), Integer.parseInt(o2.replaceAll(p, "$9")));
        return cal1.compareTo(cal2);
    }
});

它使用正则表达式,但排序正确,只有提供的日期排序不正确。

最佳答案

您正在将“4 月 31 日”与 5 月 1 日进行比较。 没有 4 月 31 日,所以无论如何都会延期到 5 月 1 日。 (好吧,抛出异常会更有意义,但是嘿...这远不是 Calendar 中最糟糕的 API 设计。)

我强烈建议使用 SimpleDateFormat 来解析日期/时间值的字符串表示形式,而不是自己做。除了其他任何事情之外,SimpleDateFormat“知道”Java 中的月份是从 0 开始的......这是您遇到的基本错误。我怀疑代码也会更具可读性。

您真的需要将集合保留为字符串集合吗?如果它们只是日期,请将其转换为某种日期类型的集合(最好使用 Joda Time 或 Java 8 的 java.time 包)。如果它们类似于包含日期和其他信息的日志条目,请首先将它们转换为该信息的表示形式。无论哪种方式,您都会得到一个集合,它可以更自然地表示它所包含的信息。

关于java - CompareTo(GregorianCalendar c) 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29395060/

相关文章:

java - 使用 OData4J 检索 OData 数据时出错

Java 将一个类转换为另一个类

java - 使用 ArrayList 和 CompareTo 对文件的结果进行排序

java - 无法解决 makeText 方法

java - 如何在RecyclerView中每3个项目放置一次原生广告?

java - 将系统应用程序的文件复制到另一个位置时出错

java - compareTo 是否有某种预启动延迟?

java - 在Java中以通用方式实现comprable方法进行排序

java - 原始类型双重错误

java - 与经济数据的比较逻辑错误 - 比较方法违反了其一般契约