日本年號【和歷】和【西曆】相互轉換(Java, C#, VB三版本)

大約兩三個月之前,有個朋友問我說日本新天皇即將繼位(平成退位),更改新的年號,現在的年號算法需要變更,問我有沒有時間幫寫一個VB版本和Java版本的轉換方法,將Sample code給朋友後,發現對於這個問題其他的在日本的朋友或者正在做日本項目的程序猿可能都會遇到,便總結整理了本文。

本文地址:https://bluetata.blog.csdn.net/article/details/88238876
本文所有代碼:https://github.com/bluetata/wareki-seireki-hennkou
本文作者:bluetata  [email protected]
****** 如果你看到這一行,說明網絡爬蟲可能在本人還沒有發佈完成的時候就抓走了我的文章,導致內容不完整,請去上述的原文鏈接查看原文 ******

本文大綱如下:

1. 年號歷史及日本年號的劃分區間

2. 【西曆】向【和歷】轉換方法

3. 【和歷】向【西曆】轉換方法

首先聲明的是:本文拋開歷史和政治不談,僅站在中立的角度對日本年號切替(変更)的問題進行討論。

日本現任天皇(平成Heisei)將於2019年4月30日即將退位,其皇子(德仁なるひと)將於2019年5月1日繼位,30年零4個月的【平成】元號即將落幕。 對於日本元號更替,「和暦」(wareki)和「西暦」(seireki)相互轉換通常是比較麻煩的。本文會詳細介紹並講解 日本「和歷」(ワレキ) 和「西曆」(セイレキ)相互轉換的方法(包括新元號・德仁(暫定)的轉換)。

1.  年號歷史及日本年號的劃分區間

1.1  年號的由來及其相關歷史

注:如果你並不怎麼關心年號或者日本年號的區分,請直接下拉到西曆與和歷的轉換方法中直接pick你想要的。

博主業餘愛好是收藏古錢幣,民國時期的中日郵票和明信片。所以對各個朝代的錢幣和年號有所瞭解。如果本文有紕漏之處,請留言告知,謝謝。

中國第一個稱帝的皇帝是秦始皇,而世界上第一個使用年號的皇帝是漢武帝,使用的年號爲「建元」(公元前140年至前135年)。

日本第一個使用年號的皇帝是「孝德天皇」年號爲「大化」。對於這個年號你可能比較陌生,但是日本歷史上非常出名的一個政治改革你可能聽說過,它就是「大化革新」。

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

奈良的談山神社,供奉了「大化革新」的功臣之一「中臣鐮足」
圖片來源:大和中文官網

使用年號的國家,通常情況都是君主駕崩後,新的君主登基時一併更換年號,然而在日本明治之前,他們的天皇一生中並不是只限制使用一種年號,有的時候因爲天災戰亂或者國家發生重大事件時也會出現更換年號的情況,看日本動漫或者電影的同學一定對日本的江戶幕府有所未聞,在江戶時代,年號大多就由有實權的幕府決定。

而在近代年號的決定一般會由 內閣總理大臣(現任:安倍晉三)指定幾位有識有識之士向 日本內閣官房長官(現任:菅義偉)提出2~5個候選的年號,再由內閣官房長官整理好向內閣總理大臣彙報。最後再由「全閣僚會議」提出討論並決定,這一套流程在日本是有法律(年號法規)說明的。

關於「一世一元」制度:如果你使用過日本的一些系統,你會發現他們的Application中的下拉菜單一般只會出現4個年號:明治,大正,昭和,平成。他們4個年號對應了4個日本的天皇。在日本近代明治時代規定日本天皇一生只能使用一個年號,也就是「一世一元」制度。這個制度終止了明治之前時代一個天皇可能會有多個年號的情況。

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

Japan's emperor marks 30th year of reign at National Theatre in Tokyo
圖片來源:Chronicle

在文前提過:使用年號的國家,通常情況都是君主駕崩後,新的君主登基時一併更換年號。而在2016年平成提出了「生前退位」的提議。原因也不難猜測,年事已高,身體欠佳等等,亦或是年齡大其皇子也年齡大這樣後面繼位的天皇豈不是越來越大- -|· 個人揣測而已。

1.2  近代日本年號的劃分區間一覽

下表爲日本提供的年號區間,其中德仁年號暫用“德仁”代替:
 

年號 西暦 改元日 最終日
江戸時代-慶応 1865~1868   慶応3年(1867)10月14日大政奉還
明治 1868~1912 明治元年は1/1から 明治45年は7月29日まで
大正 1912~1926 大正元年は7月30日から 大正15年は12月24日まで
昭和 1926~1989 昭和元年は12月25日から 昭和64年は1月7日まで
平成 1989~2019 平成元年は1月8日から 平成30年は4月30日まで
徳仁(暫定) 2019~ 徳仁元年は5月1日  

 

整理後年號區間爲:

明治:1868年01月01日 ~ 1912年07月29日
大正:1912年07月30日 ~ 1926年12月24日
昭和:1926年12月25日 ~ 1989年01月07日
平成:1989年01月08日 ~ 2019年04月30日
德仁:1989年05月01日 ~

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
 

注意:在改元日當天日到當年的最後一天也就是12月31日爲該年號的元年,以平成舉例,在1989年01月08日到1989年12月31日間都叫平成元年,而在1989年1月1日到1月7日均爲昭和64年,這也就意味着平成最開始的一天爲平成元年1月8日,沒有平成1月1日,1989年1月1日爲昭和64年1月1日。

這些年號的區間和具體的特殊時間弄清楚後,就可以開始着手代碼了。

2.  【西曆】向【和歷】轉換方法

下列給出了從西曆轉換成日本和歷的方法,可以理解爲:用現在的西曆時間減去天皇繼位的前一年(上一任天皇的最後一年),即爲所要計算西曆的日本和歷時間。
 

*(西暦 → 新元號・德仁(暫定)) "德仁" = "西暦" – 2018
*(西暦 → 平成) "平成" = "西暦" – 1988
*(西暦 → 昭和) "昭和" = "西暦" – 1925
*(西暦 → 大正) "大正" = "西暦" – 1911
*(西暦 → 明治) "明治" = "西暦" – 1867

 

以平成年間西曆轉和歷例子:
 

2000年 → (2000 - 1988) → 平成12年
2005年 → (2005 - 1988) → 平成17年
2010年 → (2010 - 1988) → 平成22年
2018年 → (2018 - 1988) → 平成30年

根據計算方式轉換爲代碼(由於篇幅有限這裏只提供了Java版本的代碼,如果需要C#,VB版本的轉換方法請到GitHub下載:wareki-seireki-hennkou
 

public String warekiConversionApater(LocalDateTime d1) {

    // 文字列を日付に返す
    String strDay = "";
    int iYear;

    // 西暦を返還する(明治編)
    if (d1.isAfter(LocalDateTime.of(1868, 1, 24, 23, 59)) &&
            d1.isBefore(LocalDateTime.of(1912, 7, 30, 0, 0))) {

        // 西暦から和暦に変換する
        iYear = d1.getYear() - 1867;

        // 日付を返す
        if (iYear == 1) {
            strDay = "明治元年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        } else {
            strDay = "明治" + iYear + "年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        }

        return strDay;
    }

    // 西暦を返還する(大正編)
    if (d1.isAfter(LocalDateTime.of(1912, 7, 29, 23, 59)) &&
            d1.isBefore(LocalDateTime.of(1926, 12, 25, 0, 0))) {

        // 西暦から和暦に変換する
        iYear = d1.getYear() - 1911;

        // 日付を返す
        if (iYear == 1) {
            strDay = "大正元年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        } else {
            strDay = "大正" + iYear + "年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        }

        return strDay;
    }

    // 西暦を返還する(昭和編)
    if (d1.isAfter(LocalDateTime.of(1926, 12, 24, 23, 59)) &&
            d1.isBefore(LocalDateTime.of(1989, 1, 8, 0, 0))) {

        // 西暦から和暦に変換する
        iYear = d1.getYear() - 1925;

        // 日付を返す
        if (iYear == 1) {
            strDay = "昭和元年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        } else {
            strDay = "昭和" + iYear + "年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        }

        return strDay;
    }

    // 西暦を変換する(平成編)
    if (d1.isAfter(LocalDateTime.of(1989, 1, 7, 23, 59)) &&
            d1.isBefore(LocalDateTime.of(2019, 5, 1, 0, 0))) {

        //西暦から和暦に変換する
        iYear = d1.getYear() - 1988;

        //日付を返す
        if (iYear == 1) {
            strDay = "平成元年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        } else {
            strDay = "平成" + iYear + "年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        }

        return strDay;
    }

    // 西暦を変換する(新元號・德仁(暫定))
    if (d1.isAfter(LocalDateTime.of(2019, 4, 30, 23, 59))) {

        // 西暦から和暦に変換する
        iYear = d1.getYear() - 2018;

        // 日付を返す
        if (iYear == 1) {
            strDay = "新元號・德仁(暫定)元年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        } else {
            strDay = "新元號・德仁(暫定)" + iYear + "年" + d1.getMonthValue() + "月" + d1.getDayOfMonth() + "日";
        }

        return strDay;
    }

    // それ以外
    strDay = "和暦は明治・大正・昭和・平成・德仁のみ対応しております";

    return strDay;

}

3.  【和歷】向【西曆】轉換方法

在第2節知道西曆向和歷的轉換後,反過來的轉換也就簡單了:

*(德仁 → 西暦) "西暦" = "德仁" + 2018
*(平成 → 西暦) "西暦" = "平成" + 1988
*(昭和 → 西暦) "西暦" = "昭和" + 1925
*(大正 → 西暦) "西暦" = "大正" + 1911
*(明治 → 西暦) "西暦" = "明治" + 1867

以之前平成的例子計算:
 

平成12年 → (12 + 1988) → 2000年
平成17年 → (17 + 1988) → 2005年
平成22年 → (22 + 1988) → 2010年
平成30年 → (30 + 1988) → 2018年

轉換Java版本代碼(如需要C#,VB版本的轉換方法請到GitHub下載:wareki-seireki-hennkou):
 

// 和暦変換
public String seirekiConversionApater(String sWareki) {

    //和暦変換
    String sDay = sWareki;
    String sSplit[];
    Integer iYear;

    sDay = sDay.replace("日", "");
    sDay = sDay.replace("月", "/");
    sDay = sDay.replace("年", "/");
    sDay = sDay.replace("平成元", "1989/1");
    sDay = sDay.replace("昭和元", "1926/1");
    sDay = sDay.replace("大正元", "1912/1");
    sDay = sDay.replace("明治元", "1868/1");
    sDay = sDay.replace("平成", "1989/");
    sDay = sDay.replace("昭和", "1926/");
    sDay = sDay.replace("大正", "1912/");
    sDay = sDay.replace("明治", "1868/");

    // 文字を分割する。    Spilit
    sSplit = sDay.split("/", 0);

    // 日付を作成する
    iYear = Integer.parseInt(sSplit[0]) + Integer.parseInt(sSplit[1]) - 1;    // 年を數値で
    sDay = String.valueOf(iYear) + "/" + sSplit[2] + "/" + sSplit[3];         // 和暦を作成する

    return sDay;
}

reflink:

https://github.com/bluetata/wareki-seireki-hennkou/blob/master/README-cn.md
https://www.becoolusers.com/excel/heisei1.html
http://capm-network.com/?tag=日本の年號変換

本文原創由`bluetata`發佈於blog.csdn.net、轉載請務必註明出處。

Flag Counter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章