Javaの日付処理。何たるサーガか。昔、元のDateクラスが素直に動くはずだと信じていた——シンプルなタイムスタンプ、余計なドラマなし。ところがY2Kパニックと奇抜なメソッド群で大爆発。オラクルの先達どもがCalendarを救世主としてねじ込んできた。悪くない試みだが、どんより重い。java.time.LocalDateが3度目の正直として君臨し、鉄壁の解決策と祭り上げられた。だが、そうはいかない。完璧じゃない。
これで一変か? 冗談。このAPIは頭痛の種を一つ置き換えただけだ。月名を取るたび、毎回-1を引かされる羽目になる。得したのは誰だ? 深夜2時に配列インデックスエラーで睨むお前じゃない。
見てくれ、俺はアプレット戦争時代からJavaを取材してる——Sun、オラクル、今のEclipseによる管理権争いを20年眺めてきた。日付処理は常にこの言語のアキレス腱だ。タイムゾーンは政治家みたいに揺らぎ、リープセカンドが忍び寄り、APIの各イテレーションがカオスを制覇したと大口叩く。LocalDate? モダンで不変、ISO準拠。紙の上では完璧。だがMonth.getValue()を覗くと、冷めた目で見てしまう。
JavaのLocalDate 月カウントが1から始まる理由は?
問題はここだ。LocalDate.now()を取ってみろ——元ネタの愚痴通り2026-04-07だ。getMonth().getValue()を呼べば、ばん! 4月で4。論理的だろ? ISO 8601に合ってる、1月が1。非開発者はうなずく。だがプログラマー? K&RのC以来、ゼロベース万歳の脳みそだ。
おなじみの月名配列——0に1月、1に2月——が突然ミスマッチ。getValue()でインデックス? 4月のはずが5月だ。定番のoff-by-one、我々の職業病。
日付: 2026-04-07 月 (val): 5月 月 (ord): 4月
これが元ネタのコードデモの直出力だ。4月7日に実行すればordinal()(0ベース、インデックス3)で正しく4月が出る。だがgetValue()? MESES[fecha.getMonth().getValue() - 1]みたいなハック必須。醜悪だ。そして新プロジェクトに染みつく。
ordinal()はまだ使える——神に感謝——1月=0を死守してる。だがなぜ中途半端なんだ? 車のオドメーターを1kmからスタートさせるようなもんだ。乗客は喜ぶが、メカニックは激怒。
待てよ——1ベースの方が実は優れてる?
表でいく。元ネタから借用、和訳済み:
| 方法 | 基準 | 例 | 考え方 |
|---|---|---|---|
| getValue() | 1 | 1月 == 1 | 直感的 |
| ordinal() | 0 | 1月 == 0 | 慣習 |
もっともだ。人間は1月を1と数える。小学生だってそう覚える。だがコード? Cのlocaltime()はtm_monを0で詰め込む。JavaScriptのDate.getMonth()? ゼロベース、表示で+1。Perl、PHPも同じ。老兵Calendar.get(Calendar.MONTH)も0-11。
既存のJavaコードを壊すか?
答えは短く:java.timeに移行すれば、微妙に壊れる。数十年にわたりコピペされた月名ハック? 死亡。ログに変なスペイン語の月(英語同等品も)がポップアップしてデバッグ祭り。Jakarta EE何とかへのアップグレードで、2025年Q2にStack Overflowの愚痴が爆増するぞ。
誰も突いてない視点:これはJava 5のEnum ordinal()論争の再来だ。当時、enumが数値捨ててリフレクションごっこ始めたら大騒ぎ。オラクルは何も学ばず。「純粋さ」——ISO準拠——を追い、実際の破壊を無視。儲かるのは? Red Hatの有償日付監査コンサル。オラクルのHotSpot JVM? どっちでも売れる。
修正コード? 簡単だが遍在。チュートリアル、ユーティリティクラス全部書き直し。エンタープライズJavaじゃ、日付が給与やコンプライアンスアプリに巣食うから、請求工数が増える。俺の冷笑:完璧だ。Java経済を回し続ける。
歴史を振り返ろう。C99のstruct tm:tm_mon=0-11、出力で+1。JavaScript ECMA-262:明示ゼロ。BASICの1ベース異端? COBOLの遺物、笑いもの。Javaは事実上のスタンダードに倣えばよかった。代わりに「革新」——直感優先。新人に優しく、ベテランに毒。
大局:タイムゾーンは相変わらずクソ
油断するな。LocalDateは時間を避ける——時、分、オフセットなし。誕生日にはいい。だがZonedDateTimeに繋げば? タイムゾーンデータ更新が遅れ、政府がDSTを気まぐれ変更。JavaのtzdbはIANA頼みだが、JAR肥大化待ったなし。3度目? まだ穴だらけの船を塞ぐだけ。
Javaの日付大改修を3回見てきた。各々が前のを「修正」し、5つの新バグを生む。予言:Java 25までにTimeAPI 4.0で0ベース月を遡及投入。GitHubイシュー山積みでな。覚えておけ。
どうする? オールドスクールならordinal()直行。ISO純粋主義ならgetValue()-1。もしくはラップしろ:MonthUtils.toArrayIndex(month)。だがすでに膨張言語に更なるごみ。
Javaは生き延びる——戦闘テスト済み、大企業のお気に入り。だがこれ? 無用な落とし穴。たとえ「モダン」APIでも、昨日の残骸か明日の後悔を運ぶ。
🧬 関連インサイト
- 詳細: Arkhein 0.1.0: Your AI, Your Hardware, No Billionaire Middleman
- 詳細: 90% Token Slash: One Dev’s Markdown Second Brain Built on Claude Code
よくある質問
JavaのLocalDate.getMonth().getValue()とは?
1月〜12月を1-12で返す、ISO準拠。用法:ゼロベース配列なら-1。
なぜJavaのMonth enumのgetValue()は1から?
人間の直感とISO 8601準拠のため。C/JS由来のプログラマーゼロベース習慣と激突。
Javaのjava.time APIはバグだらけか?
壊れてないが、月インデックスのoff-by-oneトラップを生む——3度目の挑戦、同じ喧嘩再び。