K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

和暦を西暦へ変換する

01.7.5

和暦を西暦へ変換する

最終更新 2020-03-25 読了時間 2 分
まとめ
「令和5年度決算」「平成28年4月入社」のような和暦の文字列から元号と年数を正規表現で取り出し、ERA_TABLE に入れた元号ごとの基準年(令和なら 2018)に年数を足して西暦に直します。元年は 1 年として扱うので「令和元年」は 2018 + 1 = 2019 になります。和暦を含まない「西暦2020年」には None を返すので、変換できなかった行を後から見分けられます。自治体のオープンデータや社内の申請書を 1 本の時系列にまとめるときの最初の一手です。

直感 #

自治体のオープンデータや社内の申請書では「令和5年」「平成28年度」のように和暦が多く登場します。和暦は元号が変わるたびに 1 からやり直すので、「平成28年」と「令和5年」のどちらが新しいかを文字列の並べ替えで判断できません。西暦に直してしまえば sort_values も「2016 年から 2023 年まで 7 年」という引き算も普通に動きます。変換の中身は足し算 1 回です。元号ごとに「元年の前の年」を覚えておき、そこに年数を足すだけで、令和は 2019 年が元年なので基準は 2018、平成は 1989 年が元年なので基準は 1988 になります。

Python で変換する #

次のコードは 5 つの元号の基準年を辞書に持ち、re.compile した 1 本のパターンで元号と年数を取り出して西暦を返します。和暦を含まない「西暦2020年」は None になります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import re

ERA_TABLE = {
    "令和": 2018,  # 令和元年 = 2019
    "平成": 1988,
    "昭和": 1925,
    "大正": 1911,
    "明治": 1867,
}

ERA_PATTERN = re.compile(r"(明治|大正|昭和|平成|令和)(元|\d{1,2})年?")

def wareki_to_western(text: str) -> int | None:
    match = ERA_PATTERN.search(text)
    if not match:
        return None
    era, year = match.groups()
    base_year = ERA_TABLE[era]
    year_num = 1 if year == "元" else int(year)
    return base_year + year_num

records = ["令和5年度決算", "平成28年4月入社", "昭和60年生まれ", "西暦2020年"]
for r in records:
    converted = wareki_to_western(r)
    print(r, "→", converted if converted else "西暦表記")

実行結果の読み方 #

出力は 令和5年度決算 → 2023、平成28年4月入社 → 2016、昭和60年生まれ → 1985、西暦2020年 → 西暦表記 の 4 行です。「年度」や「4月入社」が後ろに付いていても、正規表現は「令和5年」の部分だけに一致するので結果は変わりません。ただし「令和5年度」は会計年度なので、暦年の 2023 年と同一視してよいかはデータの定義を確認してから決めます。

使いどころと落とし穴 #

和暦と西暦が混在する列では、変換後の西暦(year)と元の表記(year_raw)の 2 列を残しておくと、監査や突き合わせのときに元の帳票へ戻れます。明治より前の年号が必要な戸籍や歴史資料では、ERA_TABLE と ERA_PATTERN の両方に元号を追記します。「R05」「H28」のような英字 1 文字の略記は今のパターンでは一致せず None になるので、(R|H|S|T|M)(\d{1,2}) のような別パターンを足し、部署やシステムごとの書き方をヒアリングして対応表を育てていきます。元号が切り替わる年は注意が必要で、「平成31年」と「令和元年」はどちらも 2019 に写るため、月まで必要なら年ではなく日付単位での変換に切り替えてください。