2015-04-01 148 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()並排序多頭?