2013-02-07 17 views
11

想像できるところでは、ソフトウェアでY2Kスタイルのバグが発生しました。奇妙なことに、1年ごとの計算は2年しか行われないので、トラブルシューティングの方法がわかりません。Java日付の年計算が2日間で年を切っている

出力:

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年の最後の2日間は2013年の第1週にありました。通常は、「週の年」指定子(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を使用していると仮定しています。上記

コードスニペットはSimpleDateFormat("dd-MMM-YYYY")としてjava 1.6では動作しませんあなたがyyyy代わりのYYYYを使用する必要がありますjava.lang.IllegalArgumentException(YYYYはjava 1.6では使用できません)

が発生します。

Y -> week-year 
y -> year 

here

EDIT

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は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")、JVMの現在のタイムゾーン設定の場合はZoneId.systemDefault())。
  • 私は、旧式のCalendarクラスを使用しているコードよりも、コードを簡単かつ簡単に見つけることができます。これは新しいクラスの典型です。
  • 私はuuuuを年間使用しました。 (小文字)でも動作しますが、共通の時代(AKA BC)の前には何年も違いがあります。
関連する問題