Seita developer blog

ユーザ企業に努めるアプリケーションエンジニアがプログラミング、データベース、OS、SNS、ガジェットなどを中心に備忘録変わりに書いていきます。

【Tips】和暦西暦変換処理と明治時代とJava、C#での実装について(2017/1/10追記)

日付処理にまつわる、明治時代の和暦の考え方について紹介します。

 

学生時代に習った「明治時代の日付のずれ※」覚えていますか?

 

「明治5年12月2日」の翌日が「明治6年1月1日」

  

なぜ歴史のことをお話しするかというと、アプリケーション、特に業務アプリを作る際に絶対的に必要になってくる「西暦和暦変換処理」について、歴史的背景、Javaでの実装、C#での実装に解説したいと思います。

 

[歴史的背景]

明治になった9月8日という日付について、和暦年月(太陽太陰暦)の明治1年9月8日であり、西暦では「1868年10月23日」となる。

上記開始日のずれの原因は、明治への改元詔書が出されたのが1868年10月23日であり、当日付は、慶応4年9月8日、明治1年9月8日と同日を指す。これが翌日改元に基づいた歴史的な明治の開始日となる。
ただし、立年改善に基づいた場合、上記の日付を元に、遡って明治1年1月1日と定められたのが、1868年1月25日となる。

また、明治5年12月2日(1872年12月31日)の翌日から太陽暦グレゴリオ暦)を採用しており、明治6年(1873年)1月1日としたため、明治5年は12月3日から12月30日までの28日間が存在しない。

 

<年表>

和暦西暦
(グレゴリウス暦)
明治時代の
始まり
歴史
慶応3年12月7日 1868年1月1日   改歴を考慮しない場合の明治1年1月1日
明治1年1月1日 1868年1月25日 立年改元 公式な明治の開始日
慶応4年1月1日    
慶応4年9月7日 1868年10月22日   慶応の終了日
慶応4年9月8日 1868年10月23日   明治の開始日であるが、慶応の終了日でもある 
明治1年9月8日 翌日改元 明治への改元詔書が出された日
歴史的な明治の開始日
明治5年11月9日 1872年12月9日   改暦ノ布告
明治5年太政官布告第337号
明治5年12月2日 1872年12月31日   明治改暦
和暦における太陽太陰暦の最終日
明治6年1月1日 1873年1月1日   和暦でグレゴリウス暦が使われ始めた日

 

<日本史の教科書>

f:id:rey1229:20160610235506p:plain

 

[Javaでの実装]

JavaではJava SE6及びSE8より、標準APIで和暦に対応しています

  クラス:JapaneseImperialCalendar(JavaSE6)、JapaneseDate(JavaSE8)

  サポート:西暦1873年1月1日/明治6年1月1日

サポート対象外の日付を入れると例外が発生します。

 

実際に処理をすると「西暦1868年1月1日は例外が発生」します。

 

てわけで、JavaSE8ベースでテストしてみました。

 

<テストソース>

github.com

 

<実行結果>

JavaDoc通り、明治6年1月1日より前はサポートしてない模様。

翌日改元に基づいた実装がされていました。

(これって正しいのかな?)

RuntimeException:西暦1868年1月1日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年1月1日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年1月25日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年9月7日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年9月8日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年9月9日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年10月22日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1868年10月23日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
RuntimeException:西暦1872年12月31日  (java.time.DateTimeException: JapaneseDate before Meiji 6 is not supported)
西暦1873年1月1日 → 明治6年1月1日
西暦1912年1月1日 → 明治45年1月1日
西暦1912年7月29日 → 明治45年7月29日
西暦1912年7月30日 → 大正1年7月30日
西暦1926年1月1日 → 大正15年1月1日
西暦1926年12月24日 → 大正15年12月24日
西暦1926年12月25日 → 昭和1年12月25日
西暦1989年1月1日 → 昭和64年1月1日
西暦1989年1月7日 → 昭和64年1月7日
西暦1989年1月8日 → 平成1年1月8日

 

[C#での実装]

C#では、標準APIで和暦に対応しています。

  クラス:JapaneseCalendar

  サポート:西暦1868年9月8日

ただし、グレゴリオ暦の西暦1868年9月8日~の変換にしか対応しておらず、これより前の日付を操作しようとした場合、ArgumentOutOfRangeExceptionが発生します。

 

てわけでこっちもテストしてみました

 

<テストソース>

github.com

 

<実行結果>

MSDN通り、明治5年まではグレゴリウス暦が反映されていない模様です。

Exception:西暦1868年1月1日
Exception:西暦1868年1月1日
Exception:西暦1868年1月25日
Exception:西暦1868年9月7日
西暦1868年9月8日 → 明治01年9月8日
西暦1868年9月9日 → 明治01年9月9日
西暦1868年10月22日 → 明治01年10月22日
西暦1868年10月23日 → 明治01年10月23日
西暦1872年12月31日 → 明治05年12月31日
西暦1873年1月1日 → 明治06年1月1日
西暦1912年1月1日 → 明治45年1月1日
西暦1912年7月29日 → 明治45年7月29日
西暦1912年7月30日 → 大正01年7月30日
西暦1926年1月1日 → 大正15年1月1日
西暦1926年12月24日 → 大正15年12月24日
西暦1926年12月25日 → 昭和01年12月25日
西暦1989年1月1日 → 昭和64年1月1日
西暦1989年1月7日 → 昭和64年1月7日
西暦1989年1月8日 → 平成01年1月8日

 

[アプリでの和暦サポートの考え方]

ここまで歴史が複雑で、資料も残っておらず考え方がばらばらの場合、グレゴリウス暦に統一された「1873年1月1日(明治6年1月1日)」から、変換をサポートすることを推奨します。

また、標準APIで実装し、元号が変わった場合、標準APIライブラリが対応するまでの間、和暦のサポートができなくなります。

実態としては、アプリケーションを組む場合は、西暦を採用するか、和暦を採用する場合は個別実装することになるかと思います。

 

 

個人的所管だけど、、

日本人だけど、システム屋だから、和暦嫌い!!

 

-------------------------------------------------------------------------------

2017/1/10追記

本日、元号の改定に関する閣議が発表されました。

こちらの記事とあわせてご覧ください

rey1229.hatenablog.com

--------------------------------------------------------------------------------

 

 

[歴史系参考]

グレゴリオ暦 - Wikipedia

和暦 - Wikipedia

改元 - Wikipedia

park.geocities.jp

meiji.sakanouenokumo.jp

meiji.sakanouenokumo.jp

d.hatena.ne.jp

和暦西暦対応表

明治5年太政官布告第337号

 

[JavaSE6参考]

※パッケージプライベートのクラスなためAPIドキュメントが存在しません。

itpro.nikkeibp.co.jp

allabout.co.jp

 

[JavaSE8参考]

JapaneseDate (Java Platform SE 8)

www.atmarkit.co.jp

qiita.com

www.atmarkit.co.jp

 

 

[C#参考]

JapaneseCalendar.MinSupportedDateTime プロパティ - MSDN

desilysis.seesaa.net