■
介绍
纪元的名称通常显示在年份前面。例如,公历 2012 年就是日本历的【平成 24 年】。纪元的第一年也称为 元年(Gannen),所以公历 1989 年就是日本历的【平成元年】。
★
纪元列表
编号
|
纪元名称
|
纪元缩写
|
公历日期
|
1
|
平成(Heisei)
|
平(H, h)
|
1989 年 01 月 08 日至今
|
2
|
昭和(Showa)
|
昭(S, s)
|
1926 年 12 月 25 日至 1989 年 01 月 07 日
|
3
|
大正(Taisho)
|
大(T, t)
|
1912 年 07 月 30 日至 1926 年 12 月 24 日
|
4
|
明治(Meiji)
|
明(M, m)
|
1868 年 09 月 08 日至 1912 年 07 月 29 日
|
5
|
N/A
|
N/A
|
1868 年 09 月 07 日之前
|
■
Java 6 以后格式化和历的示例代码:
public static void testJapaneseCalendar() throws ParseException {
SimpleDateFormat d = new SimpleDateFormat("yyyy/MM/dd");
Locale locale = new Locale("ja", "JP", "JP");
// 必须这样实例化 Locale,不可使用 Locale.JAPAN 或 Locale.JAPANESE,否则后续的格式化无效
DateFormat ja = DateFormat.getDateInstance(DateFormat.FULL, locale);
System.out.println(ja.format(d.parse("2012/11/12"))); // 结果是:平成24年11月12日
ja = new SimpleDateFormat("GGGG yy年MM月dd日", locale);
System.out.println(ja.format(d.parse("2012/11/12"))); // 结果是:平成_24年11月12日(下划线代表空格)
ja = DateFormat.getDateInstance(DateFormat.SHORT, locale);
System.out.println(ja.format(d.parse("2012/11/12"))); // 结果是:H24.11.12
ja = new SimpleDateFormat("G yy.MM.dd", locale);
System.out.println(ja.format(d.parse("2012/11/12"))); // 结果是:H_24.11.12(下划线代表空格)
ja = new SimpleDateFormat("GGGG yy年MM月dd日", locale);
System.out.println(ja.format(d.parse("1868/01/01"))); // 结果是:明治_01年01月01日(下划线代表空格)
ja = new SimpleDateFormat("G yy.MM.dd", locale);
System.out.println(ja.format(d.parse("1868/01/01"))); // 结果是:M_01.01.01(下划线代表空格)
ja = new SimpleDateFormat("GGGG yy年MM月dd日", locale);
System.out.println(ja.format(d.parse("1867/12/31"))); // 结果是:西暦_1867年12月31日(下划线代表空格)
ja = new SimpleDateFormat("G yy.MM.dd", locale);
System.out.println(ja.format(d.parse("1867/12/31"))); // 结果是:_1867.12.31(下划线代表空格)
}
注意,这里的 Locale 必须实例化成 Locale("ja", "JP", "JP"),否则格式化不出来和历的效果。原因可以通过分析 Calendar 类的 createCalendar() 方法得知,对 Locale("ja", "JP", "JP") 进行了特殊处理,返回了 JapaneseImperialCalendar 这个特殊类的实例,代码如下:
private static Calendar createCalendar(TimeZone zone, Locale aLocale)
{
// If the specified locale is a Thai locale, returns a BuddhistCalendar
// instance.
if ("th".equals(aLocale.getLanguage())
&& ("TH".equals(aLocale.getCountry()))) {
return new sun.util.BuddhistCalendar(zone, aLocale);
} else if ("JP".equals(aLocale.getVariant())
&& "JP".equals(aLocale.getCountry())
&& "ja".equals(aLocale.getLanguage())) {
return new JapaneseImperialCalendar(zone, aLocale);
}
// else create the default calendar
return new GregorianCalendar(zone, aLocale);
}
补充,JapaneseImperialCalendar 类是 Java 1.6 以后才有的,所以上面的代码只在 Java 1.6 以后的版本有效。
■ 自定义的一个简单实现(旧版本 Java 可用)
通过修改 DateFormatSymbols 的纪元文字来实现。这样旧版本的 Java 环境上也可以用,也容易实现扩展。
public static String formatJapaneseCalendar(String pattern, Date date, boolean showFullName) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
DateFormatSymbols symbols = format.getDateFormatSymbols();
String[] eras = symbols.getEras();
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(date);
if (!gregorianCalendar.before(HEISEI)) {
if (showFullName) { eras[0] = "平成"; } else { eras[0] = "H"; }
gregorianCalendar.set(Calendar.YEAR, HEISEI.get(Calendar.YEAR) - gregorianCalendar.get(Calendar.YEAR));
} else if (!gregorianCalendar.before(SYOWA)) {
if (showFullName) { eras[0] = "昭和"; } else { eras[0] = "S"; }
gregorianCalendar.set(Calendar.YEAR, SYOWA.get(Calendar.YEAR) - gregorianCalendar.get(Calendar.YEAR));
} else if (!gregorianCalendar.before(TAISYO)) {
if (showFullName) { eras[0] = "大正"; } else { eras[0] = "T"; }
gregorianCalendar.set(Calendar.YEAR, TAISYO.get(Calendar.YEAR) - gregorianCalendar.get(Calendar.YEAR));
} else if (!gregorianCalendar.before(MEIJI)) {
if (showFullName) { eras[0] = "明治"; } else { eras[0] = "M"; }
gregorianCalendar.set(Calendar.YEAR, MEIJI.get(Calendar.YEAR) - gregorianCalendar.get(Calendar.YEAR));
}
symbols.setEras(eras);
format.setDateFormatSymbols(symbols);
return format.format(gregorianCalendar.getTime());
}
/** 明治 */
private static final GregorianCalendar MEIJI = new GregorianCalendar(1868, 0, 1);
/** 大正 */
private static final GregorianCalendar TAISYO = new GregorianCalendar(1912, 6, 30);
/** 昭和 */
private static final GregorianCalendar SYOWA = new GregorianCalendar(1926, 11, 25);
/** 平成 */
private static final GregorianCalendar HEISEI = new GregorianCalendar(1989, 0, 8);