Node 24のIntlは明治元年を1868年9月8日から始める|CLDR 47と48の差
和暦・西暦 変換 は、西暦の日付を令和・平成・昭和・大正・明治に変換するブラウザ内ツールである。改元日をまたぐ境目を日付単位で判定するために、改元日の表を自前で持っている。
一方 JavaScript には Intl.DateTimeFormat に ja-JP-u-ca-japanese を渡す方法があり、和暦の表示はこれで済むことが多い。では自前の表は要らないのか。両方を同じ日付で動かして比べたところ、明治の始まりだけが一致しなかった。
Intl の和暦は ICU と CLDR のデータで動く
Node.js の Intl は ICU(International Components for Unicode)で実装されていて、ICU の改元日は CLDR(Common Locale Data Repository)の calendarData から来る。手元の Node が持つ版は process.versions で分かる。
1 | |
CLDR 47 の calendarData.json(cldr-core/supplemental/calendarData.json・タグ 47.0.0)で、japanese の明治は次の値である。
1 | |
大正以降は 1912-07-30 / 1926-12-25 / 1989-01-08 / 2019-05-01 で、これは改元日の西暦(グレゴリオ暦)そのものだ。ところが明治の 1868-09-08 は西暦の日付ではない。
1868-09-08 は旧暦の日付をそのまま読んだ値
明治改元の詔は 慶応4年9月8日 に出た(国立公文書館「日本のあゆみ」)。この「9月8日」は当時の暦(天保暦・太陰太陽暦)での日付で、グレゴリオ暦に直すと 1868年10月23日 になる(Wikipedia「明治」)。
CLDR 47 の 1868-09-08 は、旧暦の「9月8日」を西暦の 9月8日として書いた値である。この件は CLDR のチケット CLDR-11375 として直され、CLDR 48 の同じファイル(main ブランチ)では次のようになっている。
1 | |
.NET 11 も同じ理由で JapaneseCalendar.MinSupportedDateTime を 1868-09-08 から 1868-10-23 に変更していて、Microsoft Learn の破壊的変更の記事が CLDR-11375 を理由として挙げている。
つまり 2026年10月時点の Node 24(CLDR 47)では、1868年9月8日から10月22日までの45日間が「明治」と表示されるが、歴史上はまだ慶応4年である。
もう1つの読み方: 慶応4年は年初に遡って明治元年
話はここで終わらない。明治改元の詔は「慶応四年を改めて明治元年と為す」と書いていて、改元の効力は 慶応4年の元日(グレゴリオ暦 1868年1月25日)に遡る。年の途中で呼び名が変わるのではなく、その年全体が明治元年になった(国立公文書館・Wikipedia とも同じ記述)。この遡及は明治だけで、大正・昭和・平成・令和は改元日の当日から切り替わる。
和暦ツールの表は、この遡及のほうを採っている。
1 | |
だから「1868年3月1日」は、ツールでは明治元年、Intl では慶応4年になる。どちらも根拠はあるが、何を聞かれているかで答えが変わる。書類の年号を書くなら「慶応4年の出来事は明治元年の出来事」で、改元の詔が出た瞬間を聞くなら 10月23日である。ツールが 1868-01-25 を採っているのは、書類の年号記入という用途に合わせたためだ。
実際に試す
Node.js 24.11.1(ICU 77.1・CLDR 47.0)で確認した。ツールの表による判定と、Intl の判定を同じ日付で並べる。
1 | |
実行結果:
1 | |
- 大正・昭和・平成・令和の境目は両者で一致する。
- Intl が明治に切り替わるのは
1868-09-08。CLDR 48 を積んだ ICU なら1868-10-23になるはずで、process.versions.cldrが 48 以上の Node で同じコードを流せば確かめられる。 1868-01-25から1868-09-07の区間は、ツールは明治元年、Intl は慶応4年を返す。
なお year: "numeric" でも Intl は元年を 1 で出す(month: "long" を指定したときは 令和元年 と出た)。元年表記が要るなら formatToParts で year の値を見て自分で置き換える。
「和暦を Intl に任せる」と決めるときの確認点
process.versions.cldrを記録する。 明治の境目は CLDR 47 と 48 で違う。同じコードがサーバとブラウザで別の答えを出し得る。- 明治元年の扱いを決める。 1868年1月25日から10月22日までを明治と呼ぶかどうかは、データではなく用途の判断である。年号記入なら遡及(表)、歴史上の呼称なら改元日(CLDR 48)。
- 令和以前の境目は Intl で問題ない。 平成31年4月30日と令和元年5月1日、昭和64年1月7日と平成元年1月8日は、どちらの方法でも一致した。
参照: CLDR calendarData.json(47.0.0) / CLDR calendarData.json(main・CLDR 48) / .NET 11 破壊的変更: Japanese Calendar minimum supported date corrected / 国立公文書館 日本のあゆみ: 改元の詔となる / 和暦・西暦 変換(hashitosystem)