8077640: DateTimeFormatter does not parse/accept the era.toString() result from MinguoEra/ThaiBuddhistEra
Summary: to parse and accept the era.toString() for era parsing in lenient/smart mode
Reviewed-by: rriggs
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Mon Apr 13 14:58:47 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Mon Apr 13 11:15:41 2015 -0700
@@ -70,6 +70,7 @@
import static java.time.temporal.ChronoField.OFFSET_SECONDS;
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoField.ERA;
import java.lang.ref.SoftReference;
import java.math.BigDecimal;
@@ -84,6 +85,7 @@
import java.time.ZoneOffset;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.Chronology;
+import java.time.chrono.Era;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeTextProvider.LocaleStore;
import java.time.temporal.ChronoField;
@@ -3131,6 +3133,16 @@
return context.setParsedField(field, entry.getValue(), position, position + itText.length());
}
}
+ if (field == ERA && !context.isStrict()) {
+ // parse the possible era name from era.toString()
+ List<Era> eras = chrono.eras();
+ for (Era era : eras) {
+ String name = era.toString();
+ if (context.subSequenceEquals(name, 0, parseText, position, name.length())) {
+ return context.setParsedField(field, era.getValue(), position, position + name.length());
+ }
+ }
+ }
if (context.isStrict()) {
return ~position;
}
--- a/jdk/test/java/time/test/java/time/format/TestTextParser.java Mon Apr 13 14:58:47 2015 +0100
+++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java Mon Apr 13 11:15:41 2015 -0700
@@ -68,10 +68,20 @@
import java.text.ParsePosition;
import java.time.DayOfWeek;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistDate;
import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
+import java.time.format.SignStyle;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalQueries;
+import java.time.temporal.ChronoField;
import java.util.Locale;
import org.testng.annotations.DataProvider;
@@ -243,6 +253,8 @@
};
}
+
+
@Test(dataProvider="parseText")
public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception {
ParsePosition pos = new ParsePosition(0);
@@ -433,4 +445,42 @@
assertEquals(pos.getIndex(), input.length());
}
+ //-----------------------------------------------------------------------
+ @DataProvider(name="parseChronoLocalDate")
+ Object[][] provider_chronoLocalDate() {
+ return new Object[][] {
+ { HijrahDate.now() },
+ { JapaneseDate.now() },
+ { MinguoDate.now() },
+ { ThaiBuddhistDate.now() }};
+ }
+
+ private static final DateTimeFormatter fmt_chrono =
+ new DateTimeFormatterBuilder()
+ .optionalStart()
+ .appendChronologyId()
+ .appendLiteral(' ')
+ .optionalEnd()
+ .optionalStart()
+ .appendText(ChronoField.ERA, TextStyle.SHORT)
+ .appendLiteral(' ')
+ .optionalEnd()
+ .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
+ .appendLiteral('-')
+ .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
+ .appendLiteral('-')
+ .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
+ .toFormatter();
+
+ @Test(dataProvider="parseChronoLocalDate")
+ public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
+ System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
+ assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
+
+ DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
+ .withChronology(date.getChronology());
+ System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
+ assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
+ }
+
}