8077640: DateTimeFormatter does not parse/accept the era.toString() result from MinguoEra/ThaiBuddhistEra
authorsherman
Mon, 13 Apr 2015 11:15:41 -0700
changeset 29877 b6b5d166d055
parent 29876 b8e4a70cd0d8
child 29878 a76077f83d26
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
jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
jdk/test/java/time/test/java/time/format/TestTextParser.java
--- 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));
+    }
+
 }