DateTimeFormatter template with lettering and without separator does not work

The parser generated DateTimeFormatter.ofPatterndemonstrates the following interesting behavior that prevents me from writing a template for parsing a string like 20150100:

System.out.println(DateTimeFormatter.ofPattern("yyyyMM").parse("201501", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'aa'").parse("201501aa", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'00'").parse("20150100", YearMonth::from));
// java.time.format.DateTimeParseException: Text '20150100' could not be parsed at index 0

I debugged the code, it seems that the problem is caused by parsing the year field outside the line (the maximum width for three or more is always equal to 19). However, I don’t understand how this could work for a template without a literal '00'at the end.

Is there a way to fix this while having to use a format builder?

Edit:

Since Jarrod below confirmed this as an error, I did more searches and finally found error reports:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8031085

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8032491

Java 9, ......

+4
2

DateTimePrinterParser :

, , . , DateTimeFormatterBuilder.parse(), , .

-, Value(YearOfEra,4,19,EXCEEDS_PAD) 00, , , 4 19. DateTimeFormatter, DateTimeParseContext, .

, xx, , .

:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'00'");
System.out.println(sdf.parse("20150100"));

"main" java.text.ParseException: : "20150100" java.text.DateFormat.parse(DateFormat.java:366)

final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'00'");
System.out.println(dateTimeFormatter.parse("20150100", YearMonth::from));

"main" java.time.format.DateTimeParseException: '20150100' 0 java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1949)    java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'xx'");
System.out.println(sdf.parse("201501xx"));

Thu Jan 01 00:00:00 EST 2015

final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'xx'");
System.out.println(dateTimeFormatter.parse("201501xx", YearMonth::from));

2015-01

+4

, Time4J, v4. 18 , :

import net.time4j.Month;
import net.time4j.range.CalendarMonth;
import net.time4j.format.expert.ChronoFormatter;
import net.time4j.format.expert.PatternType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.text.ParseException;
import java.util.Locale;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

@RunWith(JUnit4.class)
public class CalendarMonthTest {
    @Test
    public void parse2() throws ParseException {
      assertThat(
        ChronoFormatter.ofPattern(
            "yyyyMM'00'",
            PatternType.CLDR,
            Locale.ROOT,
            CalendarMonth.chronology()
        ).parse("20150100"),
        is(CalendarMonth.of(2015, Month.JANUARY)));
    }
}

, JDK- . . ​​ Java-9, . , ? , Oracle . , - , Oracle. () JSR-310 (aka java.time-package), ( SimpleDateFormat ).

: Time4J - ( ), , , JSR-310 - . : YearMonth, calendarMonth.toTemporalAccessor() .

0

Source: https://habr.com/ru/post/1652495/


All Articles