I'm handling a Minguo date parsing problem. Our system representing the year BEFORE ROC with negative sign -
.
- How to Parse Date Strings with π Japanese Numbers in Java DateTime API
- How to parse non-standard month names with DateTimeFormatter
- Parsing with Java 8 DateTimeFormatter and Spanish month names
After some reading, we came up a working solution:
Map<Long, String> eraSign = new HashMap<>();
eraSign.put((long) MinguoEra.BEFORE_ROC.getValue(), "-");
eraSign.put((long) MinguoEra.ROC.getValue(), "");
DateTimeFormatter dtf= new DateTimeFormatterBuilder().parseStrict() // Strictly parsing
.appendText(ChronoField.ERA, eraSign).appendPattern("yyyMMdd") // date pattern with era prefix
.parseDefaulting(ChronoField.ERA, MinguoEra.ROC.getValue()) // default to Minguo era
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) // default to January
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1) // default to 1st
.toFormatter().withChronology(MinguoChronology.INSTANCE);
dtf.parse("-0170417"); // AD 1895/04/17
However, this method limit us putting the era at somewhere fixed, and we can't parse date like 17-April, -17
unless we create new formatter with new rule .appendPattern("d-MMM, ").appendText(ERA, eraSign).appendPattern("y")
.
Instead of predefining all possible patterns, I'm searching a way processing the minus sign from pattern directly, without calling .appendText(TemporalField, Map<Long, String>)
:
// something like this
DateTimeFormatter dtf= new DateTimeFormatterBuilder().parseStrict() // Strictly parsing
.appendPattern("GyyyMMdd") // full date pattern
.parseDefaulting(ChronoField.ERA, MinguoEra.ROC.getValue()) // default to Minguo era
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) // default to January
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1) // default to 1st
.toFormatter().withChronology(MinguoChronology.INSTANCE);
dtf.parse("-0170417");
// or even shorter:
DateTimeFormatter.ofPattern("GyyyMMdd").parse("-0170417");
The pattern may be GyyyMMdd
, G yyy
, G
or whatever (provided by caller). The era pattern symbol can be the default G
or something else we agreed.
It seems that changing Locale doesn't work. The Locale.Builder doesn't contain any information related to DateTimeFormat, neither.
How can I parse the input with pattern directly?