日本年号【和历】和【西历】相互转换(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

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