1. ホーム

[解決済み】Javaカレンダーで1月が0になるのはなぜ?

2022-03-26 22:19:10

質問

java.util.Calendar 1月は1月ではなく0月と定義されていますが、何か特別な理由があるのでしょうか?

そのことで混乱している人を多く見かけますが...。

どうすればいい?

これは、Javaの日付/時刻APIという、恐ろしい混乱の一部に過ぎないのです。何が問題なのかを列挙すると、とても長い時間がかかるでしょう(そして、私は問題の半分も知らないはずです)。確かに日付と時刻を扱うのは厄介ですが、とにかく大変なんです。

自分のために 城田時間 または、場合によっては JSR-310 .

EDIT: 理由については、他の回答にもあるように、古いCのAPIが原因かもしれませんし、すべてを0から始めるという一般的な感覚かもしれません...もちろん、1日から始まるということを除いてですが。オリジナルの実装チーム以外の人が本当に理由を述べることができるかどうかは疑問です。 なぜ の悪意のすべてを見るように、悪い決断がなされたのです。 java.util.Calendar そして、より良いものを見つけることです。

という一点。 0ベースのインデックスを使用することで、quot;名前の配列"のようなものが簡単になります。

// I "know" there are 12 months
String[] monthNames = new String[12]; // and populate...
String name = monthNames[calendar.get(Calendar.MONTH)];

もちろん、13ヶ月のカレンダーを取得するとすぐに失敗します。しかし、少なくとも指定されたサイズは期待通りの月数です。

これは 良い という理由ですが、これは a 理由...

EDIT: コメントとして、Date/Calendarの何が問題なのか、いくつかのアイデアを要求しています。

  • 意外なベース(Dateでは1900が年ベース。非推奨のコンストラクタであることは認めます。)
  • ミュータビリティ - イミュータブルな型を使用することで 大いに をより簡単に扱えるようになりました。
  • 不十分な型セット:あると嬉しいのは DateCalendar を別物として扱います。 しかし、quot;local" と "zoned" の値の分離は、日付/時刻と日付と時刻の分離と同様に、欠落しています。
  • 明確な名前のメソッドではなく、魔法の定数を使った醜いコードにつながるAPI
  • 推論が非常に困難なAPI - 再計算のタイミングなどに関するすべてのビジネス。
  • パラメータレスコンストラクタの使用により、デフォルトで "now" となり、テストしにくいコードとなる。
  • その Date.toString() 常にシステムのローカルタイムゾーンを使用する実装 (これは、これまで多くの Stack Overflow ユーザーを混乱させてきました)