改元対応!C#.NETで和暦レジストリ情報取得クラスを公開!和暦→西暦判断にぜひ

改元対応!c#.NETで和暦レジストリ情報取得クラスを公開!和暦→西暦判断にぜひ

この記事は、もうすぐ改元対応だけど、和暦ってOSのレジストリ情報って取得できないの?コードの日付判断を変更したい。に答えます。

Windowsのレジストリにある情報を取得するクラスコードを公開!各開始日まで簡単取得できます!

改元対応って?

2019年5月1日に確定している改元。

昭和の頃はともかく、平成ってまだ続くと思ったから和暦→西暦判断ってハードコーディングしてしまった。今後のことも考えて何かいい方法ないの?

皆さんご存知の通りWindowsにはレジストリ内に和暦情報を持っています。

このレジストリ情報を取得して、和暦一覧を取得するクラスコードを公開します!

改元対応!c#.NETで和暦レジストリ情報取得クラスを公開、Windowsレジストリ情報

VB版はこちら

改元対応!VB.NETで和暦レジストリ情報取得クラスを公開!和暦→西暦判断に。
改元対応に最適!VB.NETでWindowsOSのレジストリ内和暦情報の取得クラスを公開!ハードコーディングしている和暦→西暦判断の修正に、分岐条件となる日付を取得できるクラスのご
READ MORE..

紹介クラスの使用方法

本クラスを使用して、呼び出し元での使用方法を紹介します。

コーディング方法

var cReki = cRekis.GetRekiList

textBox1.Text=cReki[0].EraName //【明治】
textBox2.Text=cReki[0].EraShortName //【M】
textBox3.Text=cReki[0].EraYear //【1868】
textBox4.Text=cReki[0].EraDate //【1868/1/1】
textBox5.Text=cReki[0].EraRange //【45】

※【】の中の値が戻ってきます

取得時の戻り値イメージ

本クラスを使用すると図のようなイメージでデータ取得が可能です。

改元対応!c#.NETで和暦レジストリ情報取得クラスを公開、コントロールパネル設定
※「和暦」などの日本語行は解説用でプロパティには入ってきません。
※Win10 1803以降の場合は、新元号「??」が取得できます

C#.NETソース

using System.Globalization;
using System.Reflection;

public class cReki
{
    public string EraName { get; set; }
    public int EraYear { get; set; }
    public DateTime EraDate { get; set; }
    public int EraRange { get; set; }
    public string EraShortName { get; set; }

    public cReki(string eraName, string eraShortName, int eraYear, DateTime eraDate, string eraRange)
    {
        this.EraName = eraName;
        this.EraShortName = eraShortName;
        this.EraYear = eraYear;
        this.EraDate = eraDate;
        if (eraRange != "")
        {
            this.EraRange = int.Parse(eraRange);
        }
        else
        {
            this.EraRange = DateTime.MaxValue.Year - DateTime.Today.Year;
        }
    }
}

public class cRekis
{
    private CultureInfo culture = new CultureInfo("ja-JP", true);

    public cRekis()
    {
        culture.DateTimeFormat.Calendar = new System.Globalization.JapaneseCalendar();
    }

    public static List GetRekiList()
    {
        return (new cRekis()).GetRekis();
    }

    public List GetRekis()
    {

        var lReki = new List();
        var iLength = culture.DateTimeFormat.Calendar.Eras.Length;

        for (int iLoop = 1; iLoop <= iLength; iLoop++)
        {
        lReki.Add(_getRekiClass(iLoop));
        }

        return lReki;
    }

    private cReki _getRekiClass(int iEra)
    {
    var calendar = new System.Globalization.JapaneseCalendar();
    var fgStatus = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

    var tpFormat = Type.GetType("System.Globalization.DateTimeFormatInfo");
    var piEraName = tpFormat.GetProperty("AbbreviatedEnglishEraNames", fgStatus);
    var shortEraNames = ((string[])(piEraName.GetValue(culture.DateTimeFormat, null)))[iEra - 1];

    var tpCalender = Type.GetType("System.Globalization.JapaneseCalendar");
    var fiHelper = tpCalender.GetField("helper", fgStatus);
    var tpHelper = fiHelper.FieldType;

    var fiEraInfo = tpHelper.GetField("m_EraInfo", fgStatus);
    var alEraInfo = (Array)(fiEraInfo.GetValue(fiHelper.GetValue(calendar)));

    var tpEraInfo = Type.GetType("System.Globalization.EraInfo");
    var fiTicks = tpEraInfo.GetField("ticks", fgStatus);
    var dteMin = new DateTime((long)(fiTicks.GetValue(alEraInfo.GetValue(alEraInfo.Length - iEra))));

    var fiEraYear = tpEraInfo.GetField("maxEraYear", fgStatus);
    var iEraYear = (int)(fiEraYear.GetValue(alEraInfo.GetValue(alEraInfo.Length - iEra)));

    return new cReki(culture.DateTimeFormat.GetEraName(iEra), shortEraNames, dteMin.Date.Year, dteMin.Date, iEraYear.ToString());
    }
}

注意点

本クラスは.NETカレンダークラスを使用しています。
.NETカレンダークラスはコントロールパネルの設定値を反映します。

仕様変更にご留意ください

本クラスは10年の本場環境にて運用実績があります。

カレンダークラスのプライベートクラスのプロパティへアクセスしております。
今後の仕様変更の可能性もありますので自己責任にてご利用下さい。

まとめ

和暦→西暦の判断条件として、暫定対応としてハードコーディングされている方も多いと思います。

WindowsOSのレジストリの格納されている日付情報を取得できれば、自動更新も可能です。

直前まで改元情報が出てこない今回の対応で、少し早めの対策にご利用下さい!

ご利用時はツイート拡散かコメントもらえるとうれしいです。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です