From 97d047202bbb04cd654ab575634990a2886ea622 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 15:48:57 +0100 Subject: [PATCH 01/19] Parse patterns with optionals using parseUnresolved Java-time fails parsing composite patterns when first pattern matches only the prefix of the input. It expects pattern in longest-shortest order. Joda does not suffer from this closes #39916 --- .../common/joda/JodaDateFormatter.java | 10 ++ .../common/time/DateFormatter.java | 13 ++- .../common/time/DateFormatters.java | 97 ++++++++++++++++--- .../common/time/JavaDateFormatter.java | 16 +++ .../joda/JavaJodaTimeDuellingTests.java | 7 ++ 5 files changed, 126 insertions(+), 17 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java index 1b428fdac3a20..03a4f19668917 100644 --- a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java @@ -26,6 +26,7 @@ import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormatter; +import java.text.ParsePosition; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -51,6 +52,15 @@ public TemporalAccessor parse(String input) { return ZonedDateTime.ofInstant(Instant.ofEpochMilli(dt.getMillis()), DateUtils.dateTimeZoneToZoneId(dt.getZone())); } + /** + * Joda allways succeds when parsing with composite optional patterns + * @return true + */ + @Override + public boolean tryParseUnresolved(String input) { + return true; + } + public long parseMillis(String input) { return parser.parseMillis(input); } diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java index bf7999067b05a..fcdfe5938f582 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.Strings; import org.joda.time.DateTime; +import java.text.ParsePosition; import java.time.Instant; import java.time.ZoneId; import java.time.ZoneOffset; @@ -149,6 +150,16 @@ static DateFormatter forPattern(String input) { return formatters.get(0); } - return DateFormatters.merge(input, formatters); + return new DateFormatters.MergedDateFormatter(input, formatters); } + + /** + * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) + * patterns. Joda does not suffer from this. + * https://bugs.openjdk.java.net/browse/JDK-8188771 + * + * @param input An arbitrary string resembling the string representation of a date or time + * @return true if parsing was successful, false if parsing failed + */ + boolean tryParseUnresolved(String input); } diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index a8dce661e1c9f..0700cd7e56370 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -19,9 +19,11 @@ package org.elasticsearch.common.time; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; +import java.text.ParsePosition; import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; @@ -32,6 +34,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; import java.time.format.SignStyle; import java.time.temporal.ChronoField; @@ -41,8 +44,10 @@ import java.time.temporal.TemporalQueries; import java.time.temporal.WeekFields; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.stream.Collectors; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.DAY_OF_WEEK; @@ -1573,25 +1578,85 @@ static DateFormatter forPattern(String input) { } } - static JavaDateFormatter merge(String pattern, List formatters) { - assert formatters.size() > 0; - - List dateTimeFormatters = new ArrayList<>(formatters.size()); - DateTimeFormatterBuilder roundupBuilder = new DateTimeFormatterBuilder(); - DateTimeFormatter printer = null; - for (DateFormatter formatter : formatters) { - assert formatter instanceof JavaDateFormatter; - JavaDateFormatter javaDateFormatter = (JavaDateFormatter) formatter; - if (printer == null) { - printer = javaDateFormatter.getPrinter(); + static class MergedDateFormatter implements DateFormatter { + + private final String pattern; + // package private for tests + final List formatters; + private final List dateMathParsers; + + MergedDateFormatter(String pattern, List formatters) { + assert formatters.size() > 0; + this.pattern = pattern; + this.formatters = Collections.unmodifiableList(formatters); + this.dateMathParsers = formatters.stream().map(DateFormatter::toDateMathParser).collect(Collectors.toList()); + } + + @Override + public TemporalAccessor parse(String input) { + for (DateFormatter formatter : formatters) { + if(formatter.tryParseUnresolved(input) == true){ + return formatter.parse(input); + } } - dateTimeFormatters.add(javaDateFormatter.getParser()); - roundupBuilder.appendOptional(javaDateFormatter.getRoundupParser()); + throw new DateTimeParseException("Text '" + input + "' could not be parsed", input, 0); + } + + @Override + public boolean tryParseUnresolved(String input) { + return false; + } + + @Override + public DateFormatter withZone(ZoneId zoneId) { + return new MergedDateFormatter(pattern, formatters.stream().map(f -> f.withZone(zoneId)).collect(Collectors.toList())); + } + + @Override + public DateFormatter withLocale(Locale locale) { + return new MergedDateFormatter(pattern, formatters.stream().map(f -> f.withLocale(locale)).collect(Collectors.toList())); } - DateTimeFormatter roundUpParser = roundupBuilder.toFormatter(Locale.ROOT); - return new JavaDateFormatter(pattern, printer, builder -> builder.append(roundUpParser), - dateTimeFormatters.toArray(new DateTimeFormatter[0])); + @Override + public String format(TemporalAccessor accessor) { + return formatters.get(0).format(accessor); + } + + @Override + public String pattern() { + return pattern; + } + + @Override + public Locale locale() { + return formatters.get(0).locale(); + } + + @Override + public ZoneId zone() { + return formatters.get(0).zone(); + } + + @Override + public DateMathParser toDateMathParser() { + return (text, now, roundUp, tz) -> { + ElasticsearchParseException failure = null; + for (DateMathParser parser : dateMathParsers) { + try { + return parser.parse(text, now, roundUp, tz); + } catch (ElasticsearchParseException e) { + if (failure == null) { + // wrap so the entire multi format is in the message + failure = new ElasticsearchParseException("failed to parse date field [" + text + "] with format [" + + pattern + "]", e); + } else { + failure.addSuppressed(e); + } + } + } + throw failure; + }; + } } private static final LocalDate LOCALDATE_EPOCH = LocalDate.of(1970, 1, 1); diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index c3adcc84b5781..b315e37b155d8 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -21,6 +21,7 @@ import org.elasticsearch.common.Strings; +import java.text.ParsePosition; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; @@ -128,6 +129,21 @@ public TemporalAccessor parse(String input) { } } + @Override + public boolean tryParseUnresolved(String input) { + try { + ParsePosition pp = new ParsePosition(0); + parser.parseUnresolved(input, pp); + int len = input.length(); + if (pp.getErrorIndex() == -1 && pp.getIndex() == len) { + return true; + } + } catch (RuntimeException ex) { + // should not happen, but ignore if it does + } + return false; + } + @Override public DateFormatter withZone(ZoneId zoneId) { // shortcurt to not create new objects unnecessarily diff --git a/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java b/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java index 40822d5a38b84..3104bf3ef8b05 100644 --- a/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java +++ b/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java @@ -343,6 +343,13 @@ public void testDuellingFormatsValidParsing() { assertSameDate("2012-W1-1", "weekyear_week_day"); } + public void testCompositeParsing(){ + //in all these examples the second pattern will be used + assertSameDate("2014-06-06T12:01:02.123", "yyyy-MM-dd'T'HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSS"); + assertSameDate("2014-06-06T12:01:02.123", "strictDateTimeNoMillis||yyyy-MM-dd'T'HH:mm:ss.SSS"); + assertSameDate("2014-06-06T12:01:02.123", "yyyy-MM-dd'T'HH:mm:ss+HH:MM||yyyy-MM-dd'T'HH:mm:ss.SSS"); + } + public void testDuelingStrictParsing() { assertSameDate("2018W313", "strict_basic_week_date"); assertParseException("18W313", "strict_basic_week_date"); From 4c7e9972a47c267163d64c7bcf77a57855497c36 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 16:03:53 +0100 Subject: [PATCH 02/19] unused imports --- .../java/org/elasticsearch/common/joda/JodaDateFormatter.java | 1 - .../main/java/org/elasticsearch/common/time/DateFormatter.java | 1 - .../main/java/org/elasticsearch/common/time/DateFormatters.java | 2 -- 3 files changed, 4 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java index 03a4f19668917..41d6896ea50db 100644 --- a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java @@ -26,7 +26,6 @@ import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormatter; -import java.text.ParsePosition; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java index fcdfe5938f582..53421bde1bc9f 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java @@ -22,7 +22,6 @@ import org.elasticsearch.common.Strings; import org.joda.time.DateTime; -import java.text.ParsePosition; import java.time.Instant; import java.time.ZoneId; import java.time.ZoneOffset; diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 0700cd7e56370..76c0e890063c0 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -23,7 +23,6 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; -import java.text.ParsePosition; import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; @@ -43,7 +42,6 @@ import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalQueries; import java.time.temporal.WeekFields; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; From a6448d2bd8881da6b1c55a7572604b1562d6e1c6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 16:29:46 +0100 Subject: [PATCH 03/19] exception formatting --- .../java/org/elasticsearch/common/time/DateFormatters.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 76c0e890063c0..540057d02778a 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -1645,8 +1645,7 @@ public DateMathParser toDateMathParser() { } catch (ElasticsearchParseException e) { if (failure == null) { // wrap so the entire multi format is in the message - failure = new ElasticsearchParseException("failed to parse date field [" + text + "] with format [" - + pattern + "]", e); + failure = e; } else { failure.addSuppressed(e); } From aa505e2c65f275c9a2395b46e722c2bb0e7a87dd Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 17:46:30 +0100 Subject: [PATCH 04/19] parsing pass --- .../elasticsearch/common/time/DateFormatters.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 540057d02778a..33170364f7d01 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -33,7 +33,6 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; -import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; import java.time.format.SignStyle; import java.time.temporal.ChronoField; @@ -1592,17 +1591,21 @@ static class MergedDateFormatter implements DateFormatter { @Override public TemporalAccessor parse(String input) { - for (DateFormatter formatter : formatters) { - if(formatter.tryParseUnresolved(input) == true){ - return formatter.parse(input); + try { + for (DateFormatter formatter : formatters) { + if (formatter.tryParseUnresolved(input) == true) { + return formatter.parse(input); + } } + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("failed to parse date field [" + input + "] with format [" + pattern + "]", e); } - throw new DateTimeParseException("Text '" + input + "' could not be parsed", input, 0); + throw new IllegalArgumentException("Text '" + input + "' could not be parsed"); } @Override public boolean tryParseUnresolved(String input) { - return false; + return true; } @Override From abb0bc6c851a04eb13dc1c44ac4f0be70ef96c54 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 19:04:34 +0100 Subject: [PATCH 05/19] refactor --- .../common/joda/JodaDateFormatter.java | 9 -- .../common/time/DateFormatter.java | 12 +-- .../common/time/DateFormatters.java | 101 ++++-------------- .../common/time/JavaDateFormatter.java | 36 +++++-- 4 files changed, 49 insertions(+), 109 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java index 41d6896ea50db..1b428fdac3a20 100644 --- a/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java @@ -51,15 +51,6 @@ public TemporalAccessor parse(String input) { return ZonedDateTime.ofInstant(Instant.ofEpochMilli(dt.getMillis()), DateUtils.dateTimeZoneToZoneId(dt.getZone())); } - /** - * Joda allways succeds when parsing with composite optional patterns - * @return true - */ - @Override - public boolean tryParseUnresolved(String input) { - return true; - } - public long parseMillis(String input) { return parser.parseMillis(input); } diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java index 53421bde1bc9f..bf7999067b05a 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatter.java @@ -149,16 +149,6 @@ static DateFormatter forPattern(String input) { return formatters.get(0); } - return new DateFormatters.MergedDateFormatter(input, formatters); + return DateFormatters.merge(input, formatters); } - - /** - * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) - * patterns. Joda does not suffer from this. - * https://bugs.openjdk.java.net/browse/JDK-8188771 - * - * @param input An arbitrary string resembling the string representation of a date or time - * @return true if parsing was successful, false if parsing failed - */ - boolean tryParseUnresolved(String input); } diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 33170364f7d01..0f2e3a00e6e91 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -19,7 +19,6 @@ package org.elasticsearch.common.time; -import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; @@ -41,10 +40,9 @@ import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalQueries; import java.time.temporal.WeekFields; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.stream.Collectors; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.DAY_OF_WEEK; @@ -1575,88 +1573,25 @@ static DateFormatter forPattern(String input) { } } - static class MergedDateFormatter implements DateFormatter { - - private final String pattern; - // package private for tests - final List formatters; - private final List dateMathParsers; - - MergedDateFormatter(String pattern, List formatters) { - assert formatters.size() > 0; - this.pattern = pattern; - this.formatters = Collections.unmodifiableList(formatters); - this.dateMathParsers = formatters.stream().map(DateFormatter::toDateMathParser).collect(Collectors.toList()); - } - - @Override - public TemporalAccessor parse(String input) { - try { - for (DateFormatter formatter : formatters) { - if (formatter.tryParseUnresolved(input) == true) { - return formatter.parse(input); - } - } - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("failed to parse date field [" + input + "] with format [" + pattern + "]", e); + static JavaDateFormatter merge(String pattern, List formatters) { + assert formatters.size() > 0; + + List dateTimeFormatters = new ArrayList<>(formatters.size()); + DateTimeFormatterBuilder roundupBuilder = new DateTimeFormatterBuilder(); + DateTimeFormatter printer = null; + for (DateFormatter formatter : formatters) { + assert formatter instanceof JavaDateFormatter; + JavaDateFormatter javaDateFormatter = (JavaDateFormatter) formatter; + if (printer == null) { + printer = javaDateFormatter.getPrinter(); } - throw new IllegalArgumentException("Text '" + input + "' could not be parsed"); - } - - @Override - public boolean tryParseUnresolved(String input) { - return true; - } - - @Override - public DateFormatter withZone(ZoneId zoneId) { - return new MergedDateFormatter(pattern, formatters.stream().map(f -> f.withZone(zoneId)).collect(Collectors.toList())); - } - - @Override - public DateFormatter withLocale(Locale locale) { - return new MergedDateFormatter(pattern, formatters.stream().map(f -> f.withLocale(locale)).collect(Collectors.toList())); - } - - @Override - public String format(TemporalAccessor accessor) { - return formatters.get(0).format(accessor); + dateTimeFormatters.add(javaDateFormatter.getParser()); + roundupBuilder.appendOptional(javaDateFormatter.getRoundupParser()); } + DateTimeFormatter roundUpParser = roundupBuilder.toFormatter(Locale.ROOT); - @Override - public String pattern() { - return pattern; - } - - @Override - public Locale locale() { - return formatters.get(0).locale(); - } - - @Override - public ZoneId zone() { - return formatters.get(0).zone(); - } - - @Override - public DateMathParser toDateMathParser() { - return (text, now, roundUp, tz) -> { - ElasticsearchParseException failure = null; - for (DateMathParser parser : dateMathParsers) { - try { - return parser.parse(text, now, roundUp, tz); - } catch (ElasticsearchParseException e) { - if (failure == null) { - // wrap so the entire multi format is in the message - failure = e; - } else { - failure.addSuppressed(e); - } - } - } - throw failure; - }; - } + return new JavaDateFormatter(pattern, printer, builder -> builder.append(roundUpParser), + dateTimeFormatters.toArray(new DateTimeFormatter[0])); } private static final LocalDate LOCALDATE_EPOCH = LocalDate.of(1970, 1, 1); @@ -1697,7 +1632,7 @@ public static ZonedDateTime from(TemporalAccessor accessor) { if (zoneId == null) { zoneId = ZoneOffset.UTC; } - + LocalDate localDate = accessor.query(TemporalQueries.localDate()); LocalTime localTime = accessor.query(TemporalQueries.localTime()); boolean isLocalDateSet = localDate != null; diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index b315e37b155d8..909db91b36462 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -30,6 +30,7 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -51,14 +52,16 @@ class JavaDateFormatter implements DateFormatter { private final String format; private final DateTimeFormatter printer; - private final DateTimeFormatter parser; - private final DateTimeFormatter roundupParser; + final DateTimeFormatter parser; + Collection parsers; + final DateTimeFormatter roundupParser; private JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeFormatter roundupParser, DateTimeFormatter parser) { this.format = format; this.printer = printer; this.roundupParser = roundupParser; this.parser = parser; + this.parsers = Arrays.asList(parser); } JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeFormatter... parsers) { @@ -80,8 +83,11 @@ private JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeForm } this.printer = printer; this.format = format; + this.parsers = Arrays.asList(parsers); + if (parsers.length == 0) { this.parser = printer; + this.parsers = Arrays.asList(parser); } else if (parsers.length == 1) { this.parser = parsers[0]; } else { @@ -123,17 +129,35 @@ public TemporalAccessor parse(String input) { } try { - return parser.parse(input); + return doParse(input); } catch (DateTimeParseException e) { throw new IllegalArgumentException("failed to parse date field [" + input + "] with format [" + format + "]", e); } } - @Override - public boolean tryParseUnresolved(String input) { + private TemporalAccessor doParse(String input) { + if (parsers.size() > 1) { + for (DateTimeFormatter formatter : parsers) { + if (tryParseUnresolved(formatter, input) == true) { + return formatter.parse(input); + } + } + } + return parser.parse(input); + } + + /** + * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) + * patterns. Joda does not suffer from this. + * https://bugs.openjdk.java.net/browse/JDK-8188771 + * + * @param input An arbitrary string resembling the string representation of a date or time + * @return true if parsing was successful, false if parsing failed + */ + private boolean tryParseUnresolved(DateTimeFormatter formatter, String input) { try { ParsePosition pp = new ParsePosition(0); - parser.parseUnresolved(input, pp); + formatter.parseUnresolved(input, pp); int len = input.length(); if (pp.getErrorIndex() == -1 && pp.getIndex() == len) { return true; From 5bcbb7b9909f315acdb647594e4677c4fde79b70 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 19:06:09 +0100 Subject: [PATCH 06/19] tab --- .../common/time/DateFormatters.java | 65 +++++++++---------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 0f2e3a00e6e91..49a9a9187ed4c 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -91,7 +91,7 @@ public class DateFormatters { .optionalEnd() .optionalEnd() .optionalStart() - .appendOffset("+HH:MM", "Z") + .appendZoneOrOffsetId() .optionalEnd() .optionalEnd() .optionalEnd() @@ -163,7 +163,7 @@ public class DateFormatters { .optionalEnd() .optionalEnd() .optionalStart() - .appendOffset("+HH:MM", "Z") + .appendZoneOrOffsetId() .optionalEnd() .optionalEnd() .optionalEnd() @@ -232,7 +232,7 @@ public class DateFormatters { * of hour, two digit second of minute, and time zone offset (HHmmssZ). */ private static final DateFormatter BASIC_TIME_NO_MILLIS = new JavaDateFormatter("basic_time_no_millis", - new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -257,7 +257,7 @@ public class DateFormatters { * offset (HHmmss.SSSZ). */ private static final DateFormatter BASIC_TIME = new JavaDateFormatter("basic_time", - new DateTimeFormatterBuilder().append(BASIC_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -274,7 +274,7 @@ public class DateFormatters { * offset prefixed by 'T' ('T'HHmmss.SSSZ). */ private static final DateFormatter BASIC_T_TIME = new JavaDateFormatter("basic_t_time", - new DateTimeFormatterBuilder().append(BASIC_T_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_T_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_T_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_T_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -285,8 +285,7 @@ public class DateFormatters { * ('T'HHmmssZ). */ private static final DateFormatter BASIC_T_TIME_NO_MILLIS = new JavaDateFormatter("basic_t_time_no_millis", - new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON) .toFormatter(Locale.ROOT) @@ -313,7 +312,7 @@ public class DateFormatters { * by a 'T' (yyyyMMdd'T'HHmmss.SSSZ). */ private static final DateFormatter BASIC_DATE_TIME = new JavaDateFormatter("basic_date_time", - new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -327,7 +326,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_DATE_TIME_NO_MILLIS = new JavaDateFormatter("basic_date_time_no_millis", new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) @@ -347,7 +346,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_ORDINAL_DATE_TIME = new JavaDateFormatter("basic_ordinal_date_time", new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_PRINTER) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER) @@ -361,7 +360,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("basic_ordinal_date_time_no_millis", new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) @@ -421,7 +420,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) - .appendOffset("+HH:MM", "Z") + .appendZoneOrOffsetId() .toFormatter(Locale.ROOT), new DateTimeFormatterBuilder() .append(STRICT_BASIC_WEEK_DATE_PRINTER) @@ -531,7 +530,7 @@ public class DateFormatters { * (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), + new DateTimeFormatterBuilder().append(STRICT_DATE_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), 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) ); @@ -550,7 +549,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_ordinal_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) @@ -569,7 +568,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) @@ -672,7 +671,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_ORDINAL_DATE_TIME = new JavaDateFormatter("strict_ordinal_date_time", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) @@ -704,7 +703,7 @@ public class DateFormatters { * time zone offset (HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_TIME = new JavaDateFormatter("strict_time", - new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_FORMATTER_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_FORMATTER_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -715,7 +714,7 @@ public class DateFormatters { * time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_T_TIME = new JavaDateFormatter("strict_t_time", - new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_FORMATTER_BASE) @@ -735,7 +734,7 @@ public class DateFormatters { * hour, two digit second of minute, and time zone offset (HH:mm:ssZZ). */ private static final DateFormatter STRICT_TIME_NO_MILLIS = new JavaDateFormatter("strict_time_no_millis", - new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -747,7 +746,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_T_TIME_NO_MILLIS = new JavaDateFormatter("strict_t_time_no_millis", new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) @@ -780,7 +779,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_WEEK_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_week_date_time_no_millis", new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) @@ -792,8 +791,7 @@ public class DateFormatters { * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_WEEK_DATE_TIME = new JavaDateFormatter("strict_week_date_time", - new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_FORMATTER_BASE) @@ -1091,7 +1089,7 @@ public class DateFormatters { */ private static final DateFormatter DATE_TIME = new JavaDateFormatter("date_time", STRICT_DATE_OPTIONAL_TIME_PRINTER, - new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1136,7 +1134,7 @@ public class DateFormatters { */ private static final DateFormatter DATE_TIME_NO_MILLIS = new JavaDateFormatter("date_time_no_millis", DATE_TIME_NO_MILLIS_PRINTER, - new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX) .optionalStart().appendZoneOrOffsetId().optionalEnd().toFormatter(Locale.ROOT), @@ -1199,7 +1197,7 @@ public class DateFormatters { */ private static final DateFormatter ORDINAL_DATE_TIME = new JavaDateFormatter("ordinal_date_time", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_FORMATTER_BASE) @@ -1218,7 +1216,7 @@ public class DateFormatters { */ private static final DateFormatter ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("ordinal_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_NO_MILLIS_BASE) @@ -1230,8 +1228,7 @@ public class DateFormatters { * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ). */ private static final DateFormatter WEEK_DATE_TIME = new JavaDateFormatter("week_date_time", - new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).appendLiteral("T").append(TIME_PREFIX) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).appendLiteral("T").append(TIME_PREFIX) @@ -1244,7 +1241,7 @@ public class DateFormatters { */ private static final DateFormatter WEEK_DATE_TIME_NO_MILLIS = new JavaDateFormatter("week_date_time_no_millis", new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).append(T_TIME_NO_MILLIS_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).append(T_TIME_NO_MILLIS_FORMATTER) @@ -1286,7 +1283,7 @@ public class DateFormatters { * time zone offset (HH:mm:ss.SSSZZ). */ private static final DateFormatter TIME = new JavaDateFormatter("time", - new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_PREFIX).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_PREFIX).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1296,7 +1293,7 @@ public class DateFormatters { * hour, two digit second of minute, andtime zone offset (HH:mm:ssZZ). */ private static final DateFormatter TIME_NO_MILLIS = new JavaDateFormatter("time_no_millis", - new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_NO_MILLIS_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_NO_MILLIS_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1307,7 +1304,7 @@ public class DateFormatters { * time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ). */ private static final DateFormatter T_TIME = new JavaDateFormatter("t_time", - new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(TIME_PREFIX) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(TIME_PREFIX) @@ -1321,7 +1318,7 @@ public class DateFormatters { */ private static final DateFormatter T_TIME_NO_MILLIS = new JavaDateFormatter("t_time_no_millis", new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) - .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), + .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(T_TIME_NO_MILLIS_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(T_TIME_NO_MILLIS_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); From 44ae4040d88b5def67ff9d1b69577e074c3976f6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 15 Mar 2019 19:07:51 +0100 Subject: [PATCH 07/19] revert --- .../common/time/DateFormatters.java | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 49a9a9187ed4c..0f2e3a00e6e91 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -91,7 +91,7 @@ public class DateFormatters { .optionalEnd() .optionalEnd() .optionalStart() - .appendZoneOrOffsetId() + .appendOffset("+HH:MM", "Z") .optionalEnd() .optionalEnd() .optionalEnd() @@ -163,7 +163,7 @@ public class DateFormatters { .optionalEnd() .optionalEnd() .optionalStart() - .appendZoneOrOffsetId() + .appendOffset("+HH:MM", "Z") .optionalEnd() .optionalEnd() .optionalEnd() @@ -232,7 +232,7 @@ public class DateFormatters { * of hour, two digit second of minute, and time zone offset (HHmmssZ). */ private static final DateFormatter BASIC_TIME_NO_MILLIS = new JavaDateFormatter("basic_time_no_millis", - new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -257,7 +257,7 @@ public class DateFormatters { * offset (HHmmss.SSSZ). */ private static final DateFormatter BASIC_TIME = new JavaDateFormatter("basic_time", - new DateTimeFormatterBuilder().append(BASIC_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -274,7 +274,7 @@ public class DateFormatters { * offset prefixed by 'T' ('T'HHmmss.SSSZ). */ private static final DateFormatter BASIC_T_TIME = new JavaDateFormatter("basic_t_time", - new DateTimeFormatterBuilder().append(BASIC_T_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_T_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_T_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_T_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -285,7 +285,8 @@ public class DateFormatters { * ('T'HHmmssZ). */ private static final DateFormatter BASIC_T_TIME_NO_MILLIS = new JavaDateFormatter("basic_t_time_no_millis", - new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON) .toFormatter(Locale.ROOT) @@ -312,7 +313,7 @@ public class DateFormatters { * by a 'T' (yyyyMMdd'T'HHmmss.SSSZ). */ private static final DateFormatter BASIC_DATE_TIME = new JavaDateFormatter("basic_date_time", - new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -326,7 +327,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_DATE_TIME_NO_MILLIS = new JavaDateFormatter("basic_date_time_no_millis", new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(BASIC_DATE_T).append(BASIC_TIME_NO_MILLIS_BASE) @@ -346,7 +347,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_ORDINAL_DATE_TIME = new JavaDateFormatter("basic_ordinal_date_time", new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_PRINTER) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").append(BASIC_T_TIME_FORMATTER) @@ -360,7 +361,7 @@ public class DateFormatters { */ private static final DateFormatter BASIC_ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("basic_ordinal_date_time_no_millis", new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendPattern("yyyyDDD").appendLiteral("T").append(BASIC_TIME_NO_MILLIS_BASE) @@ -420,7 +421,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) - .appendZoneOrOffsetId() + .appendOffset("+HH:MM", "Z") .toFormatter(Locale.ROOT), new DateTimeFormatterBuilder() .append(STRICT_BASIC_WEEK_DATE_PRINTER) @@ -530,7 +531,7 @@ public class DateFormatters { * (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).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_DATE_FORMATTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), 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) ); @@ -549,7 +550,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_ordinal_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) @@ -568,7 +569,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_DATE_TIME_NO_MILLIS_FORMATTER) @@ -671,7 +672,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_ORDINAL_DATE_TIME = new JavaDateFormatter("strict_ordinal_date_time", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) @@ -703,7 +704,7 @@ public class DateFormatters { * time zone offset (HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_TIME = new JavaDateFormatter("strict_time", - new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_FORMATTER_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_FORMATTER_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -714,7 +715,7 @@ public class DateFormatters { * time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_T_TIME = new JavaDateFormatter("strict_t_time", - new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_FORMATTER_BASE) @@ -734,7 +735,7 @@ public class DateFormatters { * hour, two digit second of minute, and time zone offset (HH:mm:ssZZ). */ private static final DateFormatter STRICT_TIME_NO_MILLIS = new JavaDateFormatter("strict_time_no_millis", - new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -746,7 +747,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_T_TIME_NO_MILLIS = new JavaDateFormatter("strict_t_time_no_millis", new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) @@ -779,7 +780,7 @@ public class DateFormatters { */ private static final DateFormatter STRICT_WEEK_DATE_TIME_NO_MILLIS = new JavaDateFormatter("strict_week_date_time_no_millis", new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) @@ -791,7 +792,8 @@ public class DateFormatters { * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ). */ private static final DateFormatter STRICT_WEEK_DATE_TIME = new JavaDateFormatter("strict_week_date_time", - new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) + .append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_FORMATTER_BASE) @@ -1089,7 +1091,7 @@ public class DateFormatters { */ private static final DateFormatter DATE_TIME = new JavaDateFormatter("date_time", STRICT_DATE_OPTIONAL_TIME_PRINTER, - new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1134,7 +1136,7 @@ public class DateFormatters { */ private static final DateFormatter DATE_TIME_NO_MILLIS = new JavaDateFormatter("date_time_no_millis", DATE_TIME_NO_MILLIS_PRINTER, - new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(DATE_TIME_PREFIX) .optionalStart().appendZoneOrOffsetId().optionalEnd().toFormatter(Locale.ROOT), @@ -1197,7 +1199,7 @@ public class DateFormatters { */ private static final DateFormatter ORDINAL_DATE_TIME = new JavaDateFormatter("ordinal_date_time", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_FORMATTER_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_FORMATTER_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_FORMATTER_BASE) @@ -1216,7 +1218,7 @@ public class DateFormatters { */ private static final DateFormatter ORDINAL_DATE_TIME_NO_MILLIS = new JavaDateFormatter("ordinal_date_time_no_millis", new DateTimeFormatterBuilder().append(STRICT_ORDINAL_DATE_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_NO_MILLIS_BASE) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(ORDINAL_DATE_TIME_NO_MILLIS_BASE) @@ -1228,7 +1230,8 @@ public class DateFormatters { * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ). */ private static final DateFormatter WEEK_DATE_TIME = new JavaDateFormatter("week_date_time", - new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T).append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) + .append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).appendLiteral("T").append(TIME_PREFIX) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).appendLiteral("T").append(TIME_PREFIX) @@ -1241,7 +1244,7 @@ public class DateFormatters { */ private static final DateFormatter WEEK_DATE_TIME_NO_MILLIS = new JavaDateFormatter("week_date_time_no_millis", new DateTimeFormatterBuilder().append(ISO_WEEK_DATE_T) - .append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).append(T_TIME_NO_MILLIS_FORMATTER) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(WEEK_DATE_FORMATTER).append(T_TIME_NO_MILLIS_FORMATTER) @@ -1283,7 +1286,7 @@ public class DateFormatters { * time zone offset (HH:mm:ss.SSSZZ). */ private static final DateFormatter TIME = new JavaDateFormatter("time", - new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_PREFIX).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_PREFIX).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1293,7 +1296,7 @@ public class DateFormatters { * hour, two digit second of minute, andtime zone offset (HH:mm:ssZZ). */ private static final DateFormatter TIME_NO_MILLIS = new JavaDateFormatter("time_no_millis", - new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().append(STRICT_TIME_NO_MILLIS_BASE).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_NO_MILLIS_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(TIME_NO_MILLIS_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); @@ -1304,7 +1307,7 @@ public class DateFormatters { * time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ). */ private static final DateFormatter T_TIME = new JavaDateFormatter("t_time", - new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), + new DateTimeFormatterBuilder().appendLiteral('T').append(STRICT_TIME_PRINTER).appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(TIME_PREFIX) .appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().appendLiteral("T").append(TIME_PREFIX) @@ -1318,7 +1321,7 @@ public class DateFormatters { */ private static final DateFormatter T_TIME_NO_MILLIS = new JavaDateFormatter("t_time_no_millis", new DateTimeFormatterBuilder().appendLiteral("T").append(STRICT_TIME_NO_MILLIS_BASE) - .appendZoneOrOffsetId().toFormatter(Locale.ROOT), + .appendOffset("+HH:MM", "Z").toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(T_TIME_NO_MILLIS_FORMATTER).appendZoneOrOffsetId().toFormatter(Locale.ROOT), new DateTimeFormatterBuilder().append(T_TIME_NO_MILLIS_FORMATTER).append(TIME_ZONE_FORMATTER_NO_COLON).toFormatter(Locale.ROOT) ); From 68b11f40c632744703367e1ca4f7e3afadd243fb Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 18 Mar 2019 11:54:27 +0100 Subject: [PATCH 08/19] javadatemath parser to work with merged parser --- .../common/time/DateFormatters.java | 2 +- .../common/time/JavaDateFormatter.java | 54 ++++++++----------- .../common/time/JavaDateMathParser.java | 17 +++--- 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java index 0f2e3a00e6e91..2379b4f00c2bf 100644 --- a/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java +++ b/server/src/main/java/org/elasticsearch/common/time/DateFormatters.java @@ -1585,7 +1585,7 @@ static JavaDateFormatter merge(String pattern, List formatters) { if (printer == null) { printer = javaDateFormatter.getPrinter(); } - dateTimeFormatters.add(javaDateFormatter.getParser()); + dateTimeFormatters.addAll(javaDateFormatter.getParsers()); roundupBuilder.appendOptional(javaDateFormatter.getRoundupParser()); } DateTimeFormatter roundUpParser = roundupBuilder.toFormatter(Locale.ROOT); diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 909db91b36462..842e1857daae4 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -32,6 +32,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -52,17 +53,8 @@ class JavaDateFormatter implements DateFormatter { private final String format; private final DateTimeFormatter printer; - final DateTimeFormatter parser; - Collection parsers; - final DateTimeFormatter roundupParser; - - private JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeFormatter roundupParser, DateTimeFormatter parser) { - this.format = format; - this.printer = printer; - this.roundupParser = roundupParser; - this.parser = parser; - this.parsers = Arrays.asList(parser); - } + private final List parsers; + private final DateTimeFormatter roundupParser; JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeFormatter... parsers) { this(format, printer, builder -> ROUND_UP_BASE_FIELDS.forEach(builder::parseDefaulting), parsers); @@ -83,39 +75,31 @@ private JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeForm } this.printer = printer; this.format = format; - this.parsers = Arrays.asList(parsers); if (parsers.length == 0) { - this.parser = printer; - this.parsers = Arrays.asList(parser); - } else if (parsers.length == 1) { - this.parser = parsers[0]; + this.parsers = Arrays.asList(printer); } else { - DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); - for (DateTimeFormatter parser : parsers) { - builder.appendOptional(parser); - } - this.parser = builder.toFormatter(Locale.ROOT); + this.parsers = Arrays.asList(parsers); } DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); if (format.contains("||") == false) { - builder.append(this.parser); + builder.append(firstParser()); } roundupParserConsumer.accept(builder); - DateTimeFormatter roundupFormatter = builder.toFormatter(parser.getLocale()); + DateTimeFormatter roundupFormatter = builder.toFormatter(firstParser().getLocale()); if (printer.getZone() != null) { roundupFormatter = roundupFormatter.withZone(printer.getZone()); } this.roundupParser = roundupFormatter; } - DateTimeFormatter getRoundupParser() { - return roundupParser; + private DateTimeFormatter firstParser() { + return this.parsers.get(0); } - DateTimeFormatter getParser() { - return parser; + DateTimeFormatter getRoundupParser() { + return roundupParser; } DateTimeFormatter getPrinter() { @@ -143,7 +127,7 @@ private TemporalAccessor doParse(String input) { } } } - return parser.parse(input); + return firstParser().parse(input); } /** @@ -171,21 +155,21 @@ private boolean tryParseUnresolved(DateTimeFormatter formatter, String input) { @Override public DateFormatter withZone(ZoneId zoneId) { // shortcurt to not create new objects unnecessarily - if (zoneId.equals(parser.getZone())) { + if (zoneId.equals(firstParser().getZone())) { return this; } - return new JavaDateFormatter(format, printer.withZone(zoneId), roundupParser.withZone(zoneId), parser.withZone(zoneId)); + return new JavaDateFormatter(format, printer.withZone(zoneId), roundupParser.withZone(zoneId), firstParser().withZone(zoneId)); } @Override public DateFormatter withLocale(Locale locale) { // shortcurt to not create new objects unnecessarily - if (locale.equals(parser.getLocale())) { + if (locale.equals(firstParser().getLocale())) { return this; } - return new JavaDateFormatter(format, printer.withLocale(locale), roundupParser.withLocale(locale), parser.withLocale(locale)); + return new JavaDateFormatter(format, printer.withLocale(locale), roundupParser.withLocale(locale), firstParser().withLocale(locale)); } @Override @@ -210,7 +194,7 @@ public ZoneId zone() { @Override public DateMathParser toDateMathParser() { - return new JavaDateMathParser(format, parser, roundupParser); + return new JavaDateMathParser(format, this, getRoundupParser()); } @Override @@ -234,4 +218,8 @@ public boolean equals(Object obj) { public String toString() { return String.format(Locale.ROOT, "format[%s] locale[%s]", format, locale()); } + + public Collection getParsers() { + return parsers; + } } diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java index 05e1e75efca39..aca0f3866fc5b 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java @@ -35,6 +35,7 @@ import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalQueries; import java.util.Objects; +import java.util.function.Function; import java.util.function.LongSupplier; /** @@ -46,11 +47,11 @@ */ public class JavaDateMathParser implements DateMathParser { - private final DateTimeFormatter formatter; - private final DateTimeFormatter roundUpFormatter; - private final String format; + private JavaDateFormatter formatter; + private DateTimeFormatter roundUpFormatter; + private String format; - JavaDateMathParser(String format, DateTimeFormatter formatter, DateTimeFormatter roundUpFormatter) { + JavaDateMathParser(String format, JavaDateFormatter formatter, DateTimeFormatter roundUpFormatter) { this.format = format; Objects.requireNonNull(formatter); this.formatter = formatter; @@ -215,12 +216,12 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo throw new ElasticsearchParseException("cannot parse empty date"); } - DateTimeFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter; + Function formatter = roundUpIfNoTime ? this.roundUpFormatter::parse : this.formatter::parse; try { if (timeZone == null) { - return DateFormatters.from(formatter.parse(value)).toInstant(); + return DateFormatters.from(formatter.apply(value)).toInstant(); } else { - TemporalAccessor accessor = formatter.parse(value); + TemporalAccessor accessor = formatter.apply(value); ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor); if (zoneId != null) { timeZone = zoneId; @@ -228,7 +229,7 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo return DateFormatters.from(accessor).withZoneSameLocal(timeZone).toInstant(); } - } catch (DateTimeParseException e) { + } catch (IllegalArgumentException | DateTimeParseException e) { throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]: [{}]", e, value, format, e.getMessage()); } From 8fb210cd8471d34efac63e079d9e2834392173d8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 18 Mar 2019 12:21:30 +0100 Subject: [PATCH 09/19] codestyle --- .../java/org/elasticsearch/common/time/JavaDateFormatter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 842e1857daae4..4d5feb7fe1ea1 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -169,7 +169,8 @@ public DateFormatter withLocale(Locale locale) { return this; } - return new JavaDateFormatter(format, printer.withLocale(locale), roundupParser.withLocale(locale), firstParser().withLocale(locale)); + return new JavaDateFormatter(format, printer.withLocale(locale), roundupParser.withLocale(locale), + firstParser().withLocale(locale)); } @Override From 0f2fca3fe7bab797a06a044d9155ba060d48f1a9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 18 Mar 2019 14:30:00 +0100 Subject: [PATCH 10/19] passing tests --- .../org/elasticsearch/common/time/JavaDateFormatter.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 4d5feb7fe1ea1..aebc2c1e17219 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; +import java.util.stream.Collectors; class JavaDateFormatter implements DateFormatter { @@ -159,18 +160,20 @@ public DateFormatter withZone(ZoneId zoneId) { return this; } - return new JavaDateFormatter(format, printer.withZone(zoneId), roundupParser.withZone(zoneId), firstParser().withZone(zoneId)); + return new JavaDateFormatter(format, printer.withZone(zoneId), + parsers.stream().map(p->p.withZone(zoneId)).toArray(size->new DateTimeFormatter[size])); } @Override public DateFormatter withLocale(Locale locale) { + //TODO not sure that we can keep that shortcut, and the one above // shortcurt to not create new objects unnecessarily if (locale.equals(firstParser().getLocale())) { return this; } - return new JavaDateFormatter(format, printer.withLocale(locale), roundupParser.withLocale(locale), - firstParser().withLocale(locale)); + return new JavaDateFormatter(format, printer.withLocale(locale), + parsers.stream().map(p->p.withLocale(locale)).toArray(size->new DateTimeFormatter[size])); } @Override From 22269cee0a2f88e40f8fcbf0c2b667f2d091111a Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 18 Mar 2019 14:43:07 +0100 Subject: [PATCH 11/19] unused import --- .../java/org/elasticsearch/common/time/JavaDateFormatter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index aebc2c1e17219..a52cd1578f05a 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -37,7 +37,6 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import java.util.stream.Collectors; class JavaDateFormatter implements DateFormatter { From ef01371a8ce4aacc747713dd448637f091d7fd6d Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 19 Mar 2019 08:50:09 +0100 Subject: [PATCH 12/19] code review follow up --- .../org/elasticsearch/common/time/JavaDateFormatter.java | 9 ++++----- .../elasticsearch/common/time/JavaDateMathParser.java | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index a52cd1578f05a..35c9e0478fdfd 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -31,6 +31,7 @@ import java.time.temporal.TemporalField; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -77,7 +78,7 @@ class JavaDateFormatter implements DateFormatter { this.format = format; if (parsers.length == 0) { - this.parsers = Arrays.asList(printer); + this.parsers = Collections.singletonList(printer); } else { this.parsers = Arrays.asList(parsers); } @@ -142,8 +143,7 @@ private boolean tryParseUnresolved(DateTimeFormatter formatter, String input) { try { ParsePosition pp = new ParsePosition(0); formatter.parseUnresolved(input, pp); - int len = input.length(); - if (pp.getErrorIndex() == -1 && pp.getIndex() == len) { + if (pp.getErrorIndex() == -1 && pp.getIndex() == input.length()) { return true; } } catch (RuntimeException ex) { @@ -165,7 +165,6 @@ public DateFormatter withZone(ZoneId zoneId) { @Override public DateFormatter withLocale(Locale locale) { - //TODO not sure that we can keep that shortcut, and the one above // shortcurt to not create new objects unnecessarily if (locale.equals(firstParser().getLocale())) { return this; @@ -222,7 +221,7 @@ public String toString() { return String.format(Locale.ROOT, "format[%s] locale[%s]", format, locale()); } - public Collection getParsers() { + Collection getParsers() { return parsers; } } diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java index aca0f3866fc5b..dc7c195e2fd6c 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java @@ -47,9 +47,9 @@ */ public class JavaDateMathParser implements DateMathParser { - private JavaDateFormatter formatter; - private DateTimeFormatter roundUpFormatter; - private String format; + private final JavaDateFormatter formatter; + private final DateTimeFormatter roundUpFormatter; + private final String format; JavaDateMathParser(String format, JavaDateFormatter formatter, DateTimeFormatter roundUpFormatter) { this.format = format; From 0337fe0de2810d64438bc029e0ebe12db62c56ea Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 19 Mar 2019 16:14:52 +0100 Subject: [PATCH 13/19] code review followup cleanup --- .../java/org/elasticsearch/common/time/JavaDateFormatter.java | 2 ++ .../elasticsearch/common/joda/JavaJodaTimeDuellingTests.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 35c9e0478fdfd..827043da8fa24 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.Strings; import java.text.ParsePosition; +import java.time.DateTimeException; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; @@ -127,6 +128,7 @@ private TemporalAccessor doParse(String input) { return formatter.parse(input); } } + throw new DateTimeParseException("Failed to parse with all parsers from a composite parser", input, 0); } return firstParser().parse(input); } diff --git a/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java b/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java index 3104bf3ef8b05..5798b5f799203 100644 --- a/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java +++ b/server/src/test/java/org/elasticsearch/common/joda/JavaJodaTimeDuellingTests.java @@ -350,6 +350,10 @@ public void testCompositeParsing(){ assertSameDate("2014-06-06T12:01:02.123", "yyyy-MM-dd'T'HH:mm:ss+HH:MM||yyyy-MM-dd'T'HH:mm:ss.SSS"); } + public void testExceptionWhenCompositeParsingFails(){ + assertParseException("2014-06-06T12:01:02.123", "yyyy-MM-dd'T'HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SS"); + } + public void testDuelingStrictParsing() { assertSameDate("2018W313", "strict_basic_week_date"); assertParseException("18W313", "strict_basic_week_date"); From b295fb063d3a59f9b11a9b8212ca7c7e86684a20 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 19 Mar 2019 16:48:58 +0100 Subject: [PATCH 14/19] unused import --- .../java/org/elasticsearch/common/time/JavaDateFormatter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 827043da8fa24..9bc02c258002c 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -22,7 +22,6 @@ import org.elasticsearch.common.Strings; import java.text.ParsePosition; -import java.time.DateTimeException; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; From 1126ed11249e6ed41d1c0fcb4ae1a18bd3dd1fb1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Fri, 22 Mar 2019 15:02:29 +0100 Subject: [PATCH 15/19] trying to parse with Format.parseObject remve unused method typo and message change --- .../common/time/JavaDateFormatter.java | 40 ++++++------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 9bc02c258002c..addcb5d7ec788 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -43,6 +43,7 @@ class JavaDateFormatter implements DateFormatter { // base fields which should be used for default parsing, when we round up for date math private static final Map ROUND_UP_BASE_FIELDS = new HashMap<>(6); + { ROUND_UP_BASE_FIELDS.put(ChronoField.MONTH_OF_YEAR, 1L); ROUND_UP_BASE_FIELDS.put(ChronoField.DAY_OF_MONTH, 1L); @@ -62,7 +63,7 @@ class JavaDateFormatter implements DateFormatter { } JavaDateFormatter(String format, DateTimeFormatter printer, Consumer roundupParserConsumer, - DateTimeFormatter... parsers) { + DateTimeFormatter... parsers) { if (printer == null) { throw new IllegalArgumentException("printer may not be null"); } @@ -123,34 +124,19 @@ public TemporalAccessor parse(String input) { private TemporalAccessor doParse(String input) { if (parsers.size() > 1) { for (DateTimeFormatter formatter : parsers) { - if (tryParseUnresolved(formatter, input) == true) { - return formatter.parse(input); + ParsePosition pos = new ParsePosition(0); + Object object = formatter.toFormat().parseObject(input, pos); + if (parsingSucceeded(object, input, pos) == true) { + return (TemporalAccessor) object; } } - throw new DateTimeParseException("Failed to parse with all parsers from a composite parser", input, 0); + throw new DateTimeParseException("Failed to parse with all enclosed parsers", input, 0); } return firstParser().parse(input); } - /** - * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) - * patterns. Joda does not suffer from this. - * https://bugs.openjdk.java.net/browse/JDK-8188771 - * - * @param input An arbitrary string resembling the string representation of a date or time - * @return true if parsing was successful, false if parsing failed - */ - private boolean tryParseUnresolved(DateTimeFormatter formatter, String input) { - try { - ParsePosition pp = new ParsePosition(0); - formatter.parseUnresolved(input, pp); - if (pp.getErrorIndex() == -1 && pp.getIndex() == input.length()) { - return true; - } - } catch (RuntimeException ex) { - // should not happen, but ignore if it does - } - return false; + private boolean parsingSucceeded(Object object, String input, ParsePosition pos) { + return object != null && pos.getIndex() == input.length(); } @Override @@ -161,7 +147,7 @@ public DateFormatter withZone(ZoneId zoneId) { } return new JavaDateFormatter(format, printer.withZone(zoneId), - parsers.stream().map(p->p.withZone(zoneId)).toArray(size->new DateTimeFormatter[size])); + parsers.stream().map(p -> p.withZone(zoneId)).toArray(size -> new DateTimeFormatter[size])); } @Override @@ -172,7 +158,7 @@ public DateFormatter withLocale(Locale locale) { } return new JavaDateFormatter(format, printer.withLocale(locale), - parsers.stream().map(p->p.withLocale(locale)).toArray(size->new DateTimeFormatter[size])); + parsers.stream().map(p -> p.withLocale(locale)).toArray(size -> new DateTimeFormatter[size])); } @Override @@ -213,8 +199,8 @@ public boolean equals(Object obj) { JavaDateFormatter other = (JavaDateFormatter) obj; return Objects.equals(format, other.format) && - Objects.equals(locale(), other.locale()) && - Objects.equals(this.printer.getZone(), other.printer.getZone()); + Objects.equals(locale(), other.locale()) && + Objects.equals(this.printer.getZone(), other.printer.getZone()); } @Override From 8fcb0b1aaa2b750289dfaa71aa28f48b89323fac Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 25 Mar 2019 17:59:37 +0100 Subject: [PATCH 16/19] code review followup --- .../common/time/JavaDateFormatter.java | 26 +++++++++++-------- .../common/time/JavaDateMathParser.java | 14 +++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index addcb5d7ec788..bd042f428a399 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -86,20 +86,16 @@ class JavaDateFormatter implements DateFormatter { DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); if (format.contains("||") == false) { - builder.append(firstParser()); + builder.append(this.parsers.get(0)); } roundupParserConsumer.accept(builder); - DateTimeFormatter roundupFormatter = builder.toFormatter(firstParser().getLocale()); + DateTimeFormatter roundupFormatter = builder.toFormatter(locale()); if (printer.getZone() != null) { - roundupFormatter = roundupFormatter.withZone(printer.getZone()); + roundupFormatter = roundupFormatter.withZone(zone()); } this.roundupParser = roundupFormatter; } - private DateTimeFormatter firstParser() { - return this.parsers.get(0); - } - DateTimeFormatter getRoundupParser() { return roundupParser; } @@ -121,6 +117,14 @@ public TemporalAccessor parse(String input) { } } + /** + * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) + * patterns. Joda does not suffer from this. + * https://bugs.openjdk.java.net/browse/JDK-8188771 + * + * @param input An arbitrary string resembling the string representation of a date or time + * @return true if parsing was successful, false if parsing failed + */ private TemporalAccessor doParse(String input) { if (parsers.size() > 1) { for (DateTimeFormatter formatter : parsers) { @@ -132,7 +136,7 @@ private TemporalAccessor doParse(String input) { } throw new DateTimeParseException("Failed to parse with all enclosed parsers", input, 0); } - return firstParser().parse(input); + return this.parsers.get(0).parse(input); } private boolean parsingSucceeded(Object object, String input, ParsePosition pos) { @@ -142,7 +146,7 @@ private boolean parsingSucceeded(Object object, String input, ParsePosition pos) @Override public DateFormatter withZone(ZoneId zoneId) { // shortcurt to not create new objects unnecessarily - if (zoneId.equals(firstParser().getZone())) { + if (zoneId.equals(zone())) { return this; } @@ -153,7 +157,7 @@ public DateFormatter withZone(ZoneId zoneId) { @Override public DateFormatter withLocale(Locale locale) { // shortcurt to not create new objects unnecessarily - if (locale.equals(firstParser().getLocale())) { + if (locale.equals(locale())) { return this; } @@ -183,7 +187,7 @@ public ZoneId zone() { @Override public DateMathParser toDateMathParser() { - return new JavaDateMathParser(format, this, getRoundupParser()); + return new JavaDateMathParser(format, this.parsers.get(0), getRoundupParser()); } @Override diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java index dc7c195e2fd6c..517e9c326a65c 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java @@ -35,7 +35,6 @@ import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalQueries; import java.util.Objects; -import java.util.function.Function; import java.util.function.LongSupplier; /** @@ -47,11 +46,11 @@ */ public class JavaDateMathParser implements DateMathParser { - private final JavaDateFormatter formatter; + private final DateTimeFormatter formatter; private final DateTimeFormatter roundUpFormatter; private final String format; - JavaDateMathParser(String format, JavaDateFormatter formatter, DateTimeFormatter roundUpFormatter) { + JavaDateMathParser(String format, DateTimeFormatter formatter, DateTimeFormatter roundUpFormatter) { this.format = format; Objects.requireNonNull(formatter); this.formatter = formatter; @@ -215,13 +214,12 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo if (Strings.isNullOrEmpty(value)) { throw new ElasticsearchParseException("cannot parse empty date"); } - - Function formatter = roundUpIfNoTime ? this.roundUpFormatter::parse : this.formatter::parse; + DateTimeFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter; try { if (timeZone == null) { - return DateFormatters.from(formatter.apply(value)).toInstant(); + return DateFormatters.from(formatter.parse(value)).toInstant(); } else { - TemporalAccessor accessor = formatter.apply(value); + TemporalAccessor accessor = formatter.parse(value); ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor); if (zoneId != null) { timeZone = zoneId; @@ -229,7 +227,7 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo return DateFormatters.from(accessor).withZoneSameLocal(timeZone).toInstant(); } - } catch (IllegalArgumentException | DateTimeParseException e) { + } catch (DateTimeParseException e) { throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]: [{}]", e, value, format, e.getMessage()); } From 3019974cdf0eded730fe6c8b6c9866889d68d432 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 25 Mar 2019 20:18:54 +0100 Subject: [PATCH 17/19] fixing tests --- .../common/time/JavaDateFormatter.java | 2 +- .../common/time/JavaDateMathParser.java | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index bd042f428a399..8a389b7a09e29 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -187,7 +187,7 @@ public ZoneId zone() { @Override public DateMathParser toDateMathParser() { - return new JavaDateMathParser(format, this.parsers.get(0), getRoundupParser()); + return new JavaDateMathParser(format, this, getRoundupParser()); } @Override diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java index 517e9c326a65c..dc7c195e2fd6c 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateMathParser.java @@ -35,6 +35,7 @@ import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalQueries; import java.util.Objects; +import java.util.function.Function; import java.util.function.LongSupplier; /** @@ -46,11 +47,11 @@ */ public class JavaDateMathParser implements DateMathParser { - private final DateTimeFormatter formatter; + private final JavaDateFormatter formatter; private final DateTimeFormatter roundUpFormatter; private final String format; - JavaDateMathParser(String format, DateTimeFormatter formatter, DateTimeFormatter roundUpFormatter) { + JavaDateMathParser(String format, JavaDateFormatter formatter, DateTimeFormatter roundUpFormatter) { this.format = format; Objects.requireNonNull(formatter); this.formatter = formatter; @@ -214,12 +215,13 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo if (Strings.isNullOrEmpty(value)) { throw new ElasticsearchParseException("cannot parse empty date"); } - DateTimeFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter; + + Function formatter = roundUpIfNoTime ? this.roundUpFormatter::parse : this.formatter::parse; try { if (timeZone == null) { - return DateFormatters.from(formatter.parse(value)).toInstant(); + return DateFormatters.from(formatter.apply(value)).toInstant(); } else { - TemporalAccessor accessor = formatter.parse(value); + TemporalAccessor accessor = formatter.apply(value); ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor); if (zoneId != null) { timeZone = zoneId; @@ -227,7 +229,7 @@ private Instant parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNo return DateFormatters.from(accessor).withZoneSameLocal(timeZone).toInstant(); } - } catch (DateTimeParseException e) { + } catch (IllegalArgumentException | DateTimeParseException e) { throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]: [{}]", e, value, format, e.getMessage()); } From 9ffdb897ff252917495602698ceb9655c275a258 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 26 Mar 2019 07:56:35 +0100 Subject: [PATCH 18/19] javadoc --- .../org/elasticsearch/common/time/JavaDateFormatter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 8a389b7a09e29..9523f9750a379 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -118,12 +118,16 @@ public TemporalAccessor parse(String input) { } /** - * Attempt parsing the input without throwing exception. This is needed because java-time requires ordering on optional (composite) + * Attempt parsing the input without throwing exception. If multiple parsers are provided, + * it will continue iterating if the previous parser failed. The pattern must fully match, meaning whole input was used. + * + * The approach with collection of parsers was taken because java-time requires ordering on optional (composite) * patterns. Joda does not suffer from this. * https://bugs.openjdk.java.net/browse/JDK-8188771 * * @param input An arbitrary string resembling the string representation of a date or time - * @return true if parsing was successful, false if parsing failed + * @return a TemporalAccessor if parsing was successful. + * @throws DateTimeParseException when unable to parse wih any parsers */ private TemporalAccessor doParse(String input) { if (parsers.size() > 1) { From f35d0de4b9fab05eb13babc3d4347ee8a716200c Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 26 Mar 2019 15:55:23 +0100 Subject: [PATCH 19/19] javadoc update --- .../java/org/elasticsearch/common/time/JavaDateFormatter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java index 9523f9750a379..d0f4200b3bafe 100644 --- a/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java +++ b/server/src/main/java/org/elasticsearch/common/time/JavaDateFormatter.java @@ -120,6 +120,8 @@ public TemporalAccessor parse(String input) { /** * Attempt parsing the input without throwing exception. If multiple parsers are provided, * it will continue iterating if the previous parser failed. The pattern must fully match, meaning whole input was used. + * This also means that this method depends on DateTimeFormatter.ClassicFormat.parseObject + * which does not throw exceptions when parsing failed. * * The approach with collection of parsers was taken because java-time requires ordering on optional (composite) * patterns. Joda does not suffer from this. @@ -127,7 +129,7 @@ public TemporalAccessor parse(String input) { * * @param input An arbitrary string resembling the string representation of a date or time * @return a TemporalAccessor if parsing was successful. - * @throws DateTimeParseException when unable to parse wih any parsers + * @throws DateTimeParseException when unable to parse with any parsers */ private TemporalAccessor doParse(String input) { if (parsers.size() > 1) {