SelectBoxで「西暦 (平成○○年)」のような、西暦と和暦を両方表示するような仕様の実装を行うことになった。
Javaで和暦→西暦、西暦→和暦に変換する
https://qiita.com/u-chida/items/31b3415a52f0e1818ab2
和暦はこれで取れる
引用すると
//ロケールを指定してCalendarインスタンスを取得
Locale locale = new Locale("ja", "JP", "JP");
Calendar calendar = Calendar.getInstance(locale);
//calendar.getTime()で現在日時を取得して和暦にフォーマットする
DateFormat japaseseFormat = new SimpleDateFormat("GGGGy年M月d日", locale);
String dateStr = japaseseFormat.format(calendar.getTime());
System.out.println("和暦:" + dateStr);
//和暦にフォーマットした現在日時を西暦にパースする
//日付の妥当性をチェックするためsetLenient()にfalseを渡す
calendar.setLenient(false);
Date date = japaseseFormat.parse(dateStr);
System.out.println("西暦:" + date);
で、1990年から2000年までの和暦と併記することにした。
for (int seireki = 1990 ; seireki <= 2000; seireki++ ){
// ロケールを指定してCalendarインスタンスを取得
Locale locale = new Locale("ja", "JP", "JP");
Calendar calendar = Calendar.getInstance(locale);
// 値のクリア
calendar.clear();
// 年を設定
calendar.set(Calendar.YEAR, seireki);
// calendar.getTime()で現在日時を取得して和暦にフォーマットする
DateFormat japaseseFormat = new SimpleDateFormat("(GGGGy年)", locale);
String dateStr = japaseseFormat.format(calendar.getTime());
System.out.println(seireki + dateStr);
}
結果
1990(平成1990年)
1991(平成1991年)
1992(平成1992年)
1993(平成1993年)
1994(平成1994年)
1995(平成1995年)
1996(平成1996年)
1997(平成1997年)
1998(平成1998年)
1999(平成1999年)
2000(平成2000年)
イケてない。
calendar.getTimeInMillis()
で中身を見てみたら「633798000000」とか悲惨な値が入っていた。
calendarのロケールが和暦なので、yearに1990を入れたら平成1990年になる。
当たり前の話なのだ。
しかし、残念なことにロケールと年を同時に指定したコンストラクタはJava6にはない。
改善案
for (int seireki = 1990 ; seireki <= 2000; seireki++ ){
// ロケールを指定してCalendarインスタンスを取得
Locale locale = new Locale("ja", "JP", "JP");
// 1990年のカレンダーを作る
Calendar greCal = new GregorianCalendar(seireki, 1, 1);
Calendar calendar = Calendar.getInstance(locale);
// 値のクリア
calendar.clear();
// カレンダーから年を設定
calendar.setTimeInMillis(greCal.getTimeInMillis());
// calendar.getTime()で現在日時を取得して和暦にフォーマットする
DateFormat japaseseFormat = new SimpleDateFormat("(GGGGy年)", locale);
String dateStr = japaseseFormat.format(calendar.getTime());
System.out.println(seireki + dateStr);
}
1990(平成2年)
1991(平成3年)
1992(平成4年)
1993(平成5年)
1994(平成6年)
1995(平成7年)
1996(平成8年)
1997(平成9年)
1998(平成10年)
1999(平成11年)
2000(平成12年)
いい感じ。
平成と昭和の境目もバッチリ(1989年生まれは一律平成1年扱い)
1987(昭和62年)
1988(昭和63年)
1989(平成1年)
1990(平成2年)
本当は1年は元年にすべきなのだろうか…。
とりあえず上手くできたけれど、本当にこれでいいのかは悩む。
2017/11/17 追記
上記はJava6でやっていたのですが、Java8で修正。
コメントを受けて「1989年は昭和と平成」で表示に変更。
import java.time.chrono.JapaneseDate;
import java.time.format.DateTimeFormatter;
public class Qiita21ee9377032b650c2de6 {
public static void main(String[] args) {
QiitaExecute qiitaExe = new QiitaExecute();
qiitaExe.execute();
}
}
class QiitaExecute {
private final DateTimeFormatter japaseseFormat = DateTimeFormatter.ofPattern("GGGGy年");
/**
* 実行
*/
public void execute() {
for (int annoDomini = 1987; annoDomini <= 1990; annoDomini++) {
String eraString = getEraString(annoDomini);
System.out.println(annoDomini + "(" + eraString + ")");
}
}
/**
* 和暦返却
* 西暦を渡し、元旦から年末の間に元号の変更がある場合は両方の元号を「・」で連結して返す
* 元号の変更がない場合は元旦の元号を返す
* @param annoDomini
* @return
*/
private String getEraString(int annoDomini) {
// 元旦
// (JapaneseDateの月は1~12で表示)
JapaneseDate japaneseNewYearDate = JapaneseDate.of(annoDomini, 1, 1);
// 年末
JapaneseDate japaneseNewYearEveDate = JapaneseDate.of(annoDomini, 12, 31);
// 元号が同じ場合は元旦の元号を返し、それ以外は元旦と年末を「・」で連結して返す
if (japaneseNewYearDate.getEra().getValue() == japaneseNewYearEveDate.getEra().getValue()) {
return japaseseFormat.format(japaneseNewYearDate);
} else {
return japaseseFormat.format(japaneseNewYearDate) + "・" + japaseseFormat.format(japaneseNewYearEveDate);
}
}
}
結果
1987(昭和62年)
1988(昭和63年)
1989(昭和64年・平成1年)
1990(平成2年)
1989(昭和64年・平成元年)の表示にするかは悩みどころ。日本人なので元年にしたい気持ちがある。
1987(昭和62年)
1988(昭和63年)
1989(昭和64年)
1989(平成1年)
1990(平成2年)
が正しい表示なのかもしれないが、1989年、1990年生まれが戸惑う可能性がある。
(1990年生まれは1989の下にあるものと思うから。セレクトボックスをキーボードで選んでる人とかミスる可能性を考慮)