銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

.NET Coreにおける新元号対応について

MVPグローバルサミットに参加している最中に新元号対応が気になったのでマイクロソフトのエンジニアに聞いてみたら、publicなissueで議論しようということだったので立ててみました。するとあっという間に回答が来たので、日本語で簡単にまとめてみようと思います。

github.com

なお、ここでの新元号対応は、新元号が追加された後、どんなライブラリが更新されたら.NET Coreにおいて新元号が適用されるかという話であり、だれがいつそのライブラリを更新するかという話ではありません。

.NET Core における元号

.NET Coreは国際化対応の一貫として日本の元号にも対応しています。具体的にはSystem.Globalization.JapaneseCalendarが日本の元号に対応しているカレンダーになります。元号という概念は、ロケールによらずeraという概念で管理しているのですが、そもそも.NET Coreが対応しているロケールのうちこのeraを複数持っているのはJapaneseCalendarとそれに依存いているJapaneseLunisolarCalendar (太陰暦) となっています。従って、.NET Coreのライフサイクルの間に追加されるイベントも、現時点での日本の元号でしか発生しないということになります。

github.com

.NET Core on Windowsの場合

さて、.NET Coreで新元号が対応可能になるトリガーはWindowsとUnix(LinuxとMacOS)でことなります。これは、カレンダーの実装がプラットフォームごとにことなるものに依存しているためです。Windowsの場合は、.NET Frameworkと同じくレジストリに依存しています。つまりレジストリが更新されれば、そのOS上で動く.NET Coreのアプリは新元号に対応することになります。原理的には、ビルドしたときのマシンが対応していなくとも、もしくは対応する前にビルドした古いバイナリでも、レジストリに追加されたマシンで実行すれば新元号に対応するはずです。

https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd317805%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396msdn.microsoft.com

また、レジストリの追加に関してはすでにテストケース対応済とコメントされています。

.NET Core on Unixの場合

一方、Unixの場合、元号を含んだ国際化の情報はlib-icuというライブラリに依存いています。

github.com

従って、新元号に対応したICU ライブラリに更新すれば、.NET Coreアプリも対応することになります。対応したライブラリがリリースされたら.NET Coreでもテストを追加するとコメントされています。

それ以外

.NET Coreには一応、Windowsではレジストリからの取得に、UnixではICUライブラリからの取得に失敗した場合のフォールバックとして、ソースコード中にハードコードされた元号情報が含まれています。

[github.com

一応と書いたのは、これはあくまで何か想定しないことが起きた時のためのもので、コメントによるとこのハードコードされた情報が利用されることは基本的に想定していないということです。従って、この情報が使われるユースケースは考えなくていいわけなんですが、もし使われることがあるとすると、フレームワーク依存とself-containedで挙動が変わることが想定されます。フレームワーク依存型の場合、実行する環境の.NET Coreランタイムのハードコーティング部分が新元号対応済であれば、このフォールバックが働いた場合でも新元号に対応します。一方、self-containedの場合、ラインタイムもアプリと一緒に含まれているため、新しい元号に対応していない状態でビルドしたアプリは、このフォールバックの仕組みが働く限り永遠に新しい新元号に対応することはありません。

まとめ

.NET Coreに新元号対応を期待する場合、Windowsであればレジストリの更新、UnixであればICUライブラリの更新が行われることが前提条件となります。