2015-04-01 108 views
0

你能告诉我,为什么fillowing代码:怪异的行为

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

你在比较“4月31日”和5月1日。有没有4月31日,所以它无论如何都滚动到5月1日。 (好吧,这会更有意义,只是抛出一个异常,但嘿...这从Calendar最差的一块API设计的远远。)

我会强烈建议使用SimpleDateFormat解析日期字符串表示/时间值,而不是自己做。除了其他任何东西,SimpleDateFormat“知道”在Java的月份是基于0的......这是你犯下的基本错误。我怀疑代码也会更易读。

您是否确实需要将集合保留为字符串集合呢?如果它们是只是日期,请将其转换为某种日期类型的集合(理想情况下使用Joda Time或Java 8的java.time包)。如果它们像日志条目那样有日期而且还有其他信息,那么将它们转换成第一个表示。无论哪种方式,你都有一个更自然地代表它所拥有的信息的集合。

+0

Oooh,这里是诀窍,Java中的月份是基于0的......这真的很奇怪。 感谢您为我开放这个技巧! – 2015-04-01 15:46:10

+0

@DenisYakovenko:这是直接的问题 - 但请不要只是把这个教训带走。还有其他方法可以非常显着地改进这个代码... – 2015-04-01 15:46:46

+0

好吧,数组排序只是任务的一小部分,我有义务使用Java 7,但我会坚持您的建议) 什么是你的意思是“非常显着”?你的意思是以这种方式使用正则表达式太贵了? – 2015-04-01 15:48:42

0

为什么不直接在日历上拨打.getTime()并按日期排序?或.getTime().getTime()并排序多头?