Core: Revert back to joda's multi date formatters (#36814)

This commit partially reverts #36447 by using the ability of Joda time's
DateTimeFormatterBuilder to append multiple parsers instead of using the
MergedDateFormatter. The MergedDateFormatter will be removed in a future
change, as it is not as performant due to creating potentially many
exceptions during heavy date parsing. This change is a stop-gap until
that followup is ready.

closes #36602
This commit is contained in:
Ryan Ernst 2018-12-19 11:20:35 -08:00 committed by GitHub
parent d39956c65c
commit c85c16bd94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 15 deletions

View File

@ -232,6 +232,27 @@ public class Joda {
formatter = StrictISODateTimeFormat.yearMonth();
} else if ("strictYearMonthDay".equals(input) || "strict_year_month_day".equals(input)) {
formatter = StrictISODateTimeFormat.yearMonthDay();
} else if (Strings.hasLength(input) && input.contains("||")) {
String[] formats = Strings.delimitedListToStringArray(input, "||");
DateTimeParser[] parsers = new DateTimeParser[formats.length];
if (formats.length == 1) {
formatter = forPattern(input).parser;
} else {
DateTimeFormatter dateTimeFormatter = null;
for (int i = 0; i < formats.length; i++) {
JodaDateFormatter currentFormatter = forPattern(formats[i]);
DateTimeFormatter currentParser = currentFormatter.parser;
if (dateTimeFormatter == null) {
dateTimeFormatter = currentFormatter.printer;
}
parsers[i] = currentParser.getParser();
}
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
.append(dateTimeFormatter.withZone(DateTimeZone.UTC).getPrinter(), parsers);
formatter = builder.toFormatter();
}
} else {
try {
maybeLogJodaDeprecation(input);

View File

@ -129,19 +129,17 @@ public interface DateFormatter {
if (Strings.hasLength(input) == false) {
throw new IllegalArgumentException("No date pattern provided");
}
if (input.startsWith("8") == false) {
return Joda.forPattern(input);
}
// force java 8 date format
List<DateFormatter> formatters = new ArrayList<>();
for (String pattern : Strings.delimitedListToStringArray(input, "||")) {
if (Strings.hasLength(input) == false) {
for (String pattern : Strings.delimitedListToStringArray(input.substring(1), "||")) {
if (Strings.hasLength(pattern) == false) {
throw new IllegalArgumentException("Cannot have empty element in multi date format pattern: " + input);
}
final DateFormatter formatter;
if (pattern.startsWith("8")) {
// force java 8 date format
formatter = DateFormatters.forPattern(pattern.substring(1));
} else {
formatter = Joda.forPattern(pattern);
}
formatters.add(formatter);
formatters.add(DateFormatters.forPattern(pattern));
}
if (formatters.size() == 1) {

View File

@ -471,7 +471,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
public void testSeveralTimeFormats() {
DateFormatter jodaFormatter = DateFormatter.forPattern("year_month_day||ordinal_date");
DateFormatter javaFormatter = DateFormatter.forPattern("8year_month_day||8ordinal_date");
DateFormatter javaFormatter = DateFormatter.forPattern("8year_month_day||ordinal_date");
assertSameDate("2018-12-12", "year_month_day||ordinal_date", jodaFormatter, javaFormatter);
assertSameDate("2018-128", "year_month_day||ordinal_date", jodaFormatter, javaFormatter);
}

View File

@ -19,7 +19,6 @@
package org.elasticsearch.common.time;
import org.elasticsearch.common.joda.JodaDateFormatter;
import org.elasticsearch.test.ESTestCase;
import java.time.Instant;
@ -204,6 +203,6 @@ public class DateFormattersTests extends ESTestCase {
assertThat(formatter, instanceOf(DateFormatters.MergedDateFormatter.class));
DateFormatters.MergedDateFormatter mergedFormatter = (DateFormatters.MergedDateFormatter) formatter;
assertThat(mergedFormatter.formatters.get(0), instanceOf(JavaDateFormatter.class));
assertThat(mergedFormatter.formatters.get(1), instanceOf(JodaDateFormatter.class));
assertThat(mergedFormatter.formatters.get(1), instanceOf(JavaDateFormatter.class));
}
}

View File

@ -239,7 +239,7 @@ public class JavaDateMathParserTests extends ESTestCase {
assertDateMathEquals("1418248078000||/m", "2014-12-10T21:47:00.000");
// also check other time units
DateMathParser parser = DateFormatter.forPattern("8epoch_second||8dateOptionalTime").toDateMathParser();
DateMathParser parser = DateFormatter.forPattern("8epoch_second||dateOptionalTime").toDateMathParser();
long datetime = parser.parse("1418248078", () -> 0);
assertDateEquals(datetime, "1418248078", "2014-12-10T21:47:58.000");

View File

@ -174,7 +174,7 @@ public class DateFieldMapperTests extends ESSingleNodeTestCase {
.endObject()),
XContentType.JSON));
MapperParsingException e = expectThrows(MapperParsingException.class, runnable);
assertThat(e.getCause().getMessage(), containsString("failed to parse date field [2016-03-99]"));
assertThat(e.getCause().getMessage(), containsString("Cannot parse \"2016-03-99\""));
mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("field").field("type", "date")