I've run across a strange issue when testing some method of mine and I seem to have been able to obtain a concrete example of my issue.
I am using the ja_JP_JP_#u-ca-japanese
locale not able to parse a date using it's own date pattern defined by the locale.
I am wondering whether I am doing something wrong, or if this is a JDK bug.
Please note that in order to construct ja_JP_JP_#u-ca-japanese
, you need to use new Locale("ja", "JP", "JP")
as per excerpt from the Locale javadoc:
Special cases
For compatibility reasons, two non-conforming locales are treated as special cases. These are ja_JP_JP and th_TH_TH. These are ill-formed in BCP 47 since the variants are too short. To ease migration to BCP 47, these are treated specially during construction. These two cases (and only these) cause a constructor to generate an extension, all other values behave exactly as they did prior to Java 7.
Java has used ja_JP_JP to represent Japanese as used in Japan together with the Japanese Imperial calendar. This is now representable using a Unicode locale extension, by specifying the Unicode locale key ca (for "calendar") and type japanese. When the Locale constructor is called with the arguments "ja", "JP", "JP", the extension "u-ca-japanese" is automatically added.
Java has used th_TH_TH to represent Thai as used in Thailand together with Thai digits. This is also now representable using a Unicode locale extension, by specifying the Unicode locale key nu (for "number") and value thai. When the Locale constructor is called with the arguments "th", "TH", "TH", the extension "u-nu-thai" is automatically added.
The given test case that demonstrates the problem:
@Test
public void testJapaneseLocale() {
LocalDate specificLocalDate = LocalDate.of(2014, 10, 2);
Locale jpLocale = new Locale("ja", "JP", "JP");
DateTimeFormatter jpDateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(jpLocale);
String jpDate = specificLocalDate.format(jpDateTimeFormatter);
String jpPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, null, Chronology.ofLocale(jpLocale), jpLocale);
LocalDate jpLocalDate = LocalDate.parse(jpDate, DateTimeFormatter.ofPattern(jpPattern, jpLocale));
assertEquals(specificLocalDate, jpLocalDate);
}
This code does work for any other normal locale, such as english, etc.
DateTimeFormatterBuilder Class in Java. DateTimeFormatterBuilder Class is a builder class that is used to create date-time formatters. DateTimeFormatter is used as a Formatter for printing and parsing date-time objects.
Class DateTimeFormatter. Formatter for printing and parsing date-time objects. This class provides the main application entry point for printing and parsing and provides common implementations of DateTimeFormatter : Using predefined constants, such as ISO_LOCAL_DATE.
Parsing date and time To create a LocalDateTime object from a string you can use the static LocalDateTime. parse() method. It takes a string and a DateTimeFormatter as parameter. The DateTimeFormatter is used to specify the date/time pattern.
The round tripping ability does work, but it needs all the data to be made available.
In the first case, you need to specify both the locale and the chronology using the withLocale()
and withChronology()
methods:
LocalDate date = LocalDate.of(2014, 10, 2);
Locale jpLocale = new Locale("ja", "JP", "JP");
Chronology chrono = Chronology.ofLocale(jpLocale);
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(jpLocale)
.withChronology(chrono);
String jpDateStr = date.format(f);
LocalDate result = LocalDate.parse(jpDateStr, f);
The same is true of the second case, where using ofPattern()
locks the locale, but not the chronology:
String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, null, chrono, jpLocale);
DateTimeFormatter f = DateTimeFormatter.ofPattern(pattern, jpLocale)
.withChronology(chrono);
LocalDate jpLocalDate = LocalDate.parse(jpDateStr, f);
Only when both locale and chronology are available and used will round tripping be possible. Your issue is based around trying to format using the Japanese locale, but inconsistently applying the Japanese chronology.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With