注:本記事は2017年1月時点の情報に基づきます。本記事の最後に最新の情報を追記していますので、そちらもご確認ください。

旧バージョンの開発環境で作成したアプリのWindows10対応やマイグレーションを行う場合に、そのアプリで和暦を取り扱っている場合には、元号改正に伴う対応を考える必要があります。しかし元号改正に伴う対応は個々のアプリケーションごとに前提条件等が異なりますので一律に話を進めることができません。

また、アプリケーション側以外の部分での対応が必要なものもあります。たとえば、1文字で元号を表す文字(㍾、㍽、㍼、㍻)の対応が挙げられます。新しい元号が収録されるかどうかはUnicodeに関わる話ですし、それを実際に取り扱う場合にはフォントの対応やIME辞書への収録が必要となります。

このようにアプリケーション側だけでは対応できない部分については一旦置いておき、この記事ではターゲットをもっと絞り、西暦と和暦の変換に関する内容をご案内致します。

Windows OS側の対応

元号が改正された場合は、Windowsでは基本的にはレジストリへの新しい元号の登録によって対応しますDelphi/C++BuilderはOSの機能やAPIを使っており、暦の処理に独自の実装を行ってはいません。

レジストリ設定に関するマイクロソフトのドキュメントは以下のようなものがあります。

https://msdn.microsoft.com/en-us/library/windows/desktop/ee923790.aspx?f=255&MSPPError=-2147217396

これに基づくと、たとえば 2017年1月1日から元号が “改元” に変わるという設定は以下のように書けます。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras]

"2017 01 01"="改元_改_Kaigen_K"

この設定の結果は PowerShell で以下のように実行することでも確認できます。

PS C:\> $path = "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras"

PS C:\> Get-ItemProperty $path

1868 01 01 : 明治_明_Meiji_M
1912 07 30 : 大正_大_Taisho_T
1926 12 25 : 昭和_昭_Showa_S
1989 01 08 : 平成_平_Heisei_H
2017 01 01 : 改元_改_Kaigen_K

PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese

PSChildName : Eras
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry

PS C:\> $CultureInfo = New-Object system.Globalization.CultureInfo("ja-JP");
PS C:\> $CultureInfo.DateTimeFormat.Calendar = New-Object System.Globalization.JapaneseCalendar
PS C:\> $CurrentDate = Get-Date
PS C:\> $CurrentDate.ToString("ggyy年MM月dd日",$CultureInfo)

改元01年01月19日

PS C:\>

テストを終えたらレジストリの設定を元に戻すことをお忘れなく。このようにレジストリだけで新しい元号に対応できるので、改元の際には Windows Update によって新しい元号の情報が追加されることになるでしょう。

上記レジストリの値を利用可能な西暦→和暦変換

FormatDateTime, DateToStr, DateTimeToStr を実行すると、上記レジストリの値を参照しての西暦→和暦変換が行われます。

上記レジストリの値を利用可能な和暦→西暦変換

TFormatSettingsでShortDateFormatに元号を含む書式を指定した上で、StrToDate を使えば改元後の和暦の日付を西暦に変換できます。

var
  JPNEraFormat: TFormatSettings;
  strDate: String;
  timestamp: TDateTime;
begin
  strDate := '改元1年1月19日';
  JPNEraFormat := TFormatSettings.Create('ja-JP');
  JPNEraFormat.ShortDateFormat := 'ggee/m/d';

  strDate := StringReplace(strDate, '年', '/', []);
  strDate := StringReplace(strDate, '月', '/', []);
  strDate := StringReplace(strDate, '日', '', []);

  timestamp := StrToDate(strDate,JPNEraFormat);
end

このように日付の文字列に年、月、日を含む場合は / に置換するなどの前処理を行ってから StrToDate を実行することに注意が必要です。

なお、VarToDateTime で和暦→西暦変換を実装すればコードの量はもっと少なく済むのですが、残念なことに VarToDateTime は前述のレジストリを参照していません。改正後の元号を用いた日付を渡すと例外が発生します。ただしVarToDateTime の機能自体はOS側の機能に依存しています。Windows で日付文字列を内部データに変換する処理は複数の関数があるのですが、関数によって挙動が違うようです。これは今後の Windows Update によって対応がなされるかもしれません。

元号改正に関する話は元号改正に伴うユースケースの洗い出しを行うことから始めておzき、アプリケーション側で対応できない箇所が存在した場合に備えて対応方針を計画して頂くのがよいでしょう。


2019年4月17日追記

2019年4月10日以降の Windows Update により Win32 API での西暦→和暦変換は、その時点のシステムクロックの日付で有効な元号に対して行うように変わっているため、Delphi や C++Builder でこの記事を参考に令和の和暦との変換を確認する場合は、システムの日付を2019年5月1日以降に変更して実施してください。


新元号「令和」への改元に伴う様々な留意点は経済産業省のウェブページ 改元に伴う企業等の情報システム改修等への対応 に掲載の情報もご確認ください。また Windows アプリケーションの挙動は Windows Update の適用状況に影響を受けるため、マイクロソフト社のウェブページ 新元号への対応について もご確認ください。

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder. Design. Code. Compile. Deploy.

Start Free Trial   Free Delphi Community Edition   Free C++Builder Community Edition   Upgrade Today