Allow single digit milliseconds in strict date parsing (#40676)

In order to remain compatible with the existing joda based
implementation the parsing of milliseconds should support parsing single
digits instead of relying on three, even with strict formats.

This adds a few tests to duel against the existing joda based
implementation in order to ensure the parsing behaviour is the same.

Closes #40403
This commit is contained in:
Alexander Reelsen 2019-04-02 10:26:54 +02:00
parent 7bdd41399d
commit c644fbfc6e
2 changed files with 77 additions and 8 deletions

View File

@ -456,7 +456,7 @@ public class DateFormatters {
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
.appendFraction(NANO_OF_SECOND, 3, 9, true)
.appendFraction(NANO_OF_SECOND, 1, 9, true)
.appendZoneOrOffsetId()
.toFormatter(Locale.ROOT),
new DateTimeFormatterBuilder()
@ -465,7 +465,7 @@ public class DateFormatters {
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
.appendFraction(NANO_OF_SECOND, 3, 9, true)
.appendFraction(NANO_OF_SECOND, 1, 9, true)
.append(TIME_ZONE_FORMATTER_NO_COLON)
.toFormatter(Locale.ROOT)
);
@ -517,12 +517,20 @@ public class DateFormatters {
private static final DateFormatter STRICT_HOUR_MINUTE_SECOND =
new JavaDateFormatter("strict_hour_minute_second", STRICT_HOUR_MINUTE_SECOND_FORMATTER);
private static final DateTimeFormatter STRICT_DATE_PRINTER = new DateTimeFormatterBuilder()
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
.appendLiteral('T')
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
.appendFraction(NANO_OF_SECOND, 3, 9, true)
.appendOffset("+HH:MM", "Z")
.toFormatter(Locale.ROOT);
private static final DateTimeFormatter STRICT_DATE_FORMATTER = new DateTimeFormatterBuilder()
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
.appendLiteral('T')
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
.optionalStart()
.appendFraction(NANO_OF_SECOND, 3, 9, true)
.appendFraction(NANO_OF_SECOND, 1, 9, true)
.optionalEnd()
.toFormatter(Locale.ROOT);
@ -530,8 +538,7 @@ public class DateFormatters {
* Returns a formatter that combines a full date and time, separated by a 'T'
* (yyyy-MM-dd'T'HH:mm:ss.SSSZZ).
*/
private static final DateFormatter STRICT_DATE_TIME = new JavaDateFormatter("strict_date_time",
new DateTimeFormatterBuilder().append(STRICT_DATE_FORMATTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT),
private static final DateFormatter STRICT_DATE_TIME = new JavaDateFormatter("strict_date_time", STRICT_DATE_PRINTER,
new DateTimeFormatterBuilder().append(STRICT_DATE_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT),
new DateTimeFormatterBuilder().append(STRICT_DATE_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT)
);
@ -653,7 +660,7 @@ public class DateFormatters {
private static final DateFormatter STRICT_HOUR_MINUTE =
new JavaDateFormatter("strict_hour_minute", DateTimeFormatter.ofPattern("HH:mm", Locale.ROOT));
private static final DateTimeFormatter STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE = new DateTimeFormatterBuilder()
private static final DateTimeFormatter STRICT_ORDINAL_DATE_TIME_PRINTER = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(DAY_OF_YEAR, 3, 3, SignStyle.NOT_NEGATIVE)
@ -666,12 +673,25 @@ public class DateFormatters {
.optionalEnd()
.toFormatter(Locale.ROOT);
private static final DateTimeFormatter STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(DAY_OF_YEAR, 3, 3, SignStyle.NOT_NEGATIVE)
.appendLiteral('T')
.appendPattern("HH:mm")
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
.appendFraction(NANO_OF_SECOND, 1, 9, true)
.optionalEnd()
.toFormatter(Locale.ROOT);
/*
* Returns a formatter for a full ordinal date and time, using a four
* digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ss.SSSZZ).
*/
private static final DateFormatter STRICT_ORDINAL_DATE_TIME = new JavaDateFormatter("strict_ordinal_date_time",
new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE)
new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_PRINTER)
.appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT),
new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE)
.appendZoneOrOffsetId().toFormatter(Locale.ROOT),
@ -1198,7 +1218,7 @@ public class DateFormatters {
* digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ss.SSSZZ).
*/
private static final DateFormatter ORDINAL_DATE_TIME = new JavaDateFormatter("ordinal_date_time",
new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE)
new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_PRINTER)
.appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT),
new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_FORMATTER_BASE)
.appendZoneOrOffsetId().toFormatter(Locale.ROOT),

View File

@ -100,6 +100,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("20181126T121212+01:00", "basic_date_time_no_millis");
assertSameDate("20181126T121212+0100", "basic_date_time_no_millis");
assertSameDate("2018363", "basic_ordinal_date");
assertSameDate("2018363T121212.1Z", "basic_ordinal_date_time");
assertSameDate("2018363T121212.123Z", "basic_ordinal_date_time");
assertSameDate("2018363T121212.123456789Z", "basic_ordinal_date_time");
assertSameDate("2018363T121212.123+0100", "basic_ordinal_date_time");
@ -107,15 +108,19 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018363T121212Z", "basic_ordinal_date_time_no_millis");
assertSameDate("2018363T121212+0100", "basic_ordinal_date_time_no_millis");
assertSameDate("2018363T121212+01:00", "basic_ordinal_date_time_no_millis");
assertSameDate("121212.1Z", "basic_time");
assertSameDate("121212.123Z", "basic_time");
assertSameDate("121212.123456789Z", "basic_time");
assertSameDate("121212.1+0100", "basic_time");
assertSameDate("121212.123+0100", "basic_time");
assertSameDate("121212.123+01:00", "basic_time");
assertSameDate("121212Z", "basic_time_no_millis");
assertSameDate("121212+0100", "basic_time_no_millis");
assertSameDate("121212+01:00", "basic_time_no_millis");
assertSameDate("T121212.1Z", "basic_t_time");
assertSameDate("T121212.123Z", "basic_t_time");
assertSameDate("T121212.123456789Z", "basic_t_time");
assertSameDate("T121212.1+0100", "basic_t_time");
assertSameDate("T121212.123+0100", "basic_t_time");
assertSameDate("T121212.123+01:00", "basic_t_time");
assertSameDate("T121212Z", "basic_t_time_no_millis");
@ -124,6 +129,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018W313", "basic_week_date");
assertSameDate("1W313", "basic_week_date");
assertSameDate("18W313", "basic_week_date");
assertSameDate("2018W313T121212.1Z", "basic_week_date_time");
assertSameDate("2018W313T121212.123Z", "basic_week_date_time");
assertSameDate("2018W313T121212.123456789Z", "basic_week_date_time");
assertSameDate("2018W313T121212.123+0100", "basic_week_date_time");
@ -145,8 +151,10 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-12-31T12:12:12", "date_hour_minute_second");
assertSameDate("2018-12-31T12:12:1", "date_hour_minute_second");
assertSameDate("2018-12-31T12:12:12.1", "date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.123", "date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.123456789", "date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.1", "date_hour_minute_second_millis");
assertSameDate("2018-12-31T12:12:12.123", "date_hour_minute_second_millis");
assertParseException("2018-12-31T12:12:12.123456789", "date_hour_minute_second_millis");
assertSameDate("2018-12-31T12:12:12.1", "date_hour_minute_second_millis");
@ -157,11 +165,14 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-05-30T20", "date_optional_time");
assertSameDate("2018-05-30T20:21", "date_optional_time");
assertSameDate("2018-05-30T20:21:23", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.1", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123456789", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123Z", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123456789Z", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.1+0100", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123+0100", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.1+01:00", "date_optional_time");
assertSameDate("2018-05-30T20:21:23.123+01:00", "date_optional_time");
assertSameDate("2018-12-1", "date_optional_time");
assertSameDate("2018-12-31T10:15:30", "date_optional_time");
@ -169,17 +180,23 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-12-31T10:5:30", "date_optional_time");
assertSameDate("2018-12-31T1:15:30", "date_optional_time");
assertSameDate("2018-12-31T10:15:30.1Z", "date_time");
assertSameDate("2018-12-31T10:15:30.123Z", "date_time");
assertSameDate("2018-12-31T10:15:30.123456789Z", "date_time");
assertSameDate("2018-12-31T10:15:30.1+0100", "date_time");
assertSameDate("2018-12-31T10:15:30.123+0100", "date_time");
assertSameDate("2018-12-31T10:15:30.123+01:00", "date_time");
assertSameDate("2018-12-31T10:15:30.1+01:00", "date_time");
assertSameDate("2018-12-31T10:15:30.11Z", "date_time");
assertSameDate("2018-12-31T10:15:30.11+0100", "date_time");
assertSameDate("2018-12-31T10:15:30.11+01:00", "date_time");
assertSameDate("2018-12-31T10:15:3.1Z", "date_time");
assertSameDate("2018-12-31T10:15:3.123Z", "date_time");
assertSameDate("2018-12-31T10:15:3.123456789Z", "date_time");
assertSameDate("2018-12-31T10:15:3.1+0100", "date_time");
assertSameDate("2018-12-31T10:15:3.123+0100", "date_time");
assertSameDate("2018-12-31T10:15:3.123+01:00", "date_time");
assertSameDate("2018-12-31T10:15:3.1+01:00", "date_time");
assertSameDate("2018-12-31T10:15:30Z", "date_time_no_millis");
assertSameDate("2018-12-31T10:15:30+0100", "date_time_no_millis");
@ -218,10 +235,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-128", "ordinal_date");
assertSameDate("2018-1", "ordinal_date");
assertSameDate("2018-128T10:15:30.1Z", "ordinal_date_time");
assertSameDate("2018-128T10:15:30.123Z", "ordinal_date_time");
assertSameDate("2018-128T10:15:30.123456789Z", "ordinal_date_time");
assertSameDate("2018-128T10:15:30.123+0100", "ordinal_date_time");
assertSameDate("2018-128T10:15:30.123+01:00", "ordinal_date_time");
assertSameDate("2018-1T10:15:30.1Z", "ordinal_date_time");
assertSameDate("2018-1T10:15:30.123Z", "ordinal_date_time");
assertSameDate("2018-1T10:15:30.123456789Z", "ordinal_date_time");
assertSameDate("2018-1T10:15:30.123+0100", "ordinal_date_time");
@ -234,16 +253,20 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-1T10:15:30+0100", "ordinal_date_time_no_millis");
assertSameDate("2018-1T10:15:30+01:00", "ordinal_date_time_no_millis");
assertSameDate("10:15:30.1Z", "time");
assertSameDate("10:15:30.123Z", "time");
assertSameDate("10:15:30.123456789Z", "time");
assertSameDate("10:15:30.123+0100", "time");
assertSameDate("10:15:30.123+01:00", "time");
assertSameDate("1:15:30.1Z", "time");
assertSameDate("1:15:30.123Z", "time");
assertSameDate("1:15:30.123+0100", "time");
assertSameDate("1:15:30.123+01:00", "time");
assertSameDate("10:1:30.1Z", "time");
assertSameDate("10:1:30.123Z", "time");
assertSameDate("10:1:30.123+0100", "time");
assertSameDate("10:1:30.123+01:00", "time");
assertSameDate("10:15:3.1Z", "time");
assertSameDate("10:15:3.123Z", "time");
assertSameDate("10:15:3.123+0100", "time");
assertSameDate("10:15:3.123+01:00", "time");
@ -267,10 +290,13 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("10:15:3+01:00", "time_no_millis");
assertParseException("10:15:3", "time_no_millis");
assertSameDate("T10:15:30.1Z", "t_time");
assertSameDate("T10:15:30.123Z", "t_time");
assertSameDate("T10:15:30.123456789Z", "t_time");
assertSameDate("T10:15:30.1+0100", "t_time");
assertSameDate("T10:15:30.123+0100", "t_time");
assertSameDate("T10:15:30.123+01:00", "t_time");
assertSameDate("T10:15:30.1+01:00", "t_time");
assertSameDate("T1:15:30.123Z", "t_time");
assertSameDate("T1:15:30.123+0100", "t_time");
assertSameDate("T1:15:30.123+01:00", "t_time");
@ -305,12 +331,18 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
"Cannot parse \"2012-W1-8\": Value 8 for dayOfWeek must be in the range [1,7]");
assertJavaTimeParseException("2012-W1-8", "week_date");
assertSameDate("2012-W48-6T10:15:30.1Z", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.123Z", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.123456789Z", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.1+0100", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.123+0100", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.1+01:00", "week_date_time");
assertSameDate("2012-W48-6T10:15:30.123+01:00", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.1Z", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.123Z", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.1+0100", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.123+0100", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.1+01:00", "week_date_time");
assertSameDate("2012-W1-6T10:15:30.123+01:00", "week_date_time");
assertSameDate("2012-W48-6T10:15:30Z", "week_date_time_no_millis");
@ -357,9 +389,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
public void testDuelingStrictParsing() {
assertSameDate("2018W313", "strict_basic_week_date");
assertParseException("18W313", "strict_basic_week_date");
assertSameDate("2018W313T121212.1Z", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.123Z", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.123456789Z", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.1+0100", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.123+0100", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.1+01:00", "strict_basic_week_date_time");
assertSameDate("2018W313T121212.123+01:00", "strict_basic_week_date_time");
assertParseException("2018W313T12128.123Z", "strict_basic_week_date_time");
assertParseException("2018W313T12128.123456789Z", "strict_basic_week_date_time");
@ -387,6 +422,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertParseException("2018-12-31T8:3", "strict_date_hour_minute");
assertSameDate("2018-12-31T12:12:12", "strict_date_hour_minute_second");
assertParseException("2018-12-31T12:12:1", "strict_date_hour_minute_second");
assertSameDate("2018-12-31T12:12:12.1", "strict_date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.123", "strict_date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.123456789", "strict_date_hour_minute_second_fraction");
assertSameDate("2018-12-31T12:12:12.123", "strict_date_hour_minute_second_millis");
@ -407,9 +443,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertParseException("2018-12-31T10:5:30", "strict_date_optional_time");
assertParseException("2018-12-31T9:15:30", "strict_date_optional_time");
assertSameDate("2015-01-04T00:00Z", "strict_date_optional_time");
assertSameDate("2018-12-31T10:15:30.1Z", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.123Z", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.123456789Z", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.1+0100", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.123+0100", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.1+01:00", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.123+01:00", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.11Z", "strict_date_time");
assertSameDate("2018-12-31T10:15:30.11+0100", "strict_date_time");
@ -442,9 +481,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-128", "strict_ordinal_date");
assertParseException("2018-1", "strict_ordinal_date");
assertSameDate("2018-128T10:15:30.1Z", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.123Z", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.123456789Z", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.1+0100", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.123+0100", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.1+01:00", "strict_ordinal_date_time");
assertSameDate("2018-128T10:15:30.123+01:00", "strict_ordinal_date_time");
assertParseException("2018-1T10:15:30.123Z", "strict_ordinal_date_time");
@ -453,6 +495,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertSameDate("2018-128T10:15:30+01:00", "strict_ordinal_date_time_no_millis");
assertParseException("2018-1T10:15:30Z", "strict_ordinal_date_time_no_millis");
assertSameDate("10:15:30.1Z", "strict_time");
assertSameDate("10:15:30.123Z", "strict_time");
assertSameDate("10:15:30.123456789Z", "strict_time");
assertSameDate("10:15:30.123+0100", "strict_time");
@ -474,9 +517,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
assertParseException("10:15:3Z", "strict_time_no_millis");
assertParseException("10:15:3", "strict_time_no_millis");
assertSameDate("T10:15:30.1Z", "strict_t_time");
assertSameDate("T10:15:30.123Z", "strict_t_time");
assertSameDate("T10:15:30.123456789Z", "strict_t_time");
assertSameDate("T10:15:30.1+0100", "strict_t_time");
assertSameDate("T10:15:30.123+0100", "strict_t_time");
assertSameDate("T10:15:30.1+01:00", "strict_t_time");
assertSameDate("T10:15:30.123+01:00", "strict_t_time");
assertParseException("T1:15:30.123Z", "strict_t_time");
assertParseException("T10:1:30.123Z", "strict_t_time");
@ -505,9 +551,12 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
"Cannot parse \"2012-W01-8\": Value 8 for dayOfWeek must be in the range [1,7]");
assertJavaTimeParseException("2012-W01-8", "strict_week_date");
assertSameDate("2012-W48-6T10:15:30.1Z", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.123Z", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.123456789Z", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.1+0100", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.123+0100", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.1+01:00", "strict_week_date_time");
assertSameDate("2012-W48-6T10:15:30.123+01:00", "strict_week_date_time");
assertParseException("2012-W1-6T10:15:30.123Z", "strict_week_date_time");