2013-02-07 35 views
11

如果您能想象,這會在我的軟件中導致Y2K風格的錯誤。奇怪的是,一年的計算只發生在一年中的兩天,我不太確定如何排除故障。Java日期年計算在兩天內每年都會關閉

輸出:

03-Jan-2013 
02-Jan-2013 
01-Jan-2013 
31-Dec-2013 ** strange 
30-Dec-2013 ** strange 
29-Dec-2012 
28-Dec-2012 
27-Dec-2012 
26-Dec-2012 
25-Dec-2012 

我不知道其中的Java日期公用事業的一部分可能會導致這樣的錯誤。

代碼(由於測試是如此之小,我包括一個完整的工作程序):

import java.util.Calendar; 
import java.util.Date; 
import java.text.SimpleDateFormat; 

public class DateT { 

     private static String getFormattedBackscanStartTime(int days) { 

       SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-YYYY"); 
       Calendar workingDate = Calendar.getInstance(); 
       workingDate.add(Calendar.DATE, -1 * days); 

       String formattedStartTime = dateFormat.format(workingDate.getTime()); 
       return formattedStartTime; 
     } 

     public static void main(String args[]) { 

       for(int i = 35; i < 45; i++) { 
         System.out.println(getFormattedBackscanStartTime(i)); 
       } 
     } 
} 
+0

我想你會從中受益。 https://forums.oracle.com/forums/thread.jspa?threadID=2096000 – Achrome

+2

請注意''Calendar'&'SimpleDateFormat'類現在是[legacy](https://en.wikipedia.org/wiki/遺留系統)。支持[java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html)類。現代方法改用'LocalDate','ZoneId'和'DateTimeFormatter'類。 –

回答

26

這就是問題所在:

"dd-MMM-YYYY" 

YYYY是爲期一週的年,而不是日曆年。您需要改爲yyyy

2012歷年的最後兩天是2013年第一週的第一週。您通常應該只將週年與「每週的年份」說明符(w)結合使用。

2

問題在於你的日期格式字符串 - 年應該是yyyy而不是YYYY

如果您在每次循環打印workingDate.getTime()的價值,你會看到它的預期值:

Thu Jan 03 11:19:33 EST 2013 
Wed Jan 02 11:19:33 EST 2013 
Tue Jan 01 11:19:33 EST 2013 
Mon Dec 31 11:19:33 EST 2012 
Sun Dec 30 11:19:33 EST 2012 
Sat Dec 29 11:19:33 EST 2012 
Fri Dec 28 11:19:33 EST 2012 
Thu Dec 27 11:19:33 EST 2012 
Wed Dec 26 11:19:33 EST 2012 
Tue Dec 25 11:19:33 EST 2012 

因此,問題就出在SimpleDateFormat的用法。

+0

+1調試步驟 – djechlin

1

您需要在年份中使用小寫字母y。試試這個:

SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); 
5

我假設你正在使用java 1.7

中的代碼片段將不會java 1.6工作作爲SimpleDateFormat("dd-MMM-YYYY")將引發一個java.lang.IllegalArgumentException(YYYY不可用java 1.6

您需要使用yyyy,而不是YYYY

Y -> week-year 
y -> year 

here

編輯

yyyy偉大工程:

$ java DateT 
03-Jan-2013 
02-Jan-2013 
01-Jan-2013 
31-Dec-2012 
30-Dec-2012 
29-Dec-2012 
28-Dec-2012 
27-Dec-2012 
26-Dec-2012 
25-Dec-2012 
+0

+1注意它只有1.7。 – djechlin

1

爲了完整起見,這裏使用LocalDate(現代的答案作爲評論推薦蓬蒿布爾克)。

import java.time.LocalDate; 
import java.time.format.DateTimeFormatter; 
import java.util.Locale; 

public class DateT { 

    private static DateTimeFormatter dateFormatter 
      = DateTimeFormatter.ofPattern("dd-MMM-uuuu", Locale.US); 

    private static String getFormattedBackscanStartTime(int days) { 
     return LocalDate.now(ZoneId.systemDefault()).minusDays(days).format(dateFormatter); 
    } 

    public static void main(String args[]) { 
     for(int i = 155; i < 165; i++) { 
      System.out.println(getFormattedBackscanStartTime(i)); 
     } 
    } 
} 

運行這個今天我

04-Jan-2017 
03-Jan-2017 
02-Jan-2017 
01-Jan-2017 
31-Dec-2016 
30-Dec-2016 
29-Dec-2016 
28-Dec-2016 
27-Dec-2016 
26-Dec-2016 

有幾件事情需要注意:

  • 給出明確的語言環境來格式化程序來控制輸出的的langauge。即使你只是通過Locale.getDefault()你告訴讀者,你已經考慮了區域設置並做出了決定。
  • 同樣給明確的時區LocalDate.now()告訴讀者你已經做出了決定(例如ZoneId.of("America/New_York")爲特定時區; ZoneId.systemDefault()爲JVM的當前時區設置)。
  • 我發現代碼比使用老式Calendar類的代碼更簡單,更直接。這對於較新的課程來說是典型的。
  • 我已使用uuuu一年。 yyyy(小寫字母)也可以使用,在共同時代(AKA BC)之前只會有差別。