YEARのカレンダーを設定しました

私は次のコードを試しました:

Calendar c1 = Calendar.getInstance();
c1.set(Calendar.YEAR, 0);
c1.set(Calendar.DAY_OF_YEAR, 1);
Date d1 = c1.getTime();

Calendar c2 = Calendar.getInstance();
c2.setTime(d1);
c2.set(Calendar.YEAR, 2001);
c2.set(Calendar.DAY_OF_YEAR, 1);
System.out.println(c2.getTime().toString());

Calendar c3 = Calendar.getInstance();
c3.set(Calendar.YEAR, 2000);
c3.set(Calendar.DAY_OF_YEAR, 1);
Date d2 = c3.getTime();

Calendar c4 = Calendar.getInstance();
c4.setTime(d2);
c4.set(Calendar.YEAR, 2001);
c4.set(Calendar.DAY_OF_YEAR, 1);
System.out.println(c4.getTime().toString());

結果は次のとおりです。

Wed Jan 01 23:47:00 CET 2001
Mon Jan 01 23:47:00 CET 2001

なにが問題ですか? YEARを設定するためにカレンダーをこのように使用するべきではありませんか?

11

2 答え

年は時代に比例しています。年を0以下の値に設定すると、カレンダーは時代を(ADからBCまたはBCからADに)切り替えることによって自動的にこれを修正します。この動作は、他のフィールドからよくわかります。例えば。月を何か負の値に設定すると、それに応じて年が減ります。

これらの訂正は個別に行われるのではなく、通常は getTime()を呼び出して結果の日付を読み出すときにすべて一度に行われます。

Calendar c1 = Calendar.getInstance();//August  16th, 2012 AD
c1.set(Calendar.YEAR, 0);            //August  16th,    0 AD
c1.set(Calendar.DAY_OF_YEAR, 1);     //January  1st,    0 AD
Date d1 = c1.getTime();              //January  1st,    1 BC (corrected)

Calendar c2 = Calendar.getInstance();
c2.setTime(d1);
c2.set(Calendar.YEAR, 2001);         //January  1st, 2001 BC
c2.set(Calendar.DAY_OF_YEAR, 1);
System.out.println(c2.getTime());    //prints "Wed Jan 01 05:35:00 CET 2001"
                                     //because 01/01/2001 BC was a Wednesday

したがって、2001年に設定する代わりに、-2000に設定する必要があります(0年が存在しないため)。あるいは、明示的に時代を設定することができます:

c2.set(Calendar.ERA, GregorianCalendar.AD);

この「バグ」を解決する別の方法は、完全な日付が設定される前に 時間を読み込まないことです。

Calendar c1 = Calendar.getInstance();//August  16th, 2012 AD
c1.set(Calendar.YEAR, 0);            //August  16th,    0 AD
c1.set(Calendar.DAY_OF_YEAR, 1);     //January  1st,    0 AD
c1.set(Calendar.YEAR, 2001);         //January  1st, 2001 AD
System.out.println(c1.getTime());    //prints the expected date

日付の時代を出力するには、 SimpleDateFormat のパターンで "G"を使用できます。

new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy G").format(c2.getTime())
// "Wed Jan 01 05:35:00 CET 2001 BC"
14
追加された

どちらの場合も、出力を印刷する直前に、2001年に設定します。どちらの場合も、出力はその年を反映しています。あなたは別の出力を期待していましたか?

3
追加された
笑!何?ええ、それは私によって得た。あなたがバグを見つけたように私に見える。
追加された 著者 phatfingers,
異常行動は、c1年が0に設定されている(または負の年であることが判明している)ことに関連しているようです。肯定的な年にそれを試してみると、私は正しい月曜日の結果しか見ていない。
追加された 著者 phatfingers,
水曜日対月曜日。さらにMILLISECとSECを0に設定して2つの日付を比較すると、結果は等しくなりません。もともと私の目的は、時刻部分だけを比較するためにDateTimeオブジェクトの日の部分を正規化することでした。
追加された 著者 differenziale,