スポンサーリンク
技術情報

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

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

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

改元対応って?

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

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

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

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

改元対応!VB.NETで和暦レジストリ情報取得クラスを公開、Windowsレジストリ情報
改元対応!C#.NETで和暦レジストリ情報取得クラスを公開!和暦→西暦判断にぜひ この記事は、もうすぐ改元対応だけど、和暦ってOSのレジストリ情報って取得できないの?コードの日付判断を変更したい。に答えます。 W...

紹介クラスの使用方法

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

コーディング方法

Dim cReki As List(Of cReki) = cRekis.GetRekiList

With cReki(0)
TextBox1.Text=.EraName '【明治】
TextBox2.Text=.EraShortName '【M】
TextBox3.Text=.EraYear '【1868】
TextBox4.Text=.EraDate '【1868/1/1】
TextBox5.Text=.EraRange '【45】
End With

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

取得時の戻り値イメージ

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

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

VB.NETソース

Imports System.Reflection

Public Class cReki
    Public Property EraName As String
    Public Property EraYear As Integer
    Public Property EraDate As Date
    Public Property EraRange As Integer
    Public Property EraShortName As String

    Sub New(eraName As String, shortName As String, eraYear As Integer, eraDate As Date, eraRange As String)
        Me.EraName = eraName
        Me.EraShortName = shortName
        Me.EraYear = eraYear
        Me.EraDate = eraDate

        If Not eraRange = "" Then
            Me.EraRange = eraRange
        Else
            Me.EraRange = Date.MaxValue.Year - Today.Year
        End If
    End Sub
End Class

Public Class cRekis

    Private culture As New System.Globalization.CultureInfo("ja-JP", True)

    Sub New()
        culture.DateTimeFormat.Calendar = New Globalization.JapaneseCalendar
    End Sub

    Public Shared Function GetRekiList() As List(Of cReki)
        Return (New cRekis).GetRekis
    End Function

    Public Function GetRekis() As List(Of cReki)
        Dim lReki As New List(Of cReki)

        Dim iLength = culture.DateTimeFormat.Calendar.Eras.Length
        For iLoop As Integer = 1 To iLength
            lReki.Add(_getRekiClass(iLoop))
        Next
        Return lReki
    End Function

    Private Function _getRekiClass(iEra As Integer) As cReki
        Dim calendar As New System.Globalization.JapaneseCalendar()
        Dim fgStatus = BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.Static

        Dim tpFormat As Type = GetType(System.Globalization.DateTimeFormatInfo)
        Dim piEraName = tpFormat.GetProperty("AbbreviatedEnglishEraNames", fgStatus)
        Dim shortEraNames = CType(piEraName.GetValue(culture.DateTimeFormat, Nothing), String())(iEra - 1)

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

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

        Dim tpEraInfo = alEraInfo.GetValue(0).GetType
        Dim fiTicks = tpEraInfo.GetField("ticks", fgStatus)
        Dim dteMin = New DateTime(CLng(fiTicks.GetValue(alEraInfo.GetValue(alEraInfo.Length - iEra))))

        Dim fiEraYear = tpEraInfo.GetField("maxEraYear", fgStatus)
        Dim iEraYear = CInt(fiEraYear.GetValue(alEraInfo.GetValue(alEraInfo.Length - iEra)))

        Return New cReki(culture.DateTimeFormat.GetEraName(iEra), shortEraNames, dteMin.Date.Year, dteMin.Date, iEraYear.ToString)
    End Function
End Class

注意点

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

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

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

カレンダークラスのプライベートクラスのプロパティへアクセスしております。

今後の仕様変更の可能性もありますので自己責任にてご利用下さい。

まとめ

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

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

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

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