o7planning

Java JapaneseEra Tutorial with Examples

  1. JapaneseEra
  2. Japanese Era List
  3. JapaneseEra Examples
  4. of(int japaneseEra)
  5. valueOf(String japaneseEra)
  6. values()
  7. getValue()
  8. range(TemporalField)
  9. getDisplayName(TextStyle, Locale)

1. JapaneseEra

The JapaneseEra class represents an era in the Japanese imperial calendar system, a calendar system used mainly in this country.
Basically, an era in the Japanese imperial calendar system corresponds to the period of reign of a king. When an era begins, the year will be numbered starting from 1, the day and month stay unchanged and are the same as the ISO calendar system.
public final class JapaneseEra implements Era, Serializable
For simplicity let's take a look at the illustration below:
Emperor Akihito ruled Japan from January 8, 1989 to April 30, 2019. The period of his reign is known as the Heisei era. When a new era begins, the year will be numbered starting at 1, the day and month do not change.
Thus, according to the Japanese imperial calendar, the first day of the Heisei era was January 8, 01 and the last day was April 30, 31.

2. Japanese Era List

There are many dynasties in Japanese history, each of which corresponds to an era. In this article I do not intend to introduce all of them. If you are interested, the following article will be useful to you:
The first calendar systems appeared in Japan from 604 based on the Chinese lunar calendar. This calendar system existed until the end of 1872 before being replaced by the Gregorian (aka ISO) calendar system. The Japanese imperial calendar system of the period before January 1, 1873 is not supported by Java.
List of supported eras in Java:
getValue()
Era Name
Emperor
ISO Date
From
To
-1
明治 (Meiji)
Mutsuhito
1868-09-08
1873-01-01(*)
1912-07-29
0
大正 (Taisho)
Yoshihito
1912-07-30
1926-12-24
1
昭和 (Showa)
Hirohito
1926-12-25
1989-01-07
2
平成 (Heisei)
Akihito
1989-01-08
2019-04-30
3
令和 (Reiwa)
Naruhito
2019-05-01
present
JapaneseEra.MEIJI
The period from October 23, 1868 to July 29, 1912 was the reign of Emperor Meiji. His real name was Mutsuhito (December 3, 1852 - July 30, 1912). This was the first half of the Japanese empire when the Japanese transformed from an isolated feudal society in danger of being invaded by the West into a modern industrial capital country.
During the Meiji era, the calendar system underwent a major change:
From October 23, 1868 to December 31, 1872: Japan used an imperial calendar system with day and month based on the lunar calendar, but the years were numbered based on the age of the current era. (Java does not support this stage)
From January 1, 1973 to present: Japan maintains 2 calendar systems, the Gregorian and the improved imperial calendar system (Day and month are based on the Gregorian calendar but years are numbered based on the age of the current era) .
JapaneseEra.TAISHO
On July 30, 1912 Emperor Meiji died. Crown Prince Yoshihito (August 31, 1879 – December 25, 1926) became emperor and ushered in the Taisho era from July 30, 1912 to December 24, 1926. Taisho means "great righteousness".
JapaneseEra.SHOWA
Emperor Shōwa (April 29, 1901 - January 7, 1989), whose real name is Hirohito. He was the 124th emperor of Japan, ruling Japan from December 25, 1926 to January 7, 1989.
JapaneseEra.HEISEI
Emperor Heisei was born on December 23, 1933, whose real name is Akihito and is the first son of Emperor Shōwa. On January 8, 1989 he became emperor and ruled Japan until April 30, 2019. In Japanese, Heisei means "peace everywhere".
JapaneseEra.REIWA
On April 30, 2019, Emperor Heisei abdicated due to health problems, his son Naruhito ascended the throne and became the 126th emperor of Japan. He named the era Reiwa, which means "beautiful harmony". The Reiwa Era began on May 1, 2019 and is the current era of Japan.

3. JapaneseEra Examples

The following JapaneseEraUtils class provides utility methods that help you find the first and the last date in a specified era:
JapaneseEraUtils.java
package org.o7planning.japaneseera.util;

import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.ValueRange;

public class JapaneseEraUtils {
    public static final JapaneseDate FIRST_SUPPORTED_JP_DATE = JapaneseDate.of(JapaneseEra.MEIJI, 6, 1, 1);

    public static JapaneseDate getFirstDateInSameEra(final JapaneseDate japaneseDate) {
        final JapaneseEra thisEra = japaneseDate.getEra();

        // Valid Japanese Year range with the same given day & month & era.
        ValueRange validYearRange = japaneseDate.range(ChronoField.YEAR_OF_ERA); // Ex: 1-64

        // Valid Min Japanese year with the same given day & month
        int validMinYear = (int) validYearRange.getMinimum(); // 1

        if (thisEra.equals(JapaneseEra.MEIJI)) {
            if (validMinYear < 6) {
                validMinYear = 6;
            }
        }
        final JapaneseDate jpDate2 = JapaneseDate.of(thisEra, validMinYear, 12, 31);

        ValueRange dayOfY2 = jpDate2.range(ChronoField.DAY_OF_YEAR);

        // First date in the same year with jpDate2.
        final JapaneseDate jpDate3 = jpDate2.minus(dayOfY2.getMaximum() - dayOfY2.getMinimum(), ChronoUnit.DAYS);

        if (!jpDate3.isAfter(FIRST_SUPPORTED_JP_DATE)) {
            return jpDate3;
        }
        final JapaneseDate jpDate4 = jpDate3.minus(1, ChronoUnit.DAYS);
        final JapaneseEra era4 = jpDate4.getEra();

        if (!thisEra.equals(era4)) {
            return jpDate3;
        }
        ValueRange dayOfY4 = jpDate4.range(ChronoField.DAY_OF_YEAR);
        // First date in the same Era with given japaneseDate.
        final JapaneseDate jpDate5 = jpDate4.minus(dayOfY4.getMaximum() - dayOfY4.getMinimum(), ChronoUnit.DAYS);
        return jpDate5;
    }

    public static JapaneseDate getLastDateInSameEra(final JapaneseDate japaneseDate) {
        final JapaneseEra thisEra = japaneseDate.getEra();

        // Valid Japanese Year range with the same given day & month & era.
        ValueRange validYearRange = japaneseDate.range(ChronoField.YEAR_OF_ERA); // Ex: 1-64

        // Valid Max Japanese year with the same given day & month
        int validMaxYear = (int) validYearRange.getMaximum(); // Ex: 64

        final JapaneseDate jpDate2 = JapaneseDate.of(thisEra, validMaxYear, 1, 1);
        ValueRange dayOfY2 = jpDate2.range(ChronoField.DAY_OF_YEAR);

        // Last date in the same year with jpDate2.
        final JapaneseDate jpDate3 = jpDate2.plus(dayOfY2.getMaximum() - dayOfY2.getMinimum(), ChronoUnit.DAYS);

        final JapaneseDate jpDate4 = jpDate3.plus(1, ChronoUnit.DAYS);
        final JapaneseEra era4 = jpDate4.getEra();

        if (!thisEra.equals(era4)) {
            return jpDate3;
        }
        ValueRange dayOfY4 = jpDate4.range(ChronoField.DAY_OF_YEAR);
        // Last date in the same Era with given japaneseDate.
        final JapaneseDate jpDate5 = jpDate4.plus(dayOfY4.getMaximum() - dayOfY4.getMinimum(), ChronoUnit.DAYS);
        return jpDate5;
    }

    public static JapaneseDate getFirstDateInEra(final JapaneseEra era) {
        JapaneseDate jpDate = FIRST_SUPPORTED_JP_DATE;
        while (true) {
            JapaneseEra jpEra = jpDate.getEra();
            if (era.equals(jpEra)) {
                return getFirstDateInSameEra(jpDate);
            }
            jpDate = getLastDateInSameEra(jpDate);
            jpDate = jpDate.plus(1, ChronoUnit.DAYS); // First Date in next era.
        }
    }

    public static JapaneseDate getLastDateInEra(final JapaneseEra era) {
        JapaneseDate jpDate = FIRST_SUPPORTED_JP_DATE;
        while (true) {
            JapaneseEra jpEra = jpDate.getEra();
            if (era.equals(jpEra)) {
                return getLastDateInSameEra(jpDate);
            }
            jpDate = getLastDateInSameEra(jpDate);
            jpDate = jpDate.plus(1, ChronoUnit.DAYS); // First Date in next era.
        }
    }
}
Example: Print the first and the last day of each era in the Japanese imperial calendar system supported by Java.
JapaneseEra_printAllEras_ex1.java
for (JapaneseEra era : JapaneseEra.values()) {
    JapaneseDate jpFirstDate = JapaneseEraUtils.getFirstDateInEra(era);
    JapaneseDate jpLastDate = JapaneseEraUtils.getLastDateInEra(era);

    System.out.printf("Era: %s, era.getValue(): %d%n", era, era.getValue());
    System.out.printf(" >> First Date: %s ~ ISO Date: %s%n", jpFirstDate, LocalDate.from(jpFirstDate));
    System.out.printf(" >> Last Date: %s ~ ISO Date: %s%n%n", jpLastDate, LocalDate.from(jpLastDate));
}
Output:
Era: Meiji, era.getValue(): -1
 >> First Date: Japanese Meiji 6-01-01 ~ ISO Date: 1873-01-01
 >> Last Date: Japanese Meiji 45-07-29 ~ ISO Date: 1912-07-29

Era: Taisho, era.getValue(): 0
 >> First Date: Japanese Taisho 1-07-30 ~ ISO Date: 1912-07-30
 >> Last Date: Japanese Taisho 15-12-24 ~ ISO Date: 1926-12-24

Era: Showa, era.getValue(): 1
 >> First Date: Japanese Showa 1-12-25 ~ ISO Date: 1926-12-25
 >> Last Date: Japanese Showa 64-01-07 ~ ISO Date: 1989-01-07

Era: Heisei, era.getValue(): 2
 >> First Date: Japanese Heisei 1-01-08 ~ ISO Date: 1989-01-08
 >> Last Date: Japanese Heisei 31-04-30 ~ ISO Date: 2019-04-30

Era: Reiwa, era.getValue(): 3
 >> First Date: Japanese Reiwa 1-05-01 ~ ISO Date: 2019-05-01
 >> Last Date: Japanese Reiwa 292276977-04-04 ~ ISO Date: +292278995-04-04

4. of(int japaneseEra)

public static JapaneseEra of(int japaneseEra)

5. valueOf(String japaneseEra)

public static JapaneseEra valueOf(String japaneseEra)

6. values()

public static JapaneseEra[] values()

7. getValue()

public int getValue()

8. range(TemporalField)

public ValueRange range(TemporalField field)

9. getDisplayName(TextStyle, Locale)

public String getDisplayName(TextStyle style, Locale locale)