江戸時代の元号をレジストリィに足したが.NETのJapaneseCalendar Classの下限値は西暦1868年9月8日だったので和暦変換できなかった話

タイトルが全ての出落ち記事です

何がやりたかったのか

令和のレジストリィがWindows Updateで提供されたりされなかったり、一緒に文字幅が変わる修正が提供されてGUIがぶっ壊れたりしている今日この頃、皆様いかがお過ごしでしょうか

自分は思い付きでトラブルを増やすべく、江戸時代の元号Windows 10のレジストリィに追加してどうなるか試してみることにしました

レジストリィの場所とデータの形式

元号の情報を持っているレジストリィは HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras にあります

内容をPowerShellで取得するとこんな感じです

PS > Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';

    Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese

Name                           Property
----                           --------
Eras                           1868 01 01 : 明治_明_Meiji_M
                               1912 07 30 : 大正_大_Taisho_T
                               1926 12 25 : 昭和_昭_Showa_S
                               1989 01 08 : 平成_平_Heisei_H
                               2019 05 01 : 令和_令_Reiwa_R

このレジストリィの仕様は見当たらなかったのですが、直感的に値の名前を開始年月日を yyyy MM dd の形で持ち、値は元号の漢字表記、漢字表記の1文字目、ヘボン式ローマ字表記、ヘボン式ローマ字表記1文字目を _ を区切り子として持っているようです

江戸時代まで遡って元号レジストリィに登録してみる

元号一覧 (日本) - Wikipedia を参考に江戸時代までのCSVを用意して取り込んでみることにします

[String] $registryKeyPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';
[String] $csvPath = '.\JapanseEraInEdo.csv';

Get-Content -Path $csvPath |
ConvertFrom-CSV |
Where-Object {
    $null -ne ($_.StartDate -as [DateTime])
} |
ForEach-Object {
    Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Name' -Value ($_.StartDate -as [DateTime]).ToString('yyyy MM dd');
    Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Value' -Value (($_.KanjiEraName, $_.KanjiEraName[0], $_.RomanAlphabetEraName, $_.RomanAlphabetEraName[0]) -join '_');
    Write-Output $_;
} |
Where-Object {
    $_.Name -notin (Get-Member -InputObject (Get-ItemProperty -Path $registryKeyPath) | ForEach-Object {$_.Name})
} |
New-ItemProperty -Path $registryKeyPath > $null;
PS > Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';

    Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese


Name                           Property
----                           --------
Eras                           1868 01 01 : 明治_明_Meiji_M
                               1912 07 30 : 大正_大_Taisho_T
                               1926 12 25 : 昭和_昭_Showa_S
                               1989 01 08 : 平成_平_Heisei_H
                               2019 05 01 : 令和_令_Reiwa_R
                               1615 09 05 : 元和_元_Genna_G
                               1624 04 17 : 寛永_寛_Kan'ei_K
                               1645 01 13 : 正保_正_Shouhou_S
                               1648 04 07 : 慶安_慶_Keian_K
                               1652 10 20 : 承応_承_Jouou_J
                               1655 05 18 : 明暦_明_Meireki_M
                               1658 08 21 : 万治_万_Manji_M
                               1661 05 23 : 寛文_寛_Kanbun_K
                               1673 10 30 : 延宝_延_Enpou_E
                               1681 11 09 : 天和_天_Tenna_T
                               1684 04 05 : 貞享_貞_Joukyou_J
                               1688 10 23 : 元禄_元_Genroku_G
                               1704 04 16 : 宝永_宝_Houei_H
                               1711 06 11 : 正徳_正_Shoutoku_S
                               1716 08 09 : 享保_享_Kyouhou_K
                               1736 06 07 : 元文_元_Genbun_G
                               1741 04 12 : 寛保_寛_Kanpou_K
                               1744 04 03 : 延享_延_Enkyou_E
                               1748 08 05 : 寛延_寛_Kan'en_K
                               1751 12 14 : 宝暦_宝_Houreki_H
                               1764 06 30 : 明和_明_Meiwa_M
                               1772 12 10 : 安永_安_An’ei_A
                               1781 04 25 : 天明_天_Tenmei_T
                               1789 02 19 : 寛政_寛_Kansei_K
                               1801 03 19 : 享和_享_Kyouwa_K
                               1804 03 22 : 文化_文_Bunka_B
                               1818 05 26 : 文政_文_Bunsei_B
                               1831 01 23 : 天保_天_Tenpou_T
                               1845 01 09 : 弘化_弘_Kouka_K
                               1848 04 01 : 嘉永_嘉_Kaei_K
                               1855 01 15 : 安政_安_Ansei_A
                               1860 04 08 : 万延_万_Man'en_M
                               1861 03 29 : 文久_文_Bunkyuu_B
                               1864 03 27 : 元治_元_Genji_G
                               1865 05 01 : 慶応_慶_Keiou_K

JapaneseCalendar classを使って江戸時代の日付を元号表示 (しようと) する (がエラーになる)

PS > [CultureInfo] $culture = [CultureInfo]::New("ja-JP");
PS > [Globalization.JapaneseCalendar] $culture.DateTimeFormat.Calendar = [System.Globalization.JapaneseCalendar]::new();
PS > ([Datetime]'1865/05/01').ToString('ggy年', $culture);

"2" 個の引数を指定して "ToString" を呼び出し中に例外が発生しました: "指定された引数は、有効な値の範囲内にありません。
パラメーター名:時間値が年号の範囲を超えています。"
発生場所 行:3 文字:1
+ ([Datetime]'1865/05/01').ToString('ggy年', $culture);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

エラーになりました

指定された引数は、有効な値の範囲内にありません。パラメーター名:時間値が年号の範囲を超えています。 とのことなのでこの期に及んでJapaneseCalendar Classの仕様を調べます

JapaneseCalendar Class (System.Globalization) | Microsoft Docs

This class handles dates from September 8 in the year Meiji 1 (in the Gregorian calendar, September 8, 1868). Although the Japanese calendar was switched from a lunar calendar to a solar calendar in the year Meiji 6 (1873 of the Gregorian calendar), this implementation is based on the solar calendar only.

どっとはらい