🇯🇵 Uma Nova Era (Japonesa) para o Java!
No dia a dia, o Japão usa o mesmo calendário que a maior parte do mundo, no qual estamos atualmente no ano de 2019 (da era comum). Para documentos oficiais e formais, o calendário japonês usa o mesmo dia e mês, mas um nome de era e anos dentro dessa era, em vez do ano da era comum. A era japonesa atual é Heisei (平成) e o ano de 2019 corresponde a Heisei 31.
🗾 Compreendendo as Eras Japonesas
No Japão moderno, uma era começa com a ascensão de um novo imperador e dura até a ascensão do próximo imperador. Por exemplo, a era 明治 Meiji durou até 30 de julho de 1912 (30 de julho Meiji 45). A era seguinte, 大正 Taishō, começou em 31 de julho de 1912 com a ascensão do Imperador Taishō. A primeira data seria 31 de julho Taishō 1, exceto que o primeiro ano de novas eras é sempre referido como 元年 (Gan-nen). Seria escrito como “31 de julho 大正元年” (Taishō Gan-nen).
Em 2016, o Imperador Akihito anunciou planos de abdicar do trono em favor de seu filho, o Príncipe Herdeiro Naruhito. O plano era abdicar em 30 de abril de 2019 (30 de abril Heisei 31). O nome da nova era, que começaria em 1º de maio de 2019, seria anunciado pelo gabinete japonês em 1º de abril de 2019.
⚙️ Preparativos no JDK para a Nova Era
Foram necessários alguns preparativos para a nova era, mas atualizações finais só poderiam ser concluídas após o anúncio oficial do nome da nova era. No JDK, especificamente, algumas mudanças foram planejadas:
- Ao converter uma data Gregoriana para sua data equivalente no calendário japonês e renderizá-la como texto, é necessário saber o nome da era correto.
- A operação inversa, converter uma string representando uma data na data correta, requer analisar o nome da era e saber a qual ano da era comum ela corresponde.
- O Unicode adicionaria um novo caractere quadrado representando o nome da nova era.
A partir do JDK 8, as APIs Java possuem uma nova Data Time API (consulte o JSR 310), além da classe mais antiga java.util.Calendar, com métodos para manipular datas. Todas as APIs relevantes seriam atualizadas para lidar corretamente com a nova era.
Em preparação para as mudanças, o JDK 12 usaria um nome provisório para a nova era: 元号 (“NewEra”). Usando o JDK 12, seria possível ter uma ideia de como o nome da nova era seria tratado nas atualizações lançadas após o anúncio do nome.
Após o lançamento do nome da nova era, com a próxima atualização (planejada para 16 de abril de 2019), todas as versões suportadas do JDK: 7, 8, 11 LTS e 12 seriam atualizadas para lidar com a nova era.
💻 Exemplos de Código: Antes e Depois da Atualização
Em todas as versões suportadas, a classe java.util.Calendar seria atualizada para entender e retornar os valores corretos.
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());
// Antes da atualização: 平成31年5⽉1⽇
// Depois da atualização: 元号元年5⽉1⽇
// Nas versões lançadas após o novo anúncio, 元号 será substituído pelo novo nome da era.
A análise de uma data usando java.text.SimpleDateFormat funcionaria corretamente:
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⽇"));
// Resultado: “2020-2-1”
// Com 元号 substituído pelo novo nome da era
Para JDK 8 e posteriores, as novas APIs de data e hora JSR 310 também seriam atualizadas (JDK 7 não possui essas novas 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));
// Resultado: “元号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⽇"));
// Resultado: “2020-2-1”
JapaneseEra.of(3).getDisplayName(TextStyle.FULL,
Locale.forLanguageTag("ja-JP-u-ca-japanese"));
// Resultado: “元号”
// Com 元号 substituído pelo novo nome da era
No JDK 8 e posterior, o ponto de código Unicode U+32FF também seria incluído na classe java.lang.Character. O ponto de código U+32FF é reservado para o caractere quadrado da nova era japonesa.
✅ Resumo das Atualizações
Em resumo:
- As atualizações do JDK lançadas após o anúncio do novo nome da era japonesa lidariam corretamente com o novo nome da era.
- Até o nome da era ser divulgado, o JDK 12 (e, em menor extensão, o JDK 11) funcionaria de maneira semelhante à futura, mas usando 元号 como um nome provisório (*).
(*) Devido a um problema na análise de uma data em formato de string, seria necessário aguardar as atualizações do JDK de abril de 2019 para que a análise funcionasse corretamente.