In day-to-day situations Japan uses the same calendar as most of the world, according to which we are currently in the year 2019 (of the common era). For official and formal documents, the Japanese calendar uses the same day and month but an era name and years-within-that-era instead of the common era year. The current Japanese era is Heisei (平成) and the year 2019 corresponds to Heisei 31.
In modern Japan, an era starts with the ascension of a new emperor and last until the ascension of the next emperor. For example, the 明治 Meiji era lasted until July 30 of 1912 (July 30 Meiji 45). The next era, 大正 Taishō, started on July 31 of 1912 with the ascension of the Taishō Emperor (upon his death an emperor is thereafter referred to by the era of his reign). You could think of this date as July 31 Taishō 1, except that the first year of new eras are always referred to as 元年(Gan-nen). It would be written instead as “July 31 大正元年” (Taishō Gan-nen). Note that, unless a new emperor were to ascend on exactly Jan 1, the first year of the new era is shorter than a full calendar year as the first year ends on Dec 31 regardless of which day it started.
In 2016 Emperor Akihito announced plans to abdicate the throne in favor of his son Crown Prince Naruhito. The Emperor plans to abdicate on April 30, 2019 (April 30 Heisei 31). On April 1, 2019, the Japanese cabinet will announce the name of the new era which will start on May 1, 2019.
We have taken some steps to prepare for the new era but have to wait until the final announcement, with the new era name, to finalize the updates.
In the JDK in particular, there are a few changes:
Starting with JDK 8 the Java APIs have a new Data Time API (see JSR 310), as well as the older java.util.Calendar class, with methods for handling dates. All relevant APIs have been updated to correctly handle the new era.
In preparation to the new era changes, JDK 12 uses a placeholder name for the new era: 元号 (“NewEra”). Using JDK 12 you can get a feel for how the new era name will be handled on updates released after the new era name is announced.
After the new era name is released, with the next update release (planned for April 16, 2019), all supported JDK releases: 7, 8, 11 LTS, and 12 will be updated to handle the new era.
In all of them, the java.util.Calendar class will be updated to understand and return the correct values:
import java.util.*; import java.text.*; new SimpleDateFormat("GGGGyyyy年M月d日", Locale.forLanguageTag("ja-JP-u-ca-japanese")). format(new Calendar.Builder(). setDate(2019, Calendar.MAY, 1).build().getTime()); //before the update: 平成31年5⽉1⽇, after the update: 元号元年5⽉1⽇ //On versions released after new announcement the 元号 will be replaced with the new era name
and parsing a date using java.text.SimpleDateFormat will work correctly:
import java.text.*; var sdf = new SimpleDateFormat("GGGGyyyy年M⽉d⽇", Locale.forLanguageTag("ja-JP-u-ca-japanese")); sdf.setLenient(false); new SimpleDateFormat("Y-M-d", Locale.US).format(sdf.parse("元号2年2⽉1⽇")); // => “2020-2-1” // with 元号 replaced with the new era name
For JDK 8 and later we will also update the new JSR 310 date-time APIs (JDK 7 doesn’t have these new APIs)
import java.time.chrono.*; import java.time.format.*; import java.time.temporal.*; DateTimeFormatter.ofPattern("GGGGy年M⽉d⽇"). withChronology(JapaneseChronology.INSTANCE). withLocale(Locale.JAPAN). format(JapaneseDate.of(2020, 2, 1)); // => “元号2年2⽉1⽇” DateTimeFormatter.ofPattern("u-M-d").format( DateTimeFormatter.ofPattern("GGGGy年M⽉d⽇"). withChronology(JapaneseChronology.INSTANCE). withLocale(Locale.JAPAN). withResolverStyle(ResolverStyle.STRICT). parse("元号2年2⽉1⽇")); // => “2020-2-1” JapaneseEra.of(3).getDisplayName(TextStyle.FULL, Locale.forLanguageTag("ja-JP-u-ca-japanese")); // => “元号” // with 元号 replaced with the new era name
On JDK 8 and later we will also include Unicode U+32FF code point in java.lang.Character class. The U+32FF code point is reserved for the square character of the Japanese new era.
(*) Due to an issue with how parsing a date in string format works you will have to wait for the April 2019 JDK updates for parsing to work correctly.
To learn more: