Skip to content

Commit 9ec4abc

Browse files
authored
Ensure date parsing BWC compatibility (#37929)
In order to retain BWC this changes the java date formatters to be able to parse nanoseconds resolution, even if only milliseconds are supported. This used to work on joda time as well so that a user could store a date like `2018-10-03T14:42:44.613469+0000` and then just loose the precision on anything lower than millisecond level.
1 parent 908c8de commit 9ec4abc

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

server/src/main/java/org/elasticsearch/common/time/DateFormatters.java

+29-23
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,6 @@ public class DateFormatters {
108108
.appendLiteral(':')
109109
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
110110
.optionalStart()
111-
.appendFraction(NANO_OF_SECOND, 3, 3, true)
112-
.optionalEnd()
113-
.optionalStart()
114111
.appendFraction(NANO_OF_SECOND, 3, 9, true)
115112
.optionalEnd()
116113
.optionalEnd()
@@ -205,7 +202,7 @@ public class DateFormatters {
205202
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
206203
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
207204
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
208-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
205+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
209206
.toFormatter(Locale.ROOT);
210207

211208
private static final DateTimeFormatter BASIC_TIME_PRINTER = new DateTimeFormatterBuilder()
@@ -311,7 +308,7 @@ public class DateFormatters {
311308
private static final DateFormatter BASIC_ORDINAL_DATE_TIME = new JavaDateFormatter("basic_ordinal_date_time",
312309
new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_PRINTER)
313310
.appendZoneOrOffsetId().toFormatter(Locale.ROOT),
314-
new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_PRINTER)
311+
new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER)
315312
.appendZoneOrOffsetId().toFormatter(Locale.ROOT),
316313
new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER)
317314
.append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT)
@@ -419,7 +416,7 @@ public class DateFormatters {
419416
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
420417
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
421418
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
422-
.appendFraction(NANO_OF_SECOND, 3, 3, true)
419+
.appendFraction(NANO_OF_SECOND, 3, 9, true)
423420
.appendZoneOrOffsetId()
424421
.toFormatter(Locale.ROOT),
425422
new DateTimeFormatterBuilder()
@@ -428,7 +425,7 @@ public class DateFormatters {
428425
.appendValue(HOUR_OF_DAY, 2, 2, SignStyle.NOT_NEGATIVE)
429426
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
430427
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
431-
.appendFraction(NANO_OF_SECOND, 3, 3, true)
428+
.appendFraction(NANO_OF_SECOND, 3, 9, true)
432429
.append(TIME_ZONE_FORMATTER_NO_COLON)
433430
.toFormatter(Locale.ROOT)
434431
);
@@ -485,7 +482,7 @@ public class DateFormatters {
485482
.appendLiteral('T')
486483
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
487484
.optionalStart()
488-
.appendFraction(NANO_OF_SECOND, 3, 3, true)
485+
.appendFraction(NANO_OF_SECOND, 3, 9, true)
489486
.optionalEnd()
490487
.toFormatter(Locale.ROOT);
491488

@@ -542,7 +539,7 @@ public class DateFormatters {
542539
// NOTE: this is not a strict formatter to retain the joda time based behaviour, even though it's named like this
543540
private static final DateTimeFormatter STRICT_HOUR_MINUTE_SECOND_MILLIS_FORMATTER = new DateTimeFormatterBuilder()
544541
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
545-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
542+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
546543
.toFormatter(Locale.ROOT);
547544

548545
private static final DateTimeFormatter STRICT_HOUR_MINUTE_SECOND_MILLIS_PRINTER = new DateTimeFormatterBuilder()
@@ -582,8 +579,8 @@ public class DateFormatters {
582579
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
583580
.appendLiteral("T")
584581
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
585-
// this one here is lenient as well to retain joda time based bwc compatibility
586-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
582+
// this one here is lenient as well to retain joda time based bwc compatibility
583+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
587584
.toFormatter(Locale.ROOT)
588585
);
589586

@@ -599,7 +596,7 @@ public class DateFormatters {
599596
.appendLiteral("T")
600597
.append(STRICT_HOUR_MINUTE_SECOND_FORMATTER)
601598
// this one here is lenient as well to retain joda time based bwc compatibility
602-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
599+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
603600
.toFormatter(Locale.ROOT)
604601
);
605602

@@ -625,7 +622,7 @@ public class DateFormatters {
625622
.optionalStart()
626623
.appendLiteral(':')
627624
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
628-
.appendFraction(NANO_OF_SECOND, 3, 3, true)
625+
.appendFraction(NANO_OF_SECOND, 3, 9, true)
629626
.optionalEnd()
630627
.toFormatter(Locale.ROOT);
631628

@@ -649,7 +646,7 @@ public class DateFormatters {
649646
.appendValue(MINUTE_OF_HOUR, 2, 2, SignStyle.NOT_NEGATIVE)
650647
.appendLiteral(':')
651648
.appendValue(SECOND_OF_MINUTE, 2, 2, SignStyle.NOT_NEGATIVE)
652-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
649+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
653650
.toFormatter(Locale.ROOT);
654651

655652
private static final DateTimeFormatter STRICT_TIME_PRINTER = new DateTimeFormatterBuilder()
@@ -880,7 +877,7 @@ public class DateFormatters {
880877
.appendValue(SECOND_OF_MINUTE, 1, 2, SignStyle.NOT_NEGATIVE)
881878
.optionalEnd()
882879
.optionalStart()
883-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
880+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
884881
.optionalEnd()
885882
.optionalStart().appendZoneOrOffsetId().optionalEnd()
886883
.optionalStart().appendOffset("+HHmm", "Z").optionalEnd()
@@ -904,6 +901,15 @@ public class DateFormatters {
904901
.appendFraction(NANO_OF_SECOND, 1, 3, true)
905902
.toFormatter(Locale.ROOT);
906903

904+
private static final DateTimeFormatter HOUR_MINUTE_SECOND_FRACTION_FORMATTER = new DateTimeFormatterBuilder()
905+
.appendValue(HOUR_OF_DAY, 1, 2, SignStyle.NOT_NEGATIVE)
906+
.appendLiteral(':')
907+
.appendValue(MINUTE_OF_HOUR, 1, 2, SignStyle.NOT_NEGATIVE)
908+
.appendLiteral(':')
909+
.appendValue(SECOND_OF_MINUTE, 1, 2, SignStyle.NOT_NEGATIVE)
910+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
911+
.toFormatter(Locale.ROOT);
912+
907913
private static final DateTimeFormatter ORDINAL_DATE_FORMATTER = new DateTimeFormatterBuilder()
908914
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
909915
.appendLiteral('-')
@@ -936,7 +942,7 @@ public class DateFormatters {
936942

937943
private static final DateTimeFormatter TIME_PREFIX = new DateTimeFormatterBuilder()
938944
.append(TIME_NO_MILLIS_FORMATTER)
939-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
945+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
940946
.toFormatter(Locale.ROOT);
941947

942948
private static final DateTimeFormatter WEEK_DATE_FORMATTER = new DateTimeFormatterBuilder()
@@ -974,8 +980,7 @@ public class DateFormatters {
974980
/*
975981
* Returns a formatter that combines a full date, two digit hour of day,
976982
* two digit minute of hour, two digit second of minute, and three digit
977-
* fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS). Parsing will parse up
978-
* to 3 fractional second digits.
983+
* fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS).
979984
*/
980985
private static final DateFormatter DATE_HOUR_MINUTE_SECOND_MILLIS =
981986
new JavaDateFormatter("date_hour_minute_second_millis",
@@ -990,7 +995,8 @@ public class DateFormatters {
990995
.append(HOUR_MINUTE_SECOND_MILLIS_FORMATTER)
991996
.toFormatter(Locale.ROOT));
992997

993-
private static final DateFormatter DATE_HOUR_MINUTE_SECOND_FRACTION = new JavaDateFormatter("date_hour_minute_second_fraction",
998+
private static final DateFormatter DATE_HOUR_MINUTE_SECOND_FRACTION =
999+
new JavaDateFormatter("date_hour_minute_second_fraction",
9941000
new DateTimeFormatterBuilder()
9951001
.append(STRICT_YEAR_MONTH_DAY_FORMATTER)
9961002
.appendLiteral("T")
@@ -999,7 +1005,7 @@ public class DateFormatters {
9991005
new DateTimeFormatterBuilder()
10001006
.append(DATE_FORMATTER)
10011007
.appendLiteral("T")
1002-
.append(HOUR_MINUTE_SECOND_MILLIS_FORMATTER)
1008+
.append(HOUR_MINUTE_SECOND_FRACTION_FORMATTER)
10031009
.toFormatter(Locale.ROOT));
10041010

10051011
/*
@@ -1034,7 +1040,7 @@ public class DateFormatters {
10341040
.optionalStart()
10351041
.appendLiteral(':')
10361042
.appendValue(SECOND_OF_MINUTE, 1, 2, SignStyle.NOT_NEGATIVE)
1037-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
1043+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
10381044
.optionalEnd()
10391045
.toFormatter(Locale.ROOT);
10401046

@@ -1106,7 +1112,7 @@ public class DateFormatters {
11061112
STRICT_HOUR_MINUTE_SECOND_MILLIS_PRINTER, HOUR_MINUTE_SECOND_MILLIS_FORMATTER);
11071113

11081114
private static final DateFormatter HOUR_MINUTE_SECOND_FRACTION = new JavaDateFormatter("hour_minute_second_fraction",
1109-
STRICT_HOUR_MINUTE_SECOND_MILLIS_PRINTER, HOUR_MINUTE_SECOND_MILLIS_FORMATTER);
1115+
STRICT_HOUR_MINUTE_SECOND_MILLIS_PRINTER, HOUR_MINUTE_SECOND_FRACTION_FORMATTER);
11101116

11111117
/*
11121118
* Returns a formatter for a two digit hour of day and two digit minute of
@@ -1142,7 +1148,7 @@ public class DateFormatters {
11421148
.optionalStart()
11431149
.appendLiteral(':')
11441150
.appendValue(SECOND_OF_MINUTE, 1, 2, SignStyle.NOT_NEGATIVE)
1145-
.appendFraction(NANO_OF_SECOND, 1, 3, true)
1151+
.appendFraction(NANO_OF_SECOND, 1, 9, true)
11461152
.optionalEnd()
11471153
.toFormatter(Locale.ROOT);
11481154

0 commit comments

Comments
 (0)