Browse Source

Remove Joda support from date formatters (#78990)

This commit removes the last bit of support for Joda from date math and
backcompat support. It does not yet remove the dependency.
Ryan Ernst 4 years ago
parent
commit
bddf1cefdd

+ 0 - 46
benchmarks/src/main/java/org/elasticsearch/benchmark/time/DateFormatterBenchmark.java

@@ -1,46 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-package org.elasticsearch.benchmark.time;
-
-import org.elasticsearch.common.joda.Joda;
-import org.elasticsearch.common.time.DateFormatter;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Fork;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.Warmup;
-
-import java.time.temporal.TemporalAccessor;
-import java.util.concurrent.TimeUnit;
-
-@Fork(3)
-@Warmup(iterations = 10)
-@Measurement(iterations = 10)
-@BenchmarkMode(Mode.AverageTime)
-@OutputTimeUnit(TimeUnit.NANOSECONDS)
-@State(Scope.Benchmark)
-@SuppressWarnings("unused") // invoked by benchmarking framework
-public class DateFormatterBenchmark {
-
-    private final DateFormatter javaFormatter = DateFormatter.forPattern("8year_month_day||ordinal_date||epoch_millis");
-    private final DateFormatter jodaFormatter = Joda.forPattern("year_month_day||ordinal_date||epoch_millis");
-
-    @Benchmark
-    public TemporalAccessor parseJavaDate() {
-        return javaFormatter.parse("1234567890");
-    }
-
-    @Benchmark
-    public TemporalAccessor parseJodaDate() {
-        return jodaFormatter.parse("1234567890");
-    }
-}

+ 0 - 3
server/build.gradle

@@ -261,9 +261,6 @@ tasks.named('splitPackagesAudit').configure {
     // but this should be fixed in Lucene 9
     'org.apache.lucene.index.LazySoftDeletesDirectoryReaderWrapper',
 
-    // Joda should own its own packages! This should be a simple move.
-    'org.joda.time.format.StrictISODateTimeFormat',
-
     // cli is owned by the libs/cli, so these should be moved to o.e.server.cli
     'org.elasticsearch.cli.CommandLoggingConfigurator',
     'org.elasticsearch.cli.EnvironmentAwareCommand',

+ 0 - 474
server/src/main/java/org/elasticsearch/common/joda/Joda.java

@@ -1,474 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.common.joda;
-
-import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.logging.DeprecationCategory;
-import org.elasticsearch.common.logging.DeprecationLogger;
-import org.elasticsearch.common.time.DateFormatter;
-import org.elasticsearch.common.time.FormatNames;
-import org.elasticsearch.common.util.LazyInitializable;
-import org.joda.time.Chronology;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeField;
-import org.joda.time.DateTimeFieldType;
-import org.joda.time.DateTimeZone;
-import org.joda.time.DurationField;
-import org.joda.time.DurationFieldType;
-import org.joda.time.ReadablePartial;
-import org.joda.time.field.DividedDateTimeField;
-import org.joda.time.field.OffsetDateTimeField;
-import org.joda.time.field.ScaledDurationField;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.DateTimeFormatterBuilder;
-import org.joda.time.format.DateTimeParser;
-import org.joda.time.format.DateTimeParserBucket;
-import org.joda.time.format.DateTimePrinter;
-import org.joda.time.format.ISODateTimeFormat;
-import org.joda.time.format.StrictISODateTimeFormat;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.math.BigDecimal;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-@Deprecated
-public class Joda {
-    // Joda.forPattern could be used even before the logging is initialized.
-    // If LogManager.getLogger is called before logging config is loaded
-    // it results in errors sent to status logger and startup to fail.
-    // Hence a lazy initialization.
-    private static final LazyInitializable<DeprecationLogger, RuntimeException> deprecationLogger
-        = new LazyInitializable<>(() -> DeprecationLogger.getLogger(FormatNames.class));
-    /**
-     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
-     */
-    public static JodaDateFormatter forPattern(String input) {
-        if (Strings.hasLength(input)) {
-            input = input.trim();
-        }
-        if (input == null || input.length() == 0) {
-            throw new IllegalArgumentException("No date pattern provided");
-        }
-
-        DateTimeFormatter formatter;
-        if ("basicDate".equals(input) || "basic_date".equals(input)) {
-            formatter = ISODateTimeFormat.basicDate();
-        } else if ("basicDateTime".equals(input) || "basic_date_time".equals(input)) {
-            formatter = ISODateTimeFormat.basicDateTime();
-        } else if ("basicDateTimeNoMillis".equals(input) || "basic_date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.basicDateTimeNoMillis();
-        } else if ("basicOrdinalDate".equals(input) || "basic_ordinal_date".equals(input)) {
-            formatter = ISODateTimeFormat.basicOrdinalDate();
-        } else if ("basicOrdinalDateTime".equals(input) || "basic_ordinal_date_time".equals(input)) {
-            formatter = ISODateTimeFormat.basicOrdinalDateTime();
-        } else if ("basicOrdinalDateTimeNoMillis".equals(input) || "basic_ordinal_date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.basicOrdinalDateTimeNoMillis();
-        } else if ("basicTime".equals(input) || "basic_time".equals(input)) {
-            formatter = ISODateTimeFormat.basicTime();
-        } else if ("basicTimeNoMillis".equals(input) || "basic_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.basicTimeNoMillis();
-        } else if ("basicTTime".equals(input) || "basic_t_time".equals(input)) {
-            formatter = ISODateTimeFormat.basicTTime();
-        } else if ("basicTTimeNoMillis".equals(input) || "basic_t_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.basicTTimeNoMillis();
-        } else if ("basicWeekDate".equals(input) || "basic_week_date".equals(input)) {
-            formatter = ISODateTimeFormat.basicWeekDate();
-        } else if ("basicWeekDateTime".equals(input) || "basic_week_date_time".equals(input)) {
-            formatter = ISODateTimeFormat.basicWeekDateTime();
-        } else if ("basicWeekDateTimeNoMillis".equals(input) || "basic_week_date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.basicWeekDateTimeNoMillis();
-        } else if ("date".equals(input)) {
-            formatter = ISODateTimeFormat.date();
-        } else if ("dateHour".equals(input) || "date_hour".equals(input)) {
-            formatter = ISODateTimeFormat.dateHour();
-        } else if ("dateHourMinute".equals(input) || "date_hour_minute".equals(input)) {
-            formatter = ISODateTimeFormat.dateHourMinute();
-        } else if ("dateHourMinuteSecond".equals(input) || "date_hour_minute_second".equals(input)) {
-            formatter = ISODateTimeFormat.dateHourMinuteSecond();
-        } else if ("dateHourMinuteSecondFraction".equals(input) || "date_hour_minute_second_fraction".equals(input)) {
-            formatter = ISODateTimeFormat.dateHourMinuteSecondFraction();
-        } else if ("dateHourMinuteSecondMillis".equals(input) || "date_hour_minute_second_millis".equals(input)) {
-            formatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
-        } else if ("dateOptionalTime".equals(input) || "date_optional_time".equals(input)) {
-            // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
-            // this sucks we should use the root local by default and not be dependent on the node
-            return new JodaDateFormatter(input,
-                    ISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970),
-                    ISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
-        } else if ("dateTime".equals(input) || "date_time".equals(input)) {
-            formatter = ISODateTimeFormat.dateTime();
-        } else if ("dateTimeNoMillis".equals(input) || "date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.dateTimeNoMillis();
-        } else if ("hour".equals(input)) {
-            formatter = ISODateTimeFormat.hour();
-        } else if ("hourMinute".equals(input) || "hour_minute".equals(input)) {
-            formatter = ISODateTimeFormat.hourMinute();
-        } else if ("hourMinuteSecond".equals(input) || "hour_minute_second".equals(input)) {
-            formatter = ISODateTimeFormat.hourMinuteSecond();
-        } else if ("hourMinuteSecondFraction".equals(input) || "hour_minute_second_fraction".equals(input)) {
-            formatter = ISODateTimeFormat.hourMinuteSecondFraction();
-        } else if ("hourMinuteSecondMillis".equals(input) || "hour_minute_second_millis".equals(input)) {
-            formatter = ISODateTimeFormat.hourMinuteSecondMillis();
-        } else if ("ordinalDate".equals(input) || "ordinal_date".equals(input)) {
-            formatter = ISODateTimeFormat.ordinalDate();
-        } else if ("ordinalDateTime".equals(input) || "ordinal_date_time".equals(input)) {
-            formatter = ISODateTimeFormat.ordinalDateTime();
-        } else if ("ordinalDateTimeNoMillis".equals(input) || "ordinal_date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.ordinalDateTimeNoMillis();
-        } else if ("time".equals(input)) {
-            formatter = ISODateTimeFormat.time();
-        } else if ("timeNoMillis".equals(input) || "time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.timeNoMillis();
-        } else if ("tTime".equals(input) || "t_time".equals(input)) {
-            formatter = ISODateTimeFormat.tTime();
-        } else if ("tTimeNoMillis".equals(input) || "t_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.tTimeNoMillis();
-        } else if ("weekDate".equals(input) || "week_date".equals(input)) {
-            formatter = ISODateTimeFormat.weekDate();
-        } else if ("weekDateTime".equals(input) || "week_date_time".equals(input)) {
-            formatter = ISODateTimeFormat.weekDateTime();
-        } else if ("weekDateTimeNoMillis".equals(input) || "week_date_time_no_millis".equals(input)) {
-            formatter = ISODateTimeFormat.weekDateTimeNoMillis();
-        } else if ("weekyear".equals(input) ) {
-            formatter = ISODateTimeFormat.weekyear();
-        } else if ("weekyearWeek".equals(input) || "weekyear_week".equals(input)) {
-            formatter = ISODateTimeFormat.weekyearWeek();
-        } else if ("weekyearWeekDay".equals(input) || "weekyear_week_day".equals(input)) {
-            formatter = ISODateTimeFormat.weekyearWeekDay();
-        } else if ("year".equals(input)) {
-            formatter = ISODateTimeFormat.year();
-        } else if ("yearMonth".equals(input) || "year_month".equals(input)) {
-            formatter = ISODateTimeFormat.yearMonth();
-        } else if ("yearMonthDay".equals(input) || "year_month_day".equals(input)) {
-            formatter = ISODateTimeFormat.yearMonthDay();
-        } else if ("epoch_second".equals(input)) {
-            formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(false),
-                new EpochTimeParser(false)).toFormatter();
-        } else if ("epoch_millis".equals(input)) {
-            formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(true),
-                new EpochTimeParser(true)).toFormatter();
-        // strict date formats here, must be at least 4 digits for year and two for months and two for day
-        } else if ("strictBasicWeekDate".equals(input) || "strict_basic_week_date".equals(input)) {
-            formatter = StrictISODateTimeFormat.basicWeekDate();
-        } else if ("strictBasicWeekDateTime".equals(input) || "strict_basic_week_date_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.basicWeekDateTime();
-        } else if ("strictBasicWeekDateTimeNoMillis".equals(input) || "strict_basic_week_date_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.basicWeekDateTimeNoMillis();
-        } else if ("strictDate".equals(input) || "strict_date".equals(input)) {
-            formatter = StrictISODateTimeFormat.date();
-        } else if ("strictDateHour".equals(input) || "strict_date_hour".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateHour();
-        } else if ("strictDateHourMinute".equals(input) || "strict_date_hour_minute".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateHourMinute();
-        } else if ("strictDateHourMinuteSecond".equals(input) || "strict_date_hour_minute_second".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateHourMinuteSecond();
-        } else if ("strictDateHourMinuteSecondFraction".equals(input) || "strict_date_hour_minute_second_fraction".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateHourMinuteSecondFraction();
-        } else if ("strictDateHourMinuteSecondMillis".equals(input) || "strict_date_hour_minute_second_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateHourMinuteSecondMillis();
-        } else if ("strictDateOptionalTime".equals(input) || "strict_date_optional_time".equals(input)) {
-            // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
-            // this sucks we should use the root local by default and not be dependent on the node
-            return new JodaDateFormatter(input,
-                    StrictISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC)
-                        .withDefaultYear(1970),
-                    StrictISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
-        } else if ("strictDateTime".equals(input) || "strict_date_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateTime();
-        } else if ("strictDateTimeNoMillis".equals(input) || "strict_date_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.dateTimeNoMillis();
-        } else if ("strictHour".equals(input) || "strict_hour".equals(input)) {
-            formatter = StrictISODateTimeFormat.hour();
-        } else if ("strictHourMinute".equals(input) || "strict_hour_minute".equals(input)) {
-            formatter = StrictISODateTimeFormat.hourMinute();
-        } else if ("strictHourMinuteSecond".equals(input) || "strict_hour_minute_second".equals(input)) {
-            formatter = StrictISODateTimeFormat.hourMinuteSecond();
-        } else if ("strictHourMinuteSecondFraction".equals(input) || "strict_hour_minute_second_fraction".equals(input)) {
-            formatter = StrictISODateTimeFormat.hourMinuteSecondFraction();
-        } else if ("strictHourMinuteSecondMillis".equals(input) || "strict_hour_minute_second_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.hourMinuteSecondMillis();
-        } else if ("strictOrdinalDate".equals(input) || "strict_ordinal_date".equals(input)) {
-            formatter = StrictISODateTimeFormat.ordinalDate();
-        } else if ("strictOrdinalDateTime".equals(input) || "strict_ordinal_date_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.ordinalDateTime();
-        } else if ("strictOrdinalDateTimeNoMillis".equals(input) || "strict_ordinal_date_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.ordinalDateTimeNoMillis();
-        } else if ("strictTime".equals(input) || "strict_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.time();
-        } else if ("strictTimeNoMillis".equals(input) || "strict_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.timeNoMillis();
-        } else if ("strictTTime".equals(input) || "strict_t_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.tTime();
-        } else if ("strictTTimeNoMillis".equals(input) || "strict_t_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.tTimeNoMillis();
-        } else if ("strictWeekDate".equals(input) || "strict_week_date".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekDate();
-        } else if ("strictWeekDateTime".equals(input) || "strict_week_date_time".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekDateTime();
-        } else if ("strictWeekDateTimeNoMillis".equals(input) || "strict_week_date_time_no_millis".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekDateTimeNoMillis();
-        } else if ("strictWeekyear".equals(input) || "strict_weekyear".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekyear();
-        } else if ("strictWeekyearWeek".equals(input) || "strict_weekyear_week".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekyearWeek();
-        } else if ("strictWeekyearWeekDay".equals(input) || "strict_weekyear_week_day".equals(input)) {
-            formatter = StrictISODateTimeFormat.weekyearWeekDay();
-        } else if ("strictYear".equals(input) || "strict_year".equals(input)) {
-            formatter = StrictISODateTimeFormat.year();
-        } else if ("strictYearMonth".equals(input) || "strict_year_month".equals(input)) {
-            formatter = StrictISODateTimeFormat.yearMonth();
-        } else if ("strictYearMonthDay".equals(input) || "strict_year_month_day".equals(input)) {
-            formatter = StrictISODateTimeFormat.yearMonthDay();
-        } else if (Strings.hasLength(input) && input.contains("||")) {
-            String[] formats = Strings.delimitedListToStringArray(input, "||");
-            DateTimeParser[] parsers = new DateTimeParser[formats.length];
-
-            if (formats.length == 1) {
-                formatter = forPattern(input).parser;
-            } else {
-                DateTimeFormatter dateTimeFormatter = null;
-                for (int i = 0; i < formats.length; i++) {
-                    JodaDateFormatter currentFormatter = forPattern(formats[i]);
-                    DateTimeFormatter currentParser = currentFormatter.parser;
-                    if (dateTimeFormatter == null) {
-                        dateTimeFormatter = currentFormatter.printer;
-                    }
-                    parsers[i] = currentParser.getParser();
-                }
-
-                DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
-                    .append(dateTimeFormatter.withZone(DateTimeZone.UTC).getPrinter(), parsers);
-                formatter = builder.toFormatter();
-            }
-        } else {
-            try {
-                maybeLogJodaDeprecation(input);
-                formatter = DateTimeFormat.forPattern(input);
-            } catch (IllegalArgumentException e) {
-                throw new IllegalArgumentException("Invalid format: [" + input + "]: " + e.getMessage(), e);
-            }
-        }
-
-        formatter = formatter.withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970);
-        return new JodaDateFormatter(input, formatter, formatter);
-    }
-
-    private static void maybeLogJodaDeprecation(String input) {
-        if (input.contains("CC")) {
-            getDeprecationLogger().critical(DeprecationCategory.PARSING, "joda-century-of-era-format",
-                "Use of 'C' (century-of-era) is deprecated and will not be supported in the next major version of Elasticsearch.");
-        }
-        if (input.contains("YY")) {
-            getDeprecationLogger().critical(DeprecationCategory.PARSING, "joda-year-of-era-format",
-                "Use of 'Y' (year-of-era) will change to 'y' in the" +
-                    " next major version of Elasticsearch. Prefix your date format with '8' to use the new specifier.");
-        }
-        if (input.contains("xx")) {
-            getDeprecationLogger().critical(DeprecationCategory.PARSING, "joda-week-based-year-format",
-                "Use of 'x' (week-based-year) will change" +
-                " to 'Y' in the next major version of Elasticsearch. Prefix your date format with '8' to use the new specifier.");
-        }
-    }
-
-    public static DateFormatter getStrictStandardDateFormatter() {
-        // 2014/10/10
-        DateTimeFormatter shortFormatter = new DateTimeFormatterBuilder()
-                .appendFixedDecimal(DateTimeFieldType.year(), 4)
-                .appendLiteral('/')
-                .appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
-                .appendLiteral('/')
-                .appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
-                .toFormatter()
-                .withZoneUTC();
-
-        // 2014/10/10 12:12:12
-        DateTimeFormatter longFormatter = new DateTimeFormatterBuilder()
-                .appendFixedDecimal(DateTimeFieldType.year(), 4)
-                .appendLiteral('/')
-                .appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
-                .appendLiteral('/')
-                .appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
-                .appendLiteral(' ')
-                .appendFixedSignedDecimal(DateTimeFieldType.hourOfDay(), 2)
-                .appendLiteral(':')
-                .appendFixedSignedDecimal(DateTimeFieldType.minuteOfHour(), 2)
-                .appendLiteral(':')
-                .appendFixedSignedDecimal(DateTimeFieldType.secondOfMinute(), 2)
-                .toFormatter()
-                .withZoneUTC();
-
-        DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder().append(longFormatter.withZone(DateTimeZone.UTC).getPrinter(),
-            new DateTimeParser[]{longFormatter.getParser(), shortFormatter.getParser(), new EpochTimeParser(true)});
-
-        DateTimeFormatter formatter = builder.toFormatter().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970);
-        return new JodaDateFormatter("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis", formatter, formatter);
-    }
-
-
-    public static final DurationFieldType Quarters = new DurationFieldType("quarters") {
-        @Override
-        public DurationField getField(Chronology chronology) {
-            return new ScaledDurationField(chronology.months(), Quarters, 3);
-        }
-    };
-
-    public static final DateTimeFieldType QuarterOfYear = new DateTimeFieldType("quarterOfYear") {
-        @Override
-        public DurationFieldType getDurationType() {
-            return Quarters;
-        }
-
-        @Override
-        public DurationFieldType getRangeDurationType() {
-            return DurationFieldType.years();
-        }
-
-        @Override
-        public DateTimeField getField(Chronology chronology) {
-            return new OffsetDateTimeField(
-                new DividedDateTimeField(new OffsetDateTimeField(chronology.monthOfYear(), -1), QuarterOfYear, 3), 1);
-        }
-    };
-
-    public static class EpochTimeParser implements DateTimeParser {
-
-        private static final Pattern scientificNotation = Pattern.compile("[Ee]");
-
-        private final boolean hasMilliSecondPrecision;
-
-        public EpochTimeParser(boolean hasMilliSecondPrecision) {
-            this.hasMilliSecondPrecision = hasMilliSecondPrecision;
-        }
-
-        @Override
-        public int estimateParsedLength() {
-            return hasMilliSecondPrecision ? 19 : 16;
-        }
-
-        @Override
-        public int parseInto(DateTimeParserBucket bucket, String text, int position) {
-            boolean isPositive = text.startsWith("-") == false;
-            int firstDotIndex = text.indexOf('.');
-            boolean isTooLong = (firstDotIndex == -1 ? text.length() : firstDotIndex) > estimateParsedLength();
-
-            if (bucket.getZone() != DateTimeZone.UTC) {
-                String format = hasMilliSecondPrecision ? "epoch_millis" : "epoch_second";
-                throw new IllegalArgumentException("time_zone must be UTC for format [" + format + "]");
-            } else if (isPositive && isTooLong) {
-                return -1;
-            }
-
-            int factor = hasMilliSecondPrecision ? 1 : 1000;
-            try {
-                long millis = new BigDecimal(text).longValue() * factor;
-                // check for deprecations, but after it has parsed correctly so invalid values aren't counted as deprecated
-                if (millis < 0) {
-                    getDeprecationLogger().critical(DeprecationCategory.PARSING, "epoch-negative", "Use of negative values" +
-                        " in epoch time formats is deprecated and will not be supported in the next major version of Elasticsearch.");
-                }
-                if (scientificNotation.matcher(text).find()) {
-                    getDeprecationLogger().critical(DeprecationCategory.PARSING, "epoch-scientific-notation",
-                        "Use of scientific notation" +
-                        " in epoch time formats is deprecated and will not be supported in the next major version of Elasticsearch.");
-                }
-                DateTime dt = new DateTime(millis, DateTimeZone.UTC);
-                bucket.saveField(DateTimeFieldType.year(), dt.getYear());
-                bucket.saveField(DateTimeFieldType.monthOfYear(), dt.getMonthOfYear());
-                bucket.saveField(DateTimeFieldType.dayOfMonth(), dt.getDayOfMonth());
-                bucket.saveField(DateTimeFieldType.hourOfDay(), dt.getHourOfDay());
-                bucket.saveField(DateTimeFieldType.minuteOfHour(), dt.getMinuteOfHour());
-                bucket.saveField(DateTimeFieldType.secondOfMinute(), dt.getSecondOfMinute());
-                bucket.saveField(DateTimeFieldType.millisOfSecond(), dt.getMillisOfSecond());
-                bucket.setZone(DateTimeZone.UTC);
-            } catch (Exception e) {
-                return -1;
-            }
-            return text.length();
-        }
-    }
-
-    private static DeprecationLogger getDeprecationLogger() {
-        return deprecationLogger.getOrCompute();
-    }
-
-    public static class EpochTimePrinter implements DateTimePrinter {
-
-        private boolean hasMilliSecondPrecision;
-
-        public EpochTimePrinter(boolean hasMilliSecondPrecision) {
-            this.hasMilliSecondPrecision = hasMilliSecondPrecision;
-        }
-
-        @Override
-        public int estimatePrintedLength() {
-            return hasMilliSecondPrecision ? 19 : 16;
-        }
-
-
-        /**
-         * We adjust the instant by displayOffset to adjust for the offset that might have been added in
-         * {@link DateTimeFormatter#printTo(Appendable, long, Chronology)} when using a time zone.
-         */
-        @Override
-        public void printTo(StringBuffer buf, long instant, Chronology chrono, int displayOffset, DateTimeZone displayZone, Locale locale) {
-            if (hasMilliSecondPrecision) {
-                buf.append(instant - displayOffset);
-            } else {
-                buf.append((instant  - displayOffset) / 1000);
-            }
-        }
-
-        /**
-         * We adjust the instant by displayOffset to adjust for the offset that might have been added in
-         * {@link DateTimeFormatter#printTo(Appendable, long, Chronology)} when using a time zone.
-         */
-        @Override
-        public void printTo(Writer out, long instant, Chronology chrono, int displayOffset,
-                            DateTimeZone displayZone, Locale locale) throws IOException {
-            if (hasMilliSecondPrecision) {
-                out.write(String.valueOf(instant - displayOffset));
-            } else {
-                out.append(String.valueOf((instant - displayOffset) / 1000));
-            }
-        }
-
-        @Override
-        public void printTo(StringBuffer buf, ReadablePartial partial, Locale locale) {
-            if (hasMilliSecondPrecision) {
-                buf.append(String.valueOf(getDateTimeMillis(partial)));
-            } else {
-                buf.append(String.valueOf(getDateTimeMillis(partial) / 1000));
-            }
-        }
-
-        @Override
-        public void printTo(Writer out, ReadablePartial partial, Locale locale) throws IOException {
-            if (hasMilliSecondPrecision) {
-                out.append(String.valueOf(getDateTimeMillis(partial)));
-            } else {
-                out.append(String.valueOf(getDateTimeMillis(partial) / 1000));
-            }
-        }
-
-        private long getDateTimeMillis(ReadablePartial partial) {
-            int year = partial.get(DateTimeFieldType.year());
-            int monthOfYear = partial.get(DateTimeFieldType.monthOfYear());
-            int dayOfMonth = partial.get(DateTimeFieldType.dayOfMonth());
-            int hourOfDay = partial.get(DateTimeFieldType.hourOfDay());
-            int minuteOfHour = partial.get(DateTimeFieldType.minuteOfHour());
-            int secondOfMinute = partial.get(DateTimeFieldType.secondOfMinute());
-            int millisOfSecond = partial.get(DateTimeFieldType.millisOfSecond());
-            return partial.getChronology().getDateTimeMillis(year, monthOfYear, dayOfMonth,
-                hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
-        }
-    }
-}

+ 0 - 130
server/src/main/java/org/elasticsearch/common/joda/JodaDateFormatter.java

@@ -1,130 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.common.joda;
-
-import org.elasticsearch.common.time.DateFormatter;
-import org.elasticsearch.common.time.DateMathParser;
-import org.elasticsearch.common.time.DateUtils;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.joda.time.format.DateTimeFormatter;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.temporal.TemporalAccessor;
-import java.util.Locale;
-import java.util.Objects;
-
-public class JodaDateFormatter implements DateFormatter {
-
-    final String pattern;
-    final DateTimeFormatter parser;
-    final DateTimeFormatter printer;
-
-    JodaDateFormatter(String pattern, DateTimeFormatter parser, DateTimeFormatter printer) {
-        this.pattern = pattern;
-        this.printer = printer;
-        this.parser = parser;
-    }
-
-    @Override
-    public TemporalAccessor parse(String input) {
-        final DateTime dt = parser.parseDateTime(input);
-        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(dt.getMillis()), DateUtils.dateTimeZoneToZoneId(dt.getZone()));
-    }
-
-    public long parseMillis(String input) {
-        return parser.parseMillis(input);
-    }
-
-    public DateTime parseJoda(String input) {
-        return parser.parseDateTime(input);
-    }
-
-    @Override
-    public DateFormatter withZone(ZoneId zoneId) {
-        DateTimeZone timeZone = DateUtils.zoneIdToDateTimeZone(zoneId);
-        if (parser.getZone().equals(timeZone)) {
-            return this;
-        }
-        DateTimeFormatter parser = this.parser.withZone(timeZone);
-        DateTimeFormatter printer = this.printer.withZone(timeZone);
-        return new JodaDateFormatter(pattern, parser, printer);
-    }
-
-    @Override
-    public DateFormatter withLocale(Locale locale) {
-        if (parser.getLocale().equals(locale)) {
-            return this;
-        }
-        DateTimeFormatter parser = this.parser.withLocale(locale);
-        DateTimeFormatter printer = this.printer.withLocale(locale);
-        return new JodaDateFormatter(pattern, parser, printer);
-    }
-
-    @Override
-    public String format(TemporalAccessor accessor) {
-        DateTimeZone timeZone = DateUtils.zoneIdToDateTimeZone(ZoneId.from(accessor));
-        DateTime dateTime = new DateTime(Instant.from(accessor).toEpochMilli(), timeZone);
-        return printer.print(dateTime);
-    }
-
-    public String formatJoda(DateTime dateTime) {
-        return printer.print(dateTime);
-    }
-
-    public String formatMillis(long millis) {
-        return printer.print(millis);
-    }
-
-    public JodaDateFormatter withYear(int year) {
-        if (parser.getDefaultYear() == year) {
-            return this;
-        }
-        return new JodaDateFormatter(pattern, parser.withDefaultYear(year), printer.withDefaultYear(year));
-    }
-
-    @Override
-    public String pattern() {
-        return pattern;
-    }
-
-    @Override
-    public Locale locale() {
-        return printer.getLocale();
-    }
-
-    @Override
-    public ZoneId zone() {
-        return DateUtils.dateTimeZoneToZoneId(printer.getZone());
-    }
-
-    @Override
-    public DateMathParser toDateMathParser() {
-        return new JodaDateMathParser(this);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(locale(), zone(), pattern());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj.getClass().equals(this.getClass()) == false) {
-            return false;
-        }
-        JodaDateFormatter other = (JodaDateFormatter) obj;
-
-        return Objects.equals(pattern(), other.pattern()) &&
-            Objects.equals(locale(), other.locale()) &&
-            Objects.equals(zone(), other.zone());
-    }
-}

+ 0 - 209
server/src/main/java/org/elasticsearch/common/joda/JodaDateMathParser.java

@@ -1,209 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.common.joda;
-
-import org.elasticsearch.ElasticsearchParseException;
-import org.elasticsearch.common.time.DateMathParser;
-import org.elasticsearch.common.time.DateUtils;
-import org.joda.time.DateTimeZone;
-import org.joda.time.MutableDateTime;
-import org.joda.time.format.DateTimeFormatter;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.util.Objects;
-import java.util.function.LongSupplier;
-
-/**
- * A parser for date/time formatted text with optional date math.
- *
- * The format of the datetime is configurable, and unix timestamps can also be used. Datemath
- * is appended to a datetime with the following syntax:
- * <code>||[+-/](\d+)?[yMwdhHms]</code>.
- */
-public class JodaDateMathParser implements DateMathParser {
-
-    private final JodaDateFormatter dateTimeFormatter;
-
-    public JodaDateMathParser(JodaDateFormatter dateTimeFormatter) {
-        Objects.requireNonNull(dateTimeFormatter);
-        this.dateTimeFormatter = dateTimeFormatter;
-    }
-
-    // Note: we take a callable here for the timestamp in order to be able to figure out
-    // if it has been used. For instance, the request cache does not cache requests that make
-    // use of `now`.
-    @Override
-    public Instant parse(String text, LongSupplier now, boolean roundUp, ZoneId tz) {
-        final DateTimeZone timeZone = tz == null ? null : DateUtils.zoneIdToDateTimeZone(tz);
-        long time;
-        String mathString;
-        if (text.startsWith("now")) {
-            try {
-                time = now.getAsLong();
-            } catch (Exception e) {
-                throw new ElasticsearchParseException("could not read the current timestamp", e);
-            }
-            mathString = text.substring("now".length());
-        } else {
-            int index = text.indexOf("||");
-            if (index == -1) {
-                return Instant.ofEpochMilli(parseDateTime(text, timeZone, roundUp));
-            }
-            time = parseDateTime(text.substring(0, index), timeZone, false);
-            mathString = text.substring(index + 2);
-        }
-
-        return Instant.ofEpochMilli(parseMath(mathString, time, roundUp, timeZone));
-    }
-
-    private long parseMath(String mathString, long time, boolean roundUp, DateTimeZone timeZone) throws ElasticsearchParseException {
-        if (timeZone == null) {
-            timeZone = DateTimeZone.UTC;
-        }
-        MutableDateTime dateTime = new MutableDateTime(time, timeZone);
-        for (int i = 0; i < mathString.length(); ) {
-            char c = mathString.charAt(i++);
-            final boolean round;
-            final int sign;
-            if (c == '/') {
-                round = true;
-                sign = 1;
-            } else {
-                round = false;
-                if (c == '+') {
-                    sign = 1;
-                } else if (c == '-') {
-                    sign = -1;
-                } else {
-                    throw new ElasticsearchParseException("operator not supported for date math [{}]", mathString);
-                }
-            }
-
-            if (i >= mathString.length()) {
-                throw new ElasticsearchParseException("truncated date math [{}]", mathString);
-            }
-
-            final int num;
-            if (Character.isDigit(mathString.charAt(i)) == false) {
-                num = 1;
-            } else {
-                int numFrom = i;
-                while (i < mathString.length() && Character.isDigit(mathString.charAt(i))) {
-                    i++;
-                }
-                if (i >= mathString.length()) {
-                    throw new ElasticsearchParseException("truncated date math [{}]", mathString);
-                }
-                num = Integer.parseInt(mathString.substring(numFrom, i));
-            }
-            if (round) {
-                if (num != 1) {
-                    throw new ElasticsearchParseException("rounding `/` can only be used on single unit types [{}]", mathString);
-                }
-            }
-            char unit = mathString.charAt(i++);
-            MutableDateTime.Property propertyToRound = null;
-            switch (unit) {
-                case 'y':
-                    if (round) {
-                        propertyToRound = dateTime.yearOfCentury();
-                    } else {
-                        dateTime.addYears(sign * num);
-                    }
-                    break;
-                case 'M':
-                    if (round) {
-                        propertyToRound = dateTime.monthOfYear();
-                    } else {
-                        dateTime.addMonths(sign * num);
-                    }
-                    break;
-                case 'w':
-                    if (round) {
-                        propertyToRound = dateTime.weekOfWeekyear();
-                    } else {
-                        dateTime.addWeeks(sign * num);
-                    }
-                    break;
-                case 'd':
-                    if (round) {
-                        propertyToRound = dateTime.dayOfMonth();
-                    } else {
-                        dateTime.addDays(sign * num);
-                    }
-                    break;
-                case 'h':
-                case 'H':
-                    if (round) {
-                        propertyToRound = dateTime.hourOfDay();
-                    } else {
-                        dateTime.addHours(sign * num);
-                    }
-                    break;
-                case 'm':
-                    if (round) {
-                        propertyToRound = dateTime.minuteOfHour();
-                    } else {
-                        dateTime.addMinutes(sign * num);
-                    }
-                    break;
-                case 's':
-                    if (round) {
-                        propertyToRound = dateTime.secondOfMinute();
-                    } else {
-                        dateTime.addSeconds(sign * num);
-                    }
-                    break;
-                default:
-                    throw new ElasticsearchParseException("unit [{}] not supported for date math [{}]", unit, mathString);
-            }
-            if (propertyToRound != null) {
-                if (roundUp) {
-                    // we want to go up to the next whole value, even if we are already on a rounded value
-                    propertyToRound.add(1);
-                    propertyToRound.roundFloor();
-                    dateTime.addMillis(-1); // subtract 1 millisecond to get the largest inclusive value
-                } else {
-                    propertyToRound.roundFloor();
-                }
-            }
-        }
-        return dateTime.getMillis();
-    }
-
-    private long parseDateTime(String value, DateTimeZone timeZone, boolean roundUpIfNoTime) {
-        DateTimeFormatter parser = dateTimeFormatter.parser;
-        if (timeZone != null) {
-            parser = parser.withZone(timeZone);
-        }
-        try {
-            MutableDateTime date;
-            // We use 01/01/1970 as a base date so that things keep working with date
-            // fields that are filled with times without dates
-            if (roundUpIfNoTime) {
-                date = new MutableDateTime(1970, 1, 1, 23, 59, 59, 999, DateTimeZone.UTC);
-            } else {
-                date = new MutableDateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeZone.UTC);
-            }
-            final int end = parser.parseInto(date, value, 0);
-            if (end < 0) {
-                int position = ~end;
-                throw new IllegalArgumentException("Parse failure at index [" + position + "] of [" + value + "]");
-            } else if (end != value.length()) {
-                throw new IllegalArgumentException("Unrecognized chars at the end of [" + value + "]: [" + value.substring(end) + "]");
-            }
-            return date.getMillis();
-        } catch (IllegalArgumentException e) {
-            throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]", e, value,
-                dateTimeFormatter.pattern());
-        }
-    }
-
-}

+ 0 - 18
server/src/main/java/org/elasticsearch/common/time/DateFormatter.java

@@ -9,12 +9,10 @@
 package org.elasticsearch.common.time;
 
 import org.elasticsearch.common.Strings;
-import org.joda.time.DateTime;
 
 import java.time.Instant;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.TemporalAccessor;
 import java.util.ArrayList;
@@ -39,14 +37,6 @@ public interface DateFormatter {
         return DateFormatters.from(parse(input)).toInstant().toEpochMilli();
     }
 
-    /**
-     * Parse the given input into a Joda {@link DateTime}.
-     */
-    default DateTime parseJoda(String input) {
-        ZonedDateTime dateTime = ZonedDateTime.from(parse(input));
-        return new DateTime(dateTime.toInstant().toEpochMilli(), DateUtils.zoneIdToDateTimeZone(dateTime.getZone()));
-    }
-
     /**
      * Create a copy of this formatter that is configured to parse dates in the specified time zone
      *
@@ -79,14 +69,6 @@ public interface DateFormatter {
         return format(Instant.ofEpochMilli(millis).atZone(zone));
     }
 
-    /**
-     * Return the given Joda {@link DateTime} formatted with this format.
-     */
-    default String formatJoda(DateTime dateTime) {
-        return format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(dateTime.getMillis()),
-            DateUtils.dateTimeZoneToZoneId(dateTime.getZone())));
-    }
-
     /**
      * A name based format for this formatter. Can be one of the registered formatters like <code>epoch_millis</code> or
      * a configured format like <code>HH:mm:ss</code>

+ 1 - 9
server/src/main/java/org/elasticsearch/common/time/DateMathParser.java

@@ -8,8 +8,6 @@
 
 package org.elasticsearch.common.time;
 
-import org.joda.time.DateTimeZone;
-
 import java.time.Instant;
 import java.time.ZoneId;
 import java.util.function.LongSupplier;
@@ -23,19 +21,13 @@ public interface DateMathParser {
      * Parse a date math expression without timezone info and rounding down.
      */
     default Instant parse(String text, LongSupplier now) {
-        return parse(text, now, false, (ZoneId) null);
+        return parse(text, now, false, null);
     }
 
     // Note: we take a callable here for the timestamp in order to be able to figure out
     // if it has been used. For instance, the request cache does not cache requests that make
     // use of `now`.
 
-    // exists for backcompat, do not use!
-    @Deprecated
-    default Instant parse(String text, LongSupplier now, boolean roundUpProperty, DateTimeZone tz) {
-        return parse(text, now, roundUpProperty, tz == null ? null : ZoneId.of(tz.getID()));
-    }
-
     /**
      * Parse text, that potentially contains date math into the milliseconds since the epoch
      *

+ 0 - 24
server/src/main/java/org/elasticsearch/common/time/DateUtils.java

@@ -10,13 +10,11 @@ package org.elasticsearch.common.time;
 
 import org.elasticsearch.common.logging.DeprecationCategory;
 import org.elasticsearch.common.logging.DeprecationLogger;
-import org.joda.time.DateTimeZone;
 
 import java.time.Clock;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.ZoneId;
-import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.Collections;
 import java.util.HashMap;
@@ -33,17 +31,6 @@ public class DateUtils {
     public static  final long MAX_MILLIS_BEFORE_9999 = 253402300799999L; // end of year 9999
     public static  final long MAX_MILLIS_BEFORE_MINUS_9999 = -377705116800000L; // beginning of year -9999
 
-    public static DateTimeZone zoneIdToDateTimeZone(ZoneId zoneId) {
-        if (zoneId == null) {
-            return null;
-        }
-        if (zoneId instanceof ZoneOffset) {
-            // the id for zoneoffset is not ISO compatible, so cannot be read by ZoneId.of
-            return DateTimeZone.forOffsetMillis(((ZoneOffset)zoneId).getTotalSeconds() * 1000);
-        }
-        return DateTimeZone.forID(zoneId.getId());
-    }
-
     private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(DateUtils.class);
     // pkg private for tests
     static final Map<String, String> DEPRECATED_SHORT_TIMEZONES;
@@ -176,17 +163,6 @@ public class DateUtils {
             entry("W-SU", "Europe/Moscow"),
             entry("Zulu", "Etc/UTC"));
 
-    public static ZoneId dateTimeZoneToZoneId(DateTimeZone timeZone) {
-        if (timeZone == null) {
-            return null;
-        }
-        if (DateTimeZone.UTC.equals(timeZone)) {
-            return ZoneOffset.UTC;
-        }
-
-        return of(timeZone.getID());
-    }
-
     public static ZoneId of(String zoneId) {
         String deprecatedId = DEPRECATED_SHORT_TIMEZONES.get(zoneId);
         if (deprecatedId != null) {

+ 0 - 7
server/src/main/java/org/elasticsearch/search/aggregations/support/values/ScriptDoubleValues.java

@@ -12,7 +12,6 @@ import org.elasticsearch.common.lucene.ScorerAware;
 import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
 import org.elasticsearch.script.AggregationScript;
 import org.elasticsearch.search.aggregations.AggregationExecutionException;
-import org.joda.time.ReadableInstant;
 
 import java.io.IOException;
 import java.lang.reflect.Array;
@@ -41,9 +40,6 @@ public class ScriptDoubleValues extends SortingNumericDoubleValues implements Sc
         } else if (value instanceof Number) {
             resize(1);
             values[0] = ((Number) value).doubleValue();
-        } else if (value instanceof ReadableInstant) {
-            resize(1);
-            values[0] = ((ReadableInstant) value).getMillis();
         } else if (value instanceof ZonedDateTime) {
             resize(1);
             values[0] = ((ZonedDateTime) value).toInstant().toEpochMilli();
@@ -79,9 +75,6 @@ public class ScriptDoubleValues extends SortingNumericDoubleValues implements Sc
     private static double toDoubleValue(Object o) {
         if (o instanceof Number) {
             return ((Number) o).doubleValue();
-        } else if (o instanceof ReadableInstant) {
-            // Dates are exposed in scripts as ReadableDateTimes but aggregations want them to be numeric
-            return ((ReadableInstant) o).getMillis();
         } else if (o instanceof ZonedDateTime) {
             return ((ZonedDateTime) o).toInstant().toEpochMilli();
         } else if (o instanceof Boolean) {

+ 0 - 4
server/src/main/java/org/elasticsearch/search/aggregations/support/values/ScriptLongValues.java

@@ -13,7 +13,6 @@ import org.elasticsearch.common.lucene.ScorerAware;
 import org.elasticsearch.index.fielddata.AbstractSortingNumericDocValues;
 import org.elasticsearch.script.AggregationScript;
 import org.elasticsearch.search.aggregations.AggregationExecutionException;
-import org.joda.time.ReadableInstant;
 
 import java.io.IOException;
 import java.lang.reflect.Array;
@@ -78,9 +77,6 @@ public class ScriptLongValues extends AbstractSortingNumericDocValues implements
     private static long toLongValue(Object o) {
         if (o instanceof Number) {
             return ((Number) o).longValue();
-        } else if (o instanceof ReadableInstant) {
-            // Dates are exposed in scripts as ReadableDateTimes but aggregations want them to be numeric
-            return ((ReadableInstant) o).getMillis();
         } else if (o instanceof ZonedDateTime) {
             return ((ZonedDateTime) o).toInstant().toEpochMilli();
         } else if (o instanceof Boolean) {

+ 0 - 2037
server/src/main/java/org/joda/time/format/StrictISODateTimeFormat.java

@@ -1,2037 +0,0 @@
-package org.joda.time.format;
-
-/* @notice
- *  Copyright 2001-2009 Stephen Colebourne
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-import org.joda.time.DateTimeFieldType;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-/*
- * Elasticsearch Note: This class has been copied almost identically from joda, where the
- * class is named ISODatetimeFormat
- *
- * However there has been done one huge modification in several methods, which forces the date
- * year to be exactly n digits, so that a year like "5" is invalid and must be "0005"
- *
- * All methods have been marked with an "// ES change" commentary
- *
- * In case you compare this with the original ISODateTimeFormat, make sure you use a diff
- * call, that ignores whitespaces/tabs/indentations like 'diff -b'
- */
-
-/**
- * Factory that creates instances of DateTimeFormatter based on the ISO8601 standard.
- * <p>
- * Date-time formatting is performed by the {@link DateTimeFormatter} class.
- * Three classes provide factory methods to create formatters, and this is one.
- * The others are {@link DateTimeFormat} and {@link DateTimeFormatterBuilder}.
- * <p>
- * ISO8601 is the international standard for data interchange. It defines a
- * framework, rather than an absolute standard. As a result this provider has a
- * number of methods that represent common uses of the framework. The most common
- * formats are {@link #date() date}, {@link #time() time}, and {@link #dateTime() dateTime}.
- * <p>
- * For example, to format a date time in ISO format:
- * <pre>
- * DateTime dt = new DateTime();
- * DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
- * String str = fmt.print(dt);
- * </pre>
- * <p>
- * Note that these formatters mostly follow the ISO8601 standard for printing.
- * For parsing, the formatters are more lenient and allow formats that are not
- * in strict compliance with the standard.
- * <p>
- * It is important to understand that these formatters are not linked to
- * the <code>ISOChronology</code>. These formatters may be used with any
- * chronology, however there may be certain side effects with more unusual
- * chronologies. For example, the ISO formatters rely on dayOfWeek being
- * single digit, dayOfMonth being two digit and dayOfYear being three digit.
- * A chronology with a ten day week would thus cause issues. However, in
- * general, it is safe to use these formatters with other chronologies.
- * <p>
- * ISODateTimeFormat is thread-safe and immutable, and the formatters it
- * returns are as well.
- *
- * @author Brian S O'Neill
- * @since 1.0
- * @see DateTimeFormat
- * @see DateTimeFormatterBuilder
- */
-public class StrictISODateTimeFormat {
-
-    /**
-     * Constructor.
-     *
-     * @since 1.1 (previously private)
-     */
-    protected StrictISODateTimeFormat() {
-        super();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a formatter that outputs only those fields specified.
-     * <p>
-     * This method examines the fields provided and returns an ISO-style
-     * formatter that best fits. This can be useful for outputting
-     * less-common ISO styles, such as YearMonth (YYYY-MM) or MonthDay (--MM-DD).
-     * <p>
-     * The list provided may have overlapping fields, such as dayOfWeek and
-     * dayOfMonth. In this case, the style is chosen based on the following
-     * list, thus in the example, the calendar style is chosen as dayOfMonth
-     * is higher in priority than dayOfWeek:
-     * <ul>
-     * <li>monthOfYear - calendar date style
-     * <li>dayOfYear - ordinal date style
-     * <li>weekOfWeekYear - week date style
-     * <li>dayOfMonth - calendar date style
-     * <li>dayOfWeek - week date style
-     * <li>year
-     * <li>weekyear
-     * </ul>
-     * The supported formats are:
-     * <pre>
-     * Extended      Basic       Fields
-     * 2005-03-25    20050325    year/monthOfYear/dayOfMonth
-     * 2005-03       2005-03     year/monthOfYear
-     * 2005--25      2005--25    year/dayOfMonth *
-     * 2005          2005        year
-     * --03-25       --0325      monthOfYear/dayOfMonth
-     * --03          --03        monthOfYear
-     * ---03         ---03       dayOfMonth
-     * 2005-084      2005084     year/dayOfYear
-     * -084          -084        dayOfYear
-     * 2005-W12-5    2005W125    weekyear/weekOfWeekyear/dayOfWeek
-     * 2005-W-5      2005W-5     weekyear/dayOfWeek *
-     * 2005-W12      2005W12     weekyear/weekOfWeekyear
-     * -W12-5        -W125       weekOfWeekyear/dayOfWeek
-     * -W12          -W12        weekOfWeekyear
-     * -W-5          -W-5        dayOfWeek
-     * 10:20:30.040  102030.040  hour/minute/second/milli
-     * 10:20:30      102030      hour/minute/second
-     * 10:20         1020        hour/minute
-     * 10            10          hour
-     * -20:30.040    -2030.040   minute/second/milli
-     * -20:30        -2030       minute/second
-     * -20           -20         minute
-     * --30.040      --30.040    second/milli
-     * --30          --30        second
-     * ---.040       ---.040     milli *
-     * 10-30.040     10-30.040   hour/second/milli *
-     * 10:20-.040    1020-.040   hour/minute/milli *
-     * 10-30         10-30       hour/second *
-     * 10--.040      10--.040    hour/milli *
-     * -20-.040      -20-.040    minute/milli *
-     *   plus datetime formats like {date}T{time}
-     * </pre>
-     * * indicates that this is not an official ISO format and can be excluded
-     * by passing in <code>strictISO</code> as <code>true</code>.
-     * <p>
-     * This method can side effect the input collection of fields.
-     * If the input collection is modifiable, then each field that was added to
-     * the formatter will be removed from the collection, including any duplicates.
-     * If the input collection is unmodifiable then no side effect occurs.
-     * <p>
-     * This side effect processing is useful if you need to know whether all
-     * the fields were converted into the formatter or not. To achieve this,
-     * pass in a modifiable list, and check that it is empty on exit.
-     *
-     * @param fields  the fields to get a formatter for, not null,
-     *  updated by the method call unless unmodifiable,
-     *  removing those fields built in the formatter
-     * @param extended  true to use the extended format (with separators)
-     * @param strictISO  true to stick exactly to ISO8601, false to include additional formats
-     * @return a suitable formatter
-     * @throws IllegalArgumentException if there is no format for the fields
-     * @since 1.1
-     */
-    public static DateTimeFormatter forFields(
-            Collection<DateTimeFieldType> fields,
-            boolean extended,
-            boolean strictISO) {
-
-        if (fields == null || fields.size() == 0) {
-            throw new IllegalArgumentException("The fields must not be null or empty");
-        }
-        Set<DateTimeFieldType> workingFields = new HashSet<>(fields);
-        int inputSize = workingFields.size();
-        boolean reducedPrec = false;
-        DateTimeFormatterBuilder bld = new DateTimeFormatterBuilder();
-        // date
-        if (workingFields.contains(DateTimeFieldType.monthOfYear())) {
-            reducedPrec = dateByMonth(bld, workingFields, extended, strictISO);
-        } else if (workingFields.contains(DateTimeFieldType.dayOfYear())) {
-            reducedPrec = dateByOrdinal(bld, workingFields, extended);
-        } else if (workingFields.contains(DateTimeFieldType.weekOfWeekyear())) {
-            reducedPrec = dateByWeek(bld, workingFields, extended, strictISO);
-        } else if (workingFields.contains(DateTimeFieldType.dayOfMonth())) {
-            reducedPrec = dateByMonth(bld, workingFields, extended, strictISO);
-        } else if (workingFields.contains(DateTimeFieldType.dayOfWeek())) {
-            reducedPrec = dateByWeek(bld, workingFields, extended, strictISO);
-        } else if (workingFields.remove(DateTimeFieldType.year())) {
-            bld.append(Constants.ye);
-            reducedPrec = true;
-        } else if (workingFields.remove(DateTimeFieldType.weekyear())) {
-            bld.append(Constants.we);
-            reducedPrec = true;
-        }
-        boolean datePresent = (workingFields.size() < inputSize);
-
-        // time
-        time(bld, workingFields, extended, strictISO, reducedPrec, datePresent);
-
-        // result
-        if (bld.canBuildFormatter() == false) {
-            throw new IllegalArgumentException("No valid format for fields: " + fields);
-        }
-
-        // side effect the input collection to indicate the processed fields
-        // handling unmodifiable collections with no side effect
-        try {
-            fields.retainAll(workingFields);
-        } catch (UnsupportedOperationException ex) {
-            // ignore, so we can handle unmodifiable collections
-        }
-        return bld.toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates a date using the calendar date format.
-     * Specification reference: 5.2.1.
-     *
-     * @param bld  the builder
-     * @param fields  the fields
-     * @param extended  true to use extended format
-     * @param strictISO  true to only allow ISO formats
-     * @return true if reduced precision
-     * @since 1.1
-     */
-    private static boolean dateByMonth(
-            DateTimeFormatterBuilder bld,
-            Collection<DateTimeFieldType> fields,
-            boolean extended,
-            boolean strictISO) {
-
-        boolean reducedPrec = false;
-        if (fields.remove(DateTimeFieldType.year())) {
-            bld.append(Constants.ye);
-            if (fields.remove(DateTimeFieldType.monthOfYear())) {
-                if (fields.remove(DateTimeFieldType.dayOfMonth())) {
-                    // YYYY-MM-DD/YYYYMMDD
-                    appendSeparator(bld, extended);
-                    bld.appendMonthOfYear(2);
-                    appendSeparator(bld, extended);
-                    bld.appendDayOfMonth(2);
-                } else {
-                    // YYYY-MM/YYYY-MM
-                    bld.appendLiteral('-');
-                    bld.appendMonthOfYear(2);
-                    reducedPrec = true;
-                }
-            } else {
-                if (fields.remove(DateTimeFieldType.dayOfMonth())) {
-                    // YYYY--DD/YYYY--DD (non-iso)
-                    checkNotStrictISO(fields, strictISO);
-                    bld.appendLiteral('-');
-                    bld.appendLiteral('-');
-                    bld.appendDayOfMonth(2);
-                } else {
-                    // YYYY/YYYY
-                    reducedPrec = true;
-                }
-            }
-
-        } else if (fields.remove(DateTimeFieldType.monthOfYear())) {
-            bld.appendLiteral('-');
-            bld.appendLiteral('-');
-            bld.appendMonthOfYear(2);
-            if (fields.remove(DateTimeFieldType.dayOfMonth())) {
-                // --MM-DD/--MMDD
-                appendSeparator(bld, extended);
-                bld.appendDayOfMonth(2);
-            } else {
-                // --MM/--MM
-                reducedPrec = true;
-            }
-        } else if (fields.remove(DateTimeFieldType.dayOfMonth())) {
-            // ---DD/---DD
-            bld.appendLiteral('-');
-            bld.appendLiteral('-');
-            bld.appendLiteral('-');
-            bld.appendDayOfMonth(2);
-        }
-        return reducedPrec;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates a date using the ordinal date format.
-     * Specification reference: 5.2.2.
-     *
-     * @param bld  the builder
-     * @param fields  the fields
-     * @param extended  true to use extended format
-     * @since 1.1
-     */
-    private static boolean dateByOrdinal(
-            DateTimeFormatterBuilder bld,
-            Collection<DateTimeFieldType> fields,
-            boolean extended) {
-
-        boolean reducedPrec = false;
-        if (fields.remove(DateTimeFieldType.year())) {
-            bld.append(Constants.ye);
-            if (fields.remove(DateTimeFieldType.dayOfYear())) {
-                // YYYY-DDD/YYYYDDD
-                appendSeparator(bld, extended);
-                bld.appendDayOfYear(3);
-            } else {
-                // YYYY/YYYY
-                reducedPrec = true;
-            }
-
-        } else if (fields.remove(DateTimeFieldType.dayOfYear())) {
-            // -DDD/-DDD
-            bld.appendLiteral('-');
-            bld.appendDayOfYear(3);
-        }
-        return reducedPrec;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates a date using the calendar date format.
-     * Specification reference: 5.2.3.
-     *
-     * @param bld  the builder
-     * @param fields  the fields
-     * @param extended  true to use extended format
-     * @param strictISO  true to only allow ISO formats
-     * @since 1.1
-     */
-    private static boolean dateByWeek(
-            DateTimeFormatterBuilder bld,
-            Collection<DateTimeFieldType> fields,
-            boolean extended,
-            boolean strictISO) {
-
-        boolean reducedPrec = false;
-        if (fields.remove(DateTimeFieldType.weekyear())) {
-            bld.append(Constants.we);
-            if (fields.remove(DateTimeFieldType.weekOfWeekyear())) {
-                appendSeparator(bld, extended);
-                bld.appendLiteral('W');
-                bld.appendWeekOfWeekyear(2);
-                if (fields.remove(DateTimeFieldType.dayOfWeek())) {
-                    // YYYY-WWW-D/YYYYWWWD
-                    appendSeparator(bld, extended);
-                    bld.appendDayOfWeek(1);
-                } else {
-                    // YYYY-WWW/YYYY-WWW
-                    reducedPrec = true;
-                }
-            } else {
-                if (fields.remove(DateTimeFieldType.dayOfWeek())) {
-                    // YYYY-W-D/YYYYW-D (non-iso)
-                    checkNotStrictISO(fields, strictISO);
-                    appendSeparator(bld, extended);
-                    bld.appendLiteral('W');
-                    bld.appendLiteral('-');
-                    bld.appendDayOfWeek(1);
-                } else {
-                    // YYYY/YYYY
-                    reducedPrec = true;
-                }
-            }
-
-        } else if (fields.remove(DateTimeFieldType.weekOfWeekyear())) {
-            bld.appendLiteral('-');
-            bld.appendLiteral('W');
-            bld.appendWeekOfWeekyear(2);
-            if (fields.remove(DateTimeFieldType.dayOfWeek())) {
-                // -WWW-D/-WWWD
-                appendSeparator(bld, extended);
-                bld.appendDayOfWeek(1);
-            } else {
-                // -WWW/-WWW
-                reducedPrec = true;
-            }
-        } else if (fields.remove(DateTimeFieldType.dayOfWeek())) {
-            // -W-D/-W-D
-            bld.appendLiteral('-');
-            bld.appendLiteral('W');
-            bld.appendLiteral('-');
-            bld.appendDayOfWeek(1);
-        }
-        return reducedPrec;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Adds the time fields to the builder.
-     * Specification reference: 5.3.1.
-     *
-     * @param bld  the builder
-     * @param fields  the fields
-     * @param extended  whether to use the extended format
-     * @param strictISO  whether to be strict
-     * @param reducedPrec  whether the date was reduced precision
-     * @param datePresent  whether there was a date
-     * @since 1.1
-     */
-    private static void time(
-            DateTimeFormatterBuilder bld,
-            Collection<DateTimeFieldType> fields,
-            boolean extended,
-            boolean strictISO,
-            boolean reducedPrec,
-            boolean datePresent) {
-
-        boolean hour = fields.remove(DateTimeFieldType.hourOfDay());
-        boolean minute = fields.remove(DateTimeFieldType.minuteOfHour());
-        boolean second = fields.remove(DateTimeFieldType.secondOfMinute());
-        boolean milli = fields.remove(DateTimeFieldType.millisOfSecond());
-        if (hour == false && minute == false && second == false && milli == false) {
-            return;
-        }
-        if (hour || minute || second || milli) {
-            if (strictISO && reducedPrec) {
-                throw new IllegalArgumentException("No valid ISO8601 format for fields because Date was reduced precision: " + fields);
-            }
-            if (datePresent) {
-                bld.appendLiteral('T');
-            }
-        }
-        if (hour && minute && second || (hour && second == false && milli == false)) {
-            // OK - HMSm/HMS/HM/H - valid in combination with date
-        } else {
-            if (strictISO && datePresent) {
-                throw new IllegalArgumentException("No valid ISO8601 format for fields because Time was truncated: " + fields);
-            }
-            if (hour == false && (minute && second || (minute && milli == false) || second)) {
-                // OK - MSm/MS/M/Sm/S - valid ISO formats
-            } else {
-                if (strictISO) {
-                    throw new IllegalArgumentException("No valid ISO8601 format for fields: " + fields);
-                }
-            }
-        }
-        if (hour) {
-            bld.appendHourOfDay(2);
-        } else if (minute || second || milli) {
-            bld.appendLiteral('-');
-        }
-        if (extended && hour && minute) {
-            bld.appendLiteral(':');
-        }
-        if (minute) {
-            bld.appendMinuteOfHour(2);
-        } else if (second || milli) {
-            bld.appendLiteral('-');
-        }
-        if (extended && minute && second) {
-            bld.appendLiteral(':');
-        }
-        if (second) {
-            bld.appendSecondOfMinute(2);
-        } else if (milli) {
-            bld.appendLiteral('-');
-        }
-        if (milli) {
-            bld.appendLiteral('.');
-            bld.appendMillisOfSecond(3);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks that the iso only flag is not set, throwing an exception if it is.
-     *
-     * @param fields  the fields
-     * @param strictISO  true if only ISO formats allowed
-     * @since 1.1
-     */
-    private static void checkNotStrictISO(Collection<DateTimeFieldType> fields, boolean strictISO) {
-        if (strictISO) {
-            throw new IllegalArgumentException("No valid ISO8601 format for fields: " + fields);
-        }
-    }
-
-    /**
-     * Appends the separator if necessary.
-     *
-     * @param bld  the builder
-     * @param extended  whether to append the separator
-     * @since 1.1
-     */
-    private static void appendSeparator(DateTimeFormatterBuilder bld, boolean extended) {
-        if (extended) {
-            bld.appendLiteral('-');
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a generic ISO date parser for parsing dates with a possible zone.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * date              = date-element ['T' offset]
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * offset            = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
-     * </pre>
-     */
-    public static DateTimeFormatter dateParser() {
-        return Constants.dp;
-    }
-
-    /**
-     * Returns a generic ISO date parser for parsing local dates.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * This parser is initialised with the local (UTC) time zone.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * </pre>
-     * @since 1.3
-     */
-    public static DateTimeFormatter localDateParser() {
-        return Constants.ldp;
-    }
-
-    /**
-     * Returns a generic ISO date parser for parsing dates.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * </pre>
-     */
-    public static DateTimeFormatter dateElementParser() {
-        return Constants.dpe;
-    }
-
-    /**
-     * Returns a generic ISO time parser for parsing times with a possible zone.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * time           = ['T'] time-element [offset]
-     * time-element   = HH [minute-element] | [fraction]
-     * minute-element = ':' mm [second-element] | [fraction]
-     * second-element = ':' ss [fraction]
-     * fraction       = ('.' | ',') digit+
-     * offset         = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
-     * </pre>
-     */
-    public static DateTimeFormatter timeParser() {
-        return Constants.tp;
-    }
-
-    /**
-     * Returns a generic ISO time parser for parsing local times.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * This parser is initialised with the local (UTC) time zone.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * time           = ['T'] time-element
-     * time-element   = HH [minute-element] | [fraction]
-     * minute-element = ':' mm [second-element] | [fraction]
-     * second-element = ':' ss [fraction]
-     * fraction       = ('.' | ',') digit+
-     * </pre>
-     * @since 1.3
-     */
-    public static DateTimeFormatter localTimeParser() {
-        return Constants.ltp;
-    }
-
-    /**
-     * Returns a generic ISO time parser.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * time-element   = HH [minute-element] | [fraction]
-     * minute-element = ':' mm [second-element] | [fraction]
-     * second-element = ':' ss [fraction]
-     * fraction       = ('.' | ',') digit+
-     * </pre>
-     */
-    public static DateTimeFormatter timeElementParser() {
-        return Constants.tpe;
-    }
-
-    /**
-     * Returns a generic ISO datetime parser which parses either a date or a time or both.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * datetime          = time | date-opt-time
-     * time              = 'T' time-element [offset]
-     * date-opt-time     = date-element ['T' [time-element] [offset]]
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * time-element      = HH [minute-element] | [fraction]
-     * minute-element    = ':' mm [second-element] | [fraction]
-     * second-element    = ':' ss [fraction]
-     * fraction          = ('.' | ',') digit+
-     * offset            = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
-     * </pre>
-     */
-    public static DateTimeFormatter dateTimeParser() {
-        return Constants.dtp;
-    }
-
-    /**
-     * Returns a generic ISO datetime parser where the date is mandatory and the time is optional.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * This parser can parse zoned datetimes.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * date-opt-time     = date-element ['T' [time-element] [offset]]
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * time-element      = HH [minute-element] | [fraction]
-     * minute-element    = ':' mm [second-element] | [fraction]
-     * second-element    = ':' ss [fraction]
-     * fraction          = ('.' | ',') digit+
-     * </pre>
-     * @since 1.3
-     */
-    public static DateTimeFormatter dateOptionalTimeParser() {
-        return Constants.dotp;
-    }
-
-    /**
-     * Returns a generic ISO datetime parser where the date is mandatory and the time is optional.
-     * <p>
-     * The returned formatter can only be used for parsing, printing is unsupported.
-     * <p>
-     * This parser only parses local datetimes.
-     * This parser is initialised with the local (UTC) time zone.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * It accepts formats described by the following syntax:
-     * <pre>
-     * datetime          = date-element ['T' time-element]
-     * date-element      = std-date-element | ord-date-element | week-date-element
-     * std-date-element  = yyyy ['-' MM ['-' dd]]
-     * ord-date-element  = yyyy ['-' DDD]
-     * week-date-element = xxxx '-W' ww ['-' e]
-     * time-element      = HH [minute-element] | [fraction]
-     * minute-element    = ':' mm [second-element] | [fraction]
-     * second-element    = ':' ss [fraction]
-     * fraction          = ('.' | ',') digit+
-     * </pre>
-     * @since 1.3
-     */
-    public static DateTimeFormatter localDateOptionalTimeParser() {
-        return Constants.ldotp;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a formatter for a full date as four digit year, two digit month
-     * of year, and two digit day of month (yyyy-MM-dd).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     * See {@link #dateParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-MM-dd
-     */
-    public static DateTimeFormatter date() {
-        return yearMonthDay();
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, three digit fraction of second, and
-     * time zone offset (HH:mm:ss.SSSZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     * See {@link #timeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for HH:mm:ss.SSSZZ
-     */
-    public static DateTimeFormatter time() {
-        return Constants.t;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, and time zone offset (HH:mm:ssZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     * See {@link #timeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for HH:mm:ssZZ
-     */
-    public static DateTimeFormatter timeNoMillis() {
-        return Constants.tx;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, three digit fraction of second, and
-     * time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     * See {@link #timeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for 'T'HH:mm:ss.SSSZZ
-     */
-    public static DateTimeFormatter tTime() {
-        return Constants.tt;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, and time zone offset prefixed
-     * by 'T' ('T'HH:mm:ssZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     * See {@link #timeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for 'T'HH:mm:ssZZ
-     */
-    public static DateTimeFormatter tTimeNoMillis() {
-        return Constants.ttx;
-    }
-
-    /**
-     * Returns a formatter that combines a full date and time, separated by a 'T'
-     * (yyyy-MM-dd'T'HH:mm:ss.SSSZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSSZZ
-     */
-    public static DateTimeFormatter dateTime() {
-        return Constants.dt;
-    }
-
-    /**
-     * Returns a formatter that combines a full date and time without millis,
-     * separated by a 'T' (yyyy-MM-dd'T'HH:mm:ssZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm:ssZZ
-     */
-    public static DateTimeFormatter dateTimeNoMillis() {
-        return Constants.dtx;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date, using a four
-     * digit year and three digit dayOfYear (yyyy-DDD).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     * See {@link #dateParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-DDD
-     * @since 1.1
-     */
-    public static DateTimeFormatter ordinalDate() {
-        return Constants.od;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date and time, using a four
-     * digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ss.SSSZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-DDD'T'HH:mm:ss.SSSZZ
-     * @since 1.1
-     */
-    public static DateTimeFormatter ordinalDateTime() {
-        return Constants.odt;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date and time without millis,
-     * using a four digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ssZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for yyyy-DDD'T'HH:mm:ssZZ
-     * @since 1.1
-     */
-    public static DateTimeFormatter ordinalDateTimeNoMillis() {
-        return Constants.odtx;
-    }
-
-    /**
-     * Returns a formatter for a full date as four digit weekyear, two digit
-     * week of weekyear, and one digit day of week (xxxx-'W'ww-e).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     * See {@link #dateParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for xxxx-'W'ww-e
-     */
-    public static DateTimeFormatter weekDate() {
-        return Constants.wwd;
-    }
-
-    /**
-     * Returns a formatter that combines a full weekyear date and time,
-     * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ
-     */
-    public static DateTimeFormatter weekDateTime() {
-        return Constants.wdt;
-    }
-
-    /**
-     * Returns a formatter that combines a full weekyear date and time without millis,
-     * separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ssZZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     * See {@link #dateTimeParser()} for a more flexible parser that accepts different formats.
-     *
-     * @return a formatter for xxxx-'W'ww-e'T'HH:mm:ssZZ
-     */
-    public static DateTimeFormatter weekDateTimeNoMillis() {
-        return Constants.wdtx;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a basic formatter for a full date as four digit year, two digit
-     * month of year, and two digit day of month (yyyyMMdd).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     *
-     * @return a formatter for yyyyMMdd
-     */
-    public static DateTimeFormatter basicDate() {
-        return Constants.bd;
-    }
-
-    /**
-     * Returns a basic formatter for a two digit hour of day, two digit minute
-     * of hour, two digit second of minute, three digit millis, and time zone
-     * offset (HHmmss.SSSZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     *
-     * @return a formatter for HHmmss.SSSZ
-     */
-    public static DateTimeFormatter basicTime() {
-        return Constants.bt;
-    }
-
-    /**
-     * Returns a basic formatter for a two digit hour of day, two digit minute
-     * of hour, two digit second of minute, and time zone offset (HHmmssZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     *
-     * @return a formatter for HHmmssZ
-     */
-    public static DateTimeFormatter basicTimeNoMillis() {
-        return Constants.btx;
-    }
-
-    /**
-     * Returns a basic formatter for a two digit hour of day, two digit minute
-     * of hour, two digit second of minute, three digit millis, and time zone
-     * offset prefixed by 'T' ('T'HHmmss.SSSZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     *
-     * @return a formatter for 'T'HHmmss.SSSZ
-     */
-    public static DateTimeFormatter basicTTime() {
-        return Constants.btt;
-    }
-
-    /**
-     * Returns a basic formatter for a two digit hour of day, two digit minute
-     * of hour, two digit second of minute, and time zone offset prefixed by 'T'
-     * ('T'HHmmssZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     *
-     * @return a formatter for 'T'HHmmssZ
-     */
-    public static DateTimeFormatter basicTTimeNoMillis() {
-        return Constants.bttx;
-    }
-
-    /**
-     * Returns a basic formatter that combines a basic date and time, separated
-     * by a 'T' (yyyyMMdd'T'HHmmss.SSSZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     *
-     * @return a formatter for yyyyMMdd'T'HHmmss.SSSZ
-     */
-    public static DateTimeFormatter basicDateTime() {
-        return Constants.bdt;
-    }
-
-    /**
-     * Returns a basic formatter that combines a basic date and time without millis,
-     * separated by a 'T' (yyyyMMdd'T'HHmmssZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     *
-     * @return a formatter for yyyyMMdd'T'HHmmssZ
-     */
-    public static DateTimeFormatter basicDateTimeNoMillis() {
-        return Constants.bdtx;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date, using a four
-     * digit year and three digit dayOfYear (yyyyDDD).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     *
-     * @return a formatter for yyyyDDD
-     * @since 1.1
-     */
-    public static DateTimeFormatter basicOrdinalDate() {
-        return Constants.bod;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date and time, using a four
-     * digit year and three digit dayOfYear (yyyyDDD'T'HHmmss.SSSZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     *
-     * @return a formatter for yyyyDDD'T'HHmmss.SSSZ
-     * @since 1.1
-     */
-    public static DateTimeFormatter basicOrdinalDateTime() {
-        return Constants.bodt;
-    }
-
-    /**
-     * Returns a formatter for a full ordinal date and time without millis,
-     * using a four digit year and three digit dayOfYear (yyyyDDD'T'HHmmssZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     *
-     * @return a formatter for yyyyDDD'T'HHmmssZ
-     * @since 1.1
-     */
-    public static DateTimeFormatter basicOrdinalDateTimeNoMillis() {
-        return Constants.bodtx;
-    }
-
-    /**
-     * Returns a basic formatter for a full date as four digit weekyear, two
-     * digit week of weekyear, and one digit day of week (xxxx'W'wwe).
-     * <p>
-     * The returned formatter prints and parses only this format.
-     *
-     * @return a formatter for xxxx'W'wwe
-     */
-    public static DateTimeFormatter basicWeekDate() {
-        return Constants.bwd;
-    }
-
-    /**
-     * Returns a basic formatter that combines a basic weekyear date and time,
-     * separated by a 'T' (xxxx'W'wwe'T'HHmmss.SSSZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which includes milliseconds.
-     *
-     * @return a formatter for xxxx'W'wwe'T'HHmmss.SSSZ
-     */
-    public static DateTimeFormatter basicWeekDateTime() {
-        return Constants.bwdt;
-    }
-
-    /**
-     * Returns a basic formatter that combines a basic weekyear date and time
-     * without millis, separated by a 'T' (xxxx'W'wwe'T'HHmmssZ).
-     * <p>
-     * The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
-     * The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
-     * <p>
-     * The returned formatter prints and parses only this format, which excludes milliseconds.
-     *
-     * @return a formatter for xxxx'W'wwe'T'HHmmssZ
-     */
-    public static DateTimeFormatter basicWeekDateTimeNoMillis() {
-        return Constants.bwdtx;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a formatter for a four digit year. (yyyy)
-     *
-     * @return a formatter for yyyy
-     */
-    public static DateTimeFormatter year() {
-        return Constants.ye;
-    }
-
-    /**
-     * Returns a formatter for a four digit year and two digit month of
-     * year. (yyyy-MM)
-     *
-     * @return a formatter for yyyy-MM
-     */
-    public static DateTimeFormatter yearMonth() {
-        return Constants.ym;
-    }
-
-    /**
-     * Returns a formatter for a four digit year, two digit month of year, and
-     * two digit day of month. (yyyy-MM-dd)
-     *
-     * @return a formatter for yyyy-MM-dd
-     */
-    public static DateTimeFormatter yearMonthDay() {
-        return Constants.ymd;
-    }
-
-    /**
-     * Returns a formatter for a four digit weekyear. (xxxx)
-     *
-     * @return a formatter for xxxx
-     */
-    public static DateTimeFormatter weekyear() {
-        return Constants.we;
-    }
-
-    /**
-     * Returns a formatter for a four digit weekyear and two digit week of
-     * weekyear. (xxxx-'W'ww)
-     *
-     * @return a formatter for xxxx-'W'ww
-     */
-    public static DateTimeFormatter weekyearWeek() {
-        return Constants.ww;
-    }
-
-    /**
-     * Returns a formatter for a four digit weekyear, two digit week of
-     * weekyear, and one digit day of week. (xxxx-'W'ww-e)
-     *
-     * @return a formatter for xxxx-'W'ww-e
-     */
-    public static DateTimeFormatter weekyearWeekDay() {
-        return Constants.wwd;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day. (HH)
-     *
-     * @return a formatter for HH
-     */
-    public static DateTimeFormatter hour() {
-        return Constants.hde;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day and two digit minute of
-     * hour. (HH:mm)
-     *
-     * @return a formatter for HH:mm
-     */
-    public static DateTimeFormatter hourMinute() {
-        return Constants.hm;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, and two digit second of minute. (HH:mm:ss)
-     *
-     * @return a formatter for HH:mm:ss
-     */
-    public static DateTimeFormatter hourMinuteSecond() {
-        return Constants.hms;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, and three digit fraction of
-     * second (HH:mm:ss.SSS). Parsing will parse up to 3 fractional second
-     * digits.
-     *
-     * @return a formatter for HH:mm:ss.SSS
-     */
-    public static DateTimeFormatter hourMinuteSecondMillis() {
-        return Constants.hmsl;
-    }
-
-    /**
-     * Returns a formatter for a two digit hour of day, two digit minute of
-     * hour, two digit second of minute, and three digit fraction of
-     * second (HH:mm:ss.SSS). Parsing will parse up to 9 fractional second
-     * digits, throwing away all except the first three.
-     *
-     * @return a formatter for HH:mm:ss.SSS
-     */
-    public static DateTimeFormatter hourMinuteSecondFraction() {
-        return Constants.hmsf;
-    }
-
-    /**
-     * Returns a formatter that combines a full date and two digit hour of
-     * day. (yyyy-MM-dd'T'HH)
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH
-     */
-    public static DateTimeFormatter dateHour() {
-        return Constants.dh;
-    }
-
-    /**
-     * Returns a formatter that combines a full date, two digit hour of day,
-     * and two digit minute of hour. (yyyy-MM-dd'T'HH:mm)
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm
-     */
-    public static DateTimeFormatter dateHourMinute() {
-        return Constants.dhm;
-    }
-
-    /**
-     * Returns a formatter that combines a full date, two digit hour of day,
-     * two digit minute of hour, and two digit second of
-     * minute. (yyyy-MM-dd'T'HH:mm:ss)
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm:ss
-     */
-    public static DateTimeFormatter dateHourMinuteSecond() {
-        return Constants.dhms;
-    }
-
-    /**
-     * Returns a formatter that combines a full date, two digit hour of day,
-     * two digit minute of hour, two digit second of minute, and three digit
-     * fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS). Parsing will parse up
-     * to 3 fractional second digits.
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSS
-     */
-    public static DateTimeFormatter dateHourMinuteSecondMillis() {
-        return Constants.dhmsl;
-    }
-
-    /**
-     * Returns a formatter that combines a full date, two digit hour of day,
-     * two digit minute of hour, two digit second of minute, and three digit
-     * fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS). Parsing will parse up
-     * to 9 fractional second digits, throwing away all except the first three.
-     *
-     * @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSS
-     */
-    public static DateTimeFormatter dateHourMinuteSecondFraction() {
-        return Constants.dhmsf;
-    }
-
-    //-----------------------------------------------------------------------
-    static final class Constants {
-        private static final DateTimeFormatter
-                ye = yearElement(),  // year element (yyyy)
-                mye = monthElement(), // monthOfYear element (-MM)
-                dme = dayOfMonthElement(), // dayOfMonth element (-dd)
-                we = weekyearElement(),  // weekyear element (xxxx)
-                wwe = weekElement(), // weekOfWeekyear element (-ww)
-                dwe = dayOfWeekElement(), // dayOfWeek element (-ee)
-                dye = dayOfYearElement(), // dayOfYear element (-DDD)
-                hde = hourElement(), // hourOfDay element (HH)
-                mhe = minuteElement(), // minuteOfHour element (:mm)
-                sme = secondElement(), // secondOfMinute element (:ss)
-                fse = fractionElement(), // fractionOfSecond element (.SSSSSSSSS)
-                ze = offsetElement(),  // zone offset element
-                lte = literalTElement(), // literal 'T' element
-
-        //y,   // year (same as year element)
-        ym = yearMonth(),  // year month
-                ymd = yearMonthDay(), // year month day
-
-        //w,   // weekyear (same as weekyear element)
-        ww = weekyearWeek(),  // weekyear week
-                wwd = weekyearWeekDay(), // weekyear week day
-
-        //h,    // hour (same as hour element)
-        hm = hourMinute(),   // hour minute
-                hms = hourMinuteSecond(),  // hour minute second
-                hmsl = hourMinuteSecondMillis(), // hour minute second millis
-                hmsf = hourMinuteSecondFraction(), // hour minute second fraction
-
-        dh = dateHour(),    // date hour
-                dhm = dateHourMinute(),   // date hour minute
-                dhms = dateHourMinuteSecond(),  // date hour minute second
-                dhmsl = dateHourMinuteSecondMillis(), // date hour minute second millis
-                dhmsf = dateHourMinuteSecondFraction(), // date hour minute second fraction
-
-        //d,  // date (same as ymd)
-        t = time(),  // time
-                tx = timeNoMillis(),  // time no millis
-                tt = tTime(),  // Ttime
-                ttx = tTimeNoMillis(),  // Ttime no millis
-                dt = dateTime(), // date time
-                dtx = dateTimeNoMillis(), // date time no millis
-
-        //wd,  // week date (same as wwd)
-        wdt = weekDateTime(), // week date time
-                wdtx = weekDateTimeNoMillis(), // week date time no millis
-
-        od = ordinalDate(),  // ordinal date (same as yd)
-                odt = ordinalDateTime(), // ordinal date time
-                odtx = ordinalDateTimeNoMillis(), // ordinal date time no millis
-
-        bd = basicDate(),  // basic date
-                bt = basicTime(),  // basic time
-                btx = basicTimeNoMillis(),  // basic time no millis
-                btt = basicTTime(), // basic Ttime
-                bttx = basicTTimeNoMillis(), // basic Ttime no millis
-                bdt = basicDateTime(), // basic date time
-                bdtx = basicDateTimeNoMillis(), // basic date time no millis
-
-        bod = basicOrdinalDate(),  // basic ordinal date
-                bodt = basicOrdinalDateTime(), // basic ordinal date time
-                bodtx = basicOrdinalDateTimeNoMillis(), // basic ordinal date time no millis
-
-        bwd = basicWeekDate(),  // basic week date
-                bwdt = basicWeekDateTime(), // basic week date time
-                bwdtx = basicWeekDateTimeNoMillis(), // basic week date time no millis
-
-        dpe = dateElementParser(), // date parser element
-                tpe = timeElementParser(), // time parser element
-                dp = dateParser(),  // date parser
-                ldp = localDateParser(), // local date parser
-                tp = timeParser(),  // time parser
-                ltp = localTimeParser(), // local time parser
-                dtp = dateTimeParser(), // date time parser
-                dotp = dateOptionalTimeParser(), // date optional time parser
-                ldotp = localDateOptionalTimeParser(); // local date optional time parser
-
-        //-----------------------------------------------------------------------
-        private static DateTimeFormatter dateParser() {
-            if (dp == null) {
-                DateTimeParser tOffset = new DateTimeFormatterBuilder()
-                        .appendLiteral('T')
-                        .append(offsetElement()).toParser();
-                return new DateTimeFormatterBuilder()
-                        .append(dateElementParser())
-                        .appendOptional(tOffset)
-                        .toFormatter();
-            }
-            return dp;
-        }
-
-        private static DateTimeFormatter localDateParser() {
-            if (ldp == null) {
-                return dateElementParser().withZoneUTC();
-            }
-            return ldp;
-        }
-
-        private static DateTimeFormatter dateElementParser() {
-            if (dpe == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(null, new DateTimeParser[] {
-                                new DateTimeFormatterBuilder()
-                                        .append(yearElement())
-                                        .appendOptional
-                                                (new DateTimeFormatterBuilder()
-                                                        .append(monthElement())
-                                                        .appendOptional(dayOfMonthElement().getParser())
-                                                        .toParser())
-                                        .toParser(),
-                                new DateTimeFormatterBuilder()
-                                        .append(weekyearElement())
-                                        .append(weekElement())
-                                        .appendOptional(dayOfWeekElement().getParser())
-                                        .toParser(),
-                                new DateTimeFormatterBuilder()
-                                        .append(yearElement())
-                                        .append(dayOfYearElement())
-                                        .toParser()
-                        })
-                        .toFormatter();
-            }
-            return dpe;
-        }
-
-        private static DateTimeFormatter timeParser() {
-            if (tp == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendOptional(literalTElement().getParser())
-                        .append(timeElementParser())
-                        .appendOptional(offsetElement().getParser())
-                        .toFormatter();
-            }
-            return tp;
-        }
-
-        private static DateTimeFormatter localTimeParser() {
-            if (ltp == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendOptional(literalTElement().getParser())
-                        .append(timeElementParser())
-                        .toFormatter().withZoneUTC();
-            }
-            return ltp;
-        }
-
-        private static DateTimeFormatter timeElementParser() {
-            if (tpe == null) {
-                // Decimal point can be either '.' or ','
-                DateTimeParser decimalPoint = new DateTimeFormatterBuilder()
-                        .append(null, new DateTimeParser[] {
-                                new DateTimeFormatterBuilder()
-                                        .appendLiteral('.')
-                                        .toParser(),
-                                new DateTimeFormatterBuilder()
-                                        .appendLiteral(',')
-                                        .toParser()
-                        })
-                        .toParser();
-
-                return new DateTimeFormatterBuilder()
-                        // time-element
-                        .append(hourElement())
-                        .append
-                                (null, new DateTimeParser[] {
-                                        new DateTimeFormatterBuilder()
-                                                // minute-element
-                                                .append(minuteElement())
-                                                .append
-                                                        (null, new DateTimeParser[] {
-                                                                new DateTimeFormatterBuilder()
-                                                                        // second-element
-                                                                        .append(secondElement())
-                                                                                // second fraction
-                                                                        .appendOptional(new DateTimeFormatterBuilder()
-                                                                                .append(decimalPoint)
-                                                                                .appendFractionOfSecond(1, 9)
-                                                                                .toParser())
-                                                                        .toParser(),
-                                                                // minute fraction
-                                                                new DateTimeFormatterBuilder()
-                                                                        .append(decimalPoint)
-                                                                        .appendFractionOfMinute(1, 9)
-                                                                        .toParser(),
-                                                                null
-                                                        })
-                                                .toParser(),
-                                        // hour fraction
-                                        new DateTimeFormatterBuilder()
-                                                .append(decimalPoint)
-                                                .appendFractionOfHour(1, 9)
-                                                .toParser(),
-                                        null
-                                })
-                        .toFormatter();
-            }
-            return tpe;
-        }
-
-        private static DateTimeFormatter dateTimeParser() {
-            if (dtp == null) {
-                // This is different from the general time parser in that the 'T'
-                // is required.
-                DateTimeParser time = new DateTimeFormatterBuilder()
-                        .appendLiteral('T')
-                        .append(timeElementParser())
-                        .appendOptional(offsetElement().getParser())
-                        .toParser();
-                return new DateTimeFormatterBuilder()
-                        .append(null, new DateTimeParser[] {time, dateOptionalTimeParser().getParser()})
-                        .toFormatter();
-            }
-            return dtp;
-        }
-
-        private static DateTimeFormatter dateOptionalTimeParser() {
-            if (dotp == null) {
-                DateTimeParser timeOrOffset = new DateTimeFormatterBuilder()
-                        .appendLiteral('T')
-                        .appendOptional(timeElementParser().getParser())
-                        .appendOptional(offsetElement().getParser())
-                        .toParser();
-                return new DateTimeFormatterBuilder()
-                        .append(dateElementParser())
-                        .appendOptional(timeOrOffset)
-                        .toFormatter();
-            }
-            return dotp;
-        }
-
-        private static DateTimeFormatter localDateOptionalTimeParser() {
-            if (ldotp == null) {
-                DateTimeParser time = new DateTimeFormatterBuilder()
-                        .appendLiteral('T')
-                        .append(timeElementParser())
-                        .toParser();
-                return new DateTimeFormatterBuilder()
-                        .append(dateElementParser())
-                        .appendOptional(time)
-                        .toFormatter().withZoneUTC();
-            }
-            return ldotp;
-        }
-
-        //-----------------------------------------------------------------------
-        private static DateTimeFormatter time() {
-            if (t == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourMinuteSecondFraction())
-                        .append(offsetElement())
-                        .toFormatter();
-            }
-            return t;
-        }
-
-        private static DateTimeFormatter timeNoMillis() {
-            if (tx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourMinuteSecond())
-                        .append(offsetElement())
-                        .toFormatter();
-            }
-            return tx;
-        }
-
-        private static DateTimeFormatter tTime() {
-            if (tt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(literalTElement())
-                        .append(time())
-                        .toFormatter();
-            }
-            return tt;
-        }
-
-        private static DateTimeFormatter tTimeNoMillis() {
-            if (ttx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(literalTElement())
-                        .append(timeNoMillis())
-                        .toFormatter();
-            }
-            return ttx;
-        }
-
-        private static DateTimeFormatter dateTime() {
-            if (dt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(tTime())
-                        .toFormatter();
-            }
-            return dt;
-        }
-
-        private static DateTimeFormatter dateTimeNoMillis() {
-            if (dtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(tTimeNoMillis())
-                        .toFormatter();
-            }
-            return dtx;
-        }
-
-        private static DateTimeFormatter ordinalDate() {
-            if (od == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(yearElement())
-                        .append(dayOfYearElement())
-                        .toFormatter();
-            }
-            return od;
-        }
-
-        private static DateTimeFormatter ordinalDateTime() {
-            if (odt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(ordinalDate())
-                        .append(tTime())
-                        .toFormatter();
-            }
-            return odt;
-        }
-
-        private static DateTimeFormatter ordinalDateTimeNoMillis() {
-            if (odtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(ordinalDate())
-                        .append(tTimeNoMillis())
-                        .toFormatter();
-            }
-            return odtx;
-        }
-
-        private static DateTimeFormatter weekDateTime() {
-            if (wdt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(weekDate())
-                        .append(tTime())
-                        .toFormatter();
-            }
-            return wdt;
-        }
-
-        private static DateTimeFormatter weekDateTimeNoMillis() {
-            if (wdtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(weekDate())
-                        .append(tTimeNoMillis())
-                        .toFormatter();
-            }
-            return wdtx;
-        }
-
-        //-----------------------------------------------------------------------
-        private static DateTimeFormatter basicDate() {
-            if (bd == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendYear(4, 4)
-                        .appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
-                        .toFormatter();
-            }
-            return bd;
-        }
-
-        private static DateTimeFormatter basicTime() {
-            if (bt == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendFixedDecimal(DateTimeFieldType.hourOfDay(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.minuteOfHour(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.secondOfMinute(), 2)
-                        .appendLiteral('.')
-                        .appendFractionOfSecond(3, 9)
-                        .appendTimeZoneOffset("Z", false, 2, 2)
-                        .toFormatter();
-            }
-            return bt;
-        }
-
-        private static DateTimeFormatter basicTimeNoMillis() {
-            if (btx == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendFixedDecimal(DateTimeFieldType.hourOfDay(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.minuteOfHour(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.secondOfMinute(), 2)
-                        .appendTimeZoneOffset("Z", false, 2, 2)
-                        .toFormatter();
-            }
-            return btx;
-        }
-
-        private static DateTimeFormatter basicTTime() {
-            if (btt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(literalTElement())
-                        .append(basicTime())
-                        .toFormatter();
-            }
-            return btt;
-        }
-
-        private static DateTimeFormatter basicTTimeNoMillis() {
-            if (bttx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(literalTElement())
-                        .append(basicTimeNoMillis())
-                        .toFormatter();
-            }
-            return bttx;
-        }
-
-        private static DateTimeFormatter basicDateTime() {
-            if (bdt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicDate())
-                        .append(basicTTime())
-                        .toFormatter();
-            }
-            return bdt;
-        }
-
-        private static DateTimeFormatter basicDateTimeNoMillis() {
-            if (bdtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicDate())
-                        .append(basicTTimeNoMillis())
-                        .toFormatter();
-            }
-            return bdtx;
-        }
-
-        private static DateTimeFormatter basicOrdinalDate() {
-            if (bod == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendYear(4, 4)
-                        .appendFixedDecimal(DateTimeFieldType.dayOfYear(), 3)
-                        .toFormatter();
-            }
-            return bod;
-        }
-
-        private static DateTimeFormatter basicOrdinalDateTime() {
-            if (bodt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicOrdinalDate())
-                        .append(basicTTime())
-                        .toFormatter();
-            }
-            return bodt;
-        }
-
-        private static DateTimeFormatter basicOrdinalDateTimeNoMillis() {
-            if (bodtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicOrdinalDate())
-                        .append(basicTTimeNoMillis())
-                        .toFormatter();
-            }
-            return bodtx;
-        }
-
-        private static DateTimeFormatter basicWeekDate() {
-            if (bwd == null) {
-                return new DateTimeFormatterBuilder()
-                        // ES change, was .appendWeekyear(4, 4)
-                        .appendFixedSignedDecimal(DateTimeFieldType.weekyear(), 4)
-                        .appendLiteral('W')
-                        .appendFixedDecimal(DateTimeFieldType.weekOfWeekyear(), 2)
-                        .appendFixedDecimal(DateTimeFieldType.dayOfWeek(), 1)
-                        .toFormatter();
-            }
-            return bwd;
-        }
-
-        private static DateTimeFormatter basicWeekDateTime() {
-            if (bwdt == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicWeekDate())
-                        .append(basicTTime())
-                        .toFormatter();
-            }
-            return bwdt;
-        }
-
-        private static DateTimeFormatter basicWeekDateTimeNoMillis() {
-            if (bwdtx == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(basicWeekDate())
-                        .append(basicTTimeNoMillis())
-                        .toFormatter();
-            }
-            return bwdtx;
-        }
-
-        //-----------------------------------------------------------------------
-        private static DateTimeFormatter yearMonth() {
-            if (ym == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(yearElement())
-                        .append(monthElement())
-                        .toFormatter();
-            }
-            return ym;
-        }
-
-        private static DateTimeFormatter yearMonthDay() {
-            if (ymd == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(yearElement())
-                        .append(monthElement())
-                        .append(dayOfMonthElement())
-                        .toFormatter();
-            }
-            return ymd;
-        }
-
-        private static DateTimeFormatter weekyearWeek() {
-            if (ww == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(weekyearElement())
-                        .append(weekElement())
-                        .toFormatter();
-            }
-            return ww;
-        }
-
-        private static DateTimeFormatter weekyearWeekDay() {
-            if (wwd == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(weekyearElement())
-                        .append(weekElement())
-                        .append(dayOfWeekElement())
-                        .toFormatter();
-            }
-            return wwd;
-        }
-
-        private static DateTimeFormatter hourMinute() {
-            if (hm == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourElement())
-                        .append(minuteElement())
-                        .toFormatter();
-            }
-            return hm;
-        }
-
-        private static DateTimeFormatter hourMinuteSecond() {
-            if (hms == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourElement())
-                        .append(minuteElement())
-                        .append(secondElement())
-                        .toFormatter();
-            }
-            return hms;
-        }
-
-        private static DateTimeFormatter hourMinuteSecondMillis() {
-            if (hmsl == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourElement())
-                        .append(minuteElement())
-                        .append(secondElement())
-                        .appendLiteral('.')
-                        .appendFractionOfSecond(3, 3)
-                        .toFormatter();
-            }
-            return hmsl;
-        }
-
-        private static DateTimeFormatter hourMinuteSecondFraction() {
-            if (hmsf == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(hourElement())
-                        .append(minuteElement())
-                        .append(secondElement())
-                        .append(fractionElement())
-                        .toFormatter();
-            }
-            return hmsf;
-        }
-
-        private static DateTimeFormatter dateHour() {
-            if (dh == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(literalTElement())
-                        .append(hour())
-                        .toFormatter();
-            }
-            return dh;
-        }
-
-        private static DateTimeFormatter dateHourMinute() {
-            if (dhm == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(literalTElement())
-                        .append(hourMinute())
-                        .toFormatter();
-            }
-            return dhm;
-        }
-
-        private static DateTimeFormatter dateHourMinuteSecond() {
-            if (dhms == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(literalTElement())
-                        .append(hourMinuteSecond())
-                        .toFormatter();
-            }
-            return dhms;
-        }
-
-        private static DateTimeFormatter dateHourMinuteSecondMillis() {
-            if (dhmsl == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(literalTElement())
-                        .append(hourMinuteSecondMillis())
-                        .toFormatter();
-            }
-            return dhmsl;
-        }
-
-        private static DateTimeFormatter dateHourMinuteSecondFraction() {
-            if (dhmsf == null) {
-                return new DateTimeFormatterBuilder()
-                        .append(date())
-                        .append(literalTElement())
-                        .append(hourMinuteSecondFraction())
-                        .toFormatter();
-            }
-            return dhmsf;
-        }
-
-        //-----------------------------------------------------------------------
-        private static DateTimeFormatter yearElement() {
-            if (ye == null) {
-                return new DateTimeFormatterBuilder()
-                        // ES change, was .appendYear(4, 9)
-                        .appendFixedSignedDecimal(DateTimeFieldType.year(), 4)
-                        .toFormatter();
-            }
-            return ye;
-        }
-
-        private static DateTimeFormatter monthElement() {
-            if (mye == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('-')
-                        // ES change, was .appendMonthOfYear(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.monthOfYear(), 2)
-                        .toFormatter();
-            }
-            return mye;
-        }
-
-        private static DateTimeFormatter dayOfMonthElement() {
-            if (dme == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('-')
-                        // ES change, was .appendDayOfMonth(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.dayOfMonth(), 2)
-                        .toFormatter();
-            }
-            return dme;
-        }
-
-        private static DateTimeFormatter weekyearElement() {
-            if (we == null) {
-                return new DateTimeFormatterBuilder()
-                        // ES change, was .appendWeekyear(4, 9)
-                        .appendFixedSignedDecimal(DateTimeFieldType.weekyear(), 4)
-                        .toFormatter();
-            }
-            return we;
-        }
-
-        private static DateTimeFormatter weekElement() {
-            if (wwe == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral("-W")
-                        // ES change, was .appendWeekOfWeekyear(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.weekOfWeekyear(), 2)
-                        .toFormatter();
-            }
-            return wwe;
-        }
-
-        private static DateTimeFormatter dayOfWeekElement() {
-            if (dwe == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('-')
-                        .appendDayOfWeek(1)
-                        .toFormatter();
-            }
-            return dwe;
-        }
-
-        private static DateTimeFormatter dayOfYearElement() {
-            if (dye == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('-')
-                        // ES change, was .appendDayOfYear(3)
-                        .appendFixedSignedDecimal(DateTimeFieldType.dayOfYear(), 3)
-                        .toFormatter();
-            }
-            return dye;
-        }
-
-        private static DateTimeFormatter literalTElement() {
-            if (lte == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('T')
-                        .toFormatter();
-            }
-            return lte;
-        }
-
-        private static DateTimeFormatter hourElement() {
-            if (hde == null) {
-                return new DateTimeFormatterBuilder()
-                        // ES change, was .appendHourOfDay(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.hourOfDay(), 2)
-                        .toFormatter();
-            }
-            return hde;
-        }
-
-        private static DateTimeFormatter minuteElement() {
-            if (mhe == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral(':')
-                        // ES change, was .appendMinuteOfHour(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.minuteOfHour(), 2)
-                        .toFormatter();
-            }
-            return mhe;
-        }
-
-        private static DateTimeFormatter secondElement() {
-            if (sme == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral(':')
-                        // ES change, was .appendSecondOfMinute(2)
-                        .appendFixedSignedDecimal(DateTimeFieldType.secondOfMinute(), 2)
-                        .toFormatter();
-            }
-            return sme;
-        }
-
-        private static DateTimeFormatter fractionElement() {
-            if (fse == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendLiteral('.')
-                                // Support parsing up to nanosecond precision even though
-                                // those extra digits will be dropped.
-                        .appendFractionOfSecond(3, 9)
-                        .toFormatter();
-            }
-            return fse;
-        }
-
-        private static DateTimeFormatter offsetElement() {
-            if (ze == null) {
-                return new DateTimeFormatterBuilder()
-                        .appendTimeZoneOffset("Z", true, 2, 4)
-                        .toFormatter();
-            }
-            return ze;
-        }
-
-    }
-
-}

+ 0 - 327
server/src/test/java/org/elasticsearch/common/joda/JodaDateMathParserTests.java

@@ -1,327 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.common.joda;
-
-import org.elasticsearch.ElasticsearchParseException;
-import org.elasticsearch.common.time.DateFormatter;
-import org.elasticsearch.common.time.DateMathParser;
-import org.elasticsearch.test.ESTestCase;
-import org.joda.time.DateTimeZone;
-
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.LongSupplier;
-
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalTo;
-
-public class JodaDateMathParserTests extends ESTestCase {
-
-    DateFormatter formatter = Joda.forPattern("date_optional_time||epoch_millis");
-    DateMathParser parser = formatter.toDateMathParser();
-
-    void assertDateMathEquals(String toTest, String expected) {
-        assertDateMathEquals(toTest, expected, 0, false, null);
-    }
-
-    void assertDateMathEquals(String toTest, String expected, final long now, boolean roundUp, DateTimeZone timeZone) {
-        long gotMillis = parser.parse(toTest, () -> now, roundUp, timeZone).toEpochMilli();
-        assertDateEquals(gotMillis, toTest, expected);
-    }
-
-    void assertDateEquals(long gotMillis, String original, String expected) {
-        long expectedMillis = parser.parse(expected, () -> 0).toEpochMilli();
-        if (gotMillis != expectedMillis) {
-            fail("Date math not equal\n" +
-                "Original              : " + original + "\n" +
-                "Parsed                : " + formatter.formatMillis(gotMillis) + "\n" +
-                "Expected              : " + expected + "\n" +
-                "Expected milliseconds : " + expectedMillis + "\n" +
-                "Actual milliseconds   : " + gotMillis + "\n");
-        }
-    }
-
-    public void testOverridingLocaleOrZoneAndCompositeRoundUpParser() {
-        //the pattern has to be composite and the match should not be on the first one
-        DateFormatter formatter = Joda.forPattern("date||epoch_millis").withLocale(randomLocale(random()));
-        DateMathParser parser = formatter.toDateMathParser();
-        long gotMillis = parser.parse("297276785531", () -> 0, true, (ZoneId) null).toEpochMilli();
-        assertDateEquals(gotMillis, "297276785531", "297276785531");
-
-        formatter = Joda.forPattern("date||epoch_millis").withZone(ZoneOffset.UTC);
-        parser = formatter.toDateMathParser();
-        gotMillis = parser.parse("297276785531", () -> 0, true, (ZoneId) null).toEpochMilli();
-        assertDateEquals(gotMillis, "297276785531", "297276785531");
-    }
-
-    public void testBasicDates() {
-        assertDateMathEquals("2014", "2014-01-01T00:00:00.000");
-        assertDateMathEquals("2014-05", "2014-05-01T00:00:00.000");
-        assertDateMathEquals("2014-05-30", "2014-05-30T00:00:00.000");
-        assertDateMathEquals("2014-05-30T20", "2014-05-30T20:00:00.000");
-        assertDateMathEquals("2014-05-30T20:21", "2014-05-30T20:21:00.000");
-        assertDateMathEquals("2014-05-30T20:21:35", "2014-05-30T20:21:35.000");
-        assertDateMathEquals("2014-05-30T20:21:35.123", "2014-05-30T20:21:35.123");
-    }
-
-    public void testRoundingDoesNotAffectExactDate() {
-        assertDateMathEquals("2014-11-12T22:55:00.000Z", "2014-11-12T22:55:00.000Z", 0, true, null);
-        assertDateMathEquals("2014-11-12T22:55:00.000Z", "2014-11-12T22:55:00.000Z", 0, false, null);
-
-        assertDateMathEquals("2014-11-12T22:55:00.000", "2014-11-12T21:55:00.000Z", 0, true, DateTimeZone.forID("+01:00"));
-        assertDateMathEquals("2014-11-12T22:55:00.000", "2014-11-12T21:55:00.000Z", 0, false, DateTimeZone.forID("+01:00"));
-
-        assertDateMathEquals("2014-11-12T22:55:00.000+01:00", "2014-11-12T21:55:00.000Z", 0, true, null);
-        assertDateMathEquals("2014-11-12T22:55:00.000+01:00", "2014-11-12T21:55:00.000Z", 0, false, null);
-    }
-
-    public void testTimezone() {
-        // timezone works within date format
-        assertDateMathEquals("2014-05-30T20:21+02:00", "2014-05-30T18:21:00.000");
-
-        // test alternative ways of writing zero offsets, according to ISO 8601 +00:00, +00, +0000 should work.
-        // joda also seems to allow for -00:00, -00, -0000
-        assertDateMathEquals("2014-05-30T18:21+00:00", "2014-05-30T18:21:00.000");
-        assertDateMathEquals("2014-05-30T18:21+00", "2014-05-30T18:21:00.000");
-        assertDateMathEquals("2014-05-30T18:21+0000", "2014-05-30T18:21:00.000");
-        assertDateMathEquals("2014-05-30T18:21-00:00", "2014-05-30T18:21:00.000");
-        assertDateMathEquals("2014-05-30T18:21-00", "2014-05-30T18:21:00.000");
-        assertDateMathEquals("2014-05-30T18:21-0000", "2014-05-30T18:21:00.000");
-
-        // but also externally
-        assertDateMathEquals("2014-05-30T20:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("+02:00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("+00:00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("+00:00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("+00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("+0000"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("-00:00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("-00"));
-        assertDateMathEquals("2014-05-30T18:21", "2014-05-30T18:21:00.000", 0, false, DateTimeZone.forID("-0000"));
-
-        // and timezone in the date has priority
-        assertDateMathEquals("2014-05-30T20:21+03:00", "2014-05-30T17:21:00.000", 0, false, DateTimeZone.forID("-08:00"));
-        assertDateMathEquals("2014-05-30T20:21Z", "2014-05-30T20:21:00.000", 0, false, DateTimeZone.forID("-08:00"));
-    }
-
-    public void testBasicMath() {
-        assertDateMathEquals("2014-11-18||+y", "2015-11-18");
-        assertDateMathEquals("2014-11-18||-2y", "2012-11-18");
-
-        assertDateMathEquals("2014-11-18||+3M", "2015-02-18");
-        assertDateMathEquals("2014-11-18||-M", "2014-10-18");
-
-        assertDateMathEquals("2014-11-18||+1w", "2014-11-25");
-        assertDateMathEquals("2014-11-18||-3w", "2014-10-28");
-
-        assertDateMathEquals("2014-11-18||+22d", "2014-12-10");
-        assertDateMathEquals("2014-11-18||-423d", "2013-09-21");
-
-        assertDateMathEquals("2014-11-18T14||+13h", "2014-11-19T03");
-        assertDateMathEquals("2014-11-18T14||-1h", "2014-11-18T13");
-        assertDateMathEquals("2014-11-18T14||+13H", "2014-11-19T03");
-        assertDateMathEquals("2014-11-18T14||-1H", "2014-11-18T13");
-
-        assertDateMathEquals("2014-11-18T14:27||+10240m", "2014-11-25T17:07");
-        assertDateMathEquals("2014-11-18T14:27||-10m", "2014-11-18T14:17");
-
-        assertDateMathEquals("2014-11-18T14:27:32||+60s", "2014-11-18T14:28:32");
-        assertDateMathEquals("2014-11-18T14:27:32||-3600s", "2014-11-18T13:27:32");
-    }
-
-    public void testLenientEmptyMath() {
-        assertDateMathEquals("2014-05-30T20:21||", "2014-05-30T20:21:00.000");
-    }
-
-    public void testMultipleAdjustments() {
-        assertDateMathEquals("2014-11-18||+1M-1M", "2014-11-18");
-        assertDateMathEquals("2014-11-18||+1M-1m", "2014-12-17T23:59");
-        assertDateMathEquals("2014-11-18||-1m+1M", "2014-12-17T23:59");
-        assertDateMathEquals("2014-11-18||+1M/M", "2014-12-01");
-        assertDateMathEquals("2014-11-18||+1M/M+1h", "2014-12-01T01");
-    }
-
-
-    public void testNow() {
-        final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, (ZoneId) null).toEpochMilli();
-
-        assertDateMathEquals("now", "2014-11-18T14:27:32", now, false, null);
-        assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, false, null);
-        assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, true, null);
-        assertDateMathEquals("now-2d", "2014-11-16T14:27:32", now, false, null);
-        assertDateMathEquals("now-2d", "2014-11-16T14:27:32", now, true, null);
-        assertDateMathEquals("now/m", "2014-11-18T14:27", now, false, null);
-        assertDateMathEquals("now/m", "2014-11-18T14:27:59.999Z", now, true, null);
-        assertDateMathEquals("now/M", "2014-11-01T00:00:00", now, false, null);
-        assertDateMathEquals("now/M", "2014-11-30T23:59:59.999Z", now, true, null);
-
-        // timezone does not affect now
-        assertDateMathEquals("now/m", "2014-11-18T14:27", now, false, DateTimeZone.forID("+02:00"));
-    }
-
-    public void testRoundingPreservesEpochAsBaseDate() {
-        // If a user only specifies times, then the date needs to always be 1970-01-01 regardless of rounding
-        DateFormatter formatter = DateFormatter.forPattern("HH:mm:ss");
-        DateMathParser parser = formatter.toDateMathParser();
-        assertEquals(
-                this.formatter.parseMillis("1970-01-01T04:52:20.000Z"),
-                parser.parse("04:52:20", () -> 0, false, (ZoneId) null).toEpochMilli());
-        assertEquals(
-                this.formatter.parseMillis("1970-01-01T04:52:20.999Z"),
-                parser.parse("04:52:20", () -> 0, true, (ZoneId) null).toEpochMilli());
-    }
-
-    // Implicit rounding happening when parts of the date are not specified
-    public void testImplicitRounding() {
-        assertDateMathEquals("2014-11-18", "2014-11-18", 0, false, null);
-        assertDateMathEquals("2014-11-18", "2014-11-18T23:59:59.999Z", 0, true, null);
-
-        assertDateMathEquals("2014-11-18T09:20", "2014-11-18T09:20", 0, false, null);
-        assertDateMathEquals("2014-11-18T09:20", "2014-11-18T09:20:59.999Z", 0, true, null);
-
-        assertDateMathEquals("2014-11-18", "2014-11-17T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-11-18", "2014-11-18T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
-
-        assertDateMathEquals("2014-11-18T09:20", "2014-11-18T08:20:00.000Z", 0, false, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-11-18T09:20", "2014-11-18T08:20:59.999Z", 0, true, DateTimeZone.forID("CET"));
-
-        // implicit rounding with explicit timezone in the date format
-        DateFormatter formatter = Joda.forPattern("yyyy-MM-ddZ");
-        DateMathParser parser = formatter.toDateMathParser();
-        Instant time = parser.parse("2011-10-09+01:00", () -> 0, false, (ZoneId) null);
-        assertEquals(this.parser.parse("2011-10-09T00:00:00.000+01:00", () -> 0), time);
-        time = parser.parse("2011-10-09+01:00", () -> 0, true, (ZoneId) null);
-        assertEquals(this.parser.parse("2011-10-09T23:59:59.999+01:00", () -> 0), time);
-    }
-
-    // Explicit rounding using the || separator
-    public void testExplicitRounding() {
-        assertDateMathEquals("2014-11-18||/y", "2014-01-01", 0, false, null);
-        assertDateMathEquals("2014-11-18||/y", "2014-12-31T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014||/y", "2014-01-01", 0, false, null);
-        assertDateMathEquals("2014-01-01T00:00:00.001||/y", "2014-12-31T23:59:59.999", 0, true, null);
-        // rounding should also take into account time zone
-        assertDateMathEquals("2014-11-18||/y", "2013-12-31T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-11-18||/y", "2014-12-31T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
-
-        assertDateMathEquals("2014-11-18||/M", "2014-11-01", 0, false, null);
-        assertDateMathEquals("2014-11-18||/M", "2014-11-30T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11||/M", "2014-11-01", 0, false, null);
-        assertDateMathEquals("2014-11||/M", "2014-11-30T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18||/M", "2014-10-31T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-11-18||/M", "2014-11-30T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
-
-        assertDateMathEquals("2014-11-17T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-18T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-19T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-20T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-21T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-22T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-23T14||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-18T14||/w", "2014-11-23T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18||/w", "2014-11-17", 0, false, null);
-        assertDateMathEquals("2014-11-18||/w", "2014-11-23T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18||/w", "2014-11-16T23:00:00.000Z", 0, false, DateTimeZone.forID("+01:00"));
-        assertDateMathEquals("2014-11-18||/w", "2014-11-17T01:00:00.000Z", 0, false, DateTimeZone.forID("-01:00"));
-        assertDateMathEquals("2014-11-18||/w", "2014-11-16T23:00:00.000Z", 0, false, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-11-18||/w", "2014-11-23T22:59:59.999Z", 0, true, DateTimeZone.forID("CET"));
-        assertDateMathEquals("2014-07-22||/w", "2014-07-20T22:00:00.000Z", 0, false, DateTimeZone.forID("CET")); // with DST
-
-        assertDateMathEquals("2014-11-18T14||/d", "2014-11-18", 0, false, null);
-        assertDateMathEquals("2014-11-18T14||/d", "2014-11-18T23:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18||/d", "2014-11-18", 0, false, null);
-        assertDateMathEquals("2014-11-18||/d", "2014-11-18T23:59:59.999", 0, true, null);
-
-        assertDateMathEquals("2014-11-18T14:27||/h", "2014-11-18T14", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27||/h", "2014-11-18T14:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18T14||/H", "2014-11-18T14", 0, false, null);
-        assertDateMathEquals("2014-11-18T14||/H", "2014-11-18T14:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18T14:27||/h", "2014-11-18T14", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27||/h", "2014-11-18T14:59:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18T14||/H", "2014-11-18T14", 0, false, null);
-        assertDateMathEquals("2014-11-18T14||/H", "2014-11-18T14:59:59.999", 0, true, null);
-
-        assertDateMathEquals("2014-11-18T14:27:32||/m", "2014-11-18T14:27", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27:32||/m", "2014-11-18T14:27:59.999", 0, true, null);
-        assertDateMathEquals("2014-11-18T14:27||/m", "2014-11-18T14:27", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27||/m", "2014-11-18T14:27:59.999", 0, true, null);
-
-        assertDateMathEquals("2014-11-18T14:27:32.123||/s", "2014-11-18T14:27:32", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27:32.123||/s", "2014-11-18T14:27:32.999", 0, true, null);
-        assertDateMathEquals("2014-11-18T14:27:32||/s", "2014-11-18T14:27:32", 0, false, null);
-        assertDateMathEquals("2014-11-18T14:27:32||/s", "2014-11-18T14:27:32.999", 0, true, null);
-    }
-
-    public void testTimestamps() {
-        assertDateMathEquals("1418248078000", "2014-12-10T21:47:58.000");
-        assertDateMathEquals("32484216259000", "2999-05-20T17:24:19.000");
-        assertDateMathEquals("253382837059000", "9999-05-20T17:24:19.000");
-
-        // datemath still works on timestamps
-        assertDateMathEquals("1418248078000||/m", "2014-12-10T21:47:00.000");
-
-        // also check other time units
-        JodaDateMathParser parser = new JodaDateMathParser(Joda.forPattern("epoch_second"));
-        long datetime = parser.parse("1418248078", () -> 0).toEpochMilli();
-        assertDateEquals(datetime, "1418248078", "2014-12-10T21:47:58.000");
-
-        // a timestamp before 10000 is a year
-        assertDateMathEquals("9999", "9999-01-01T00:00:00.000");
-        // 10000 is also a year, breaking bwc, used to be a timestamp
-        assertDateMathEquals("10000", "10000-01-01T00:00:00.000");
-        // but 10000 with T is still a date format
-        assertDateMathEquals("10000T", "10000-01-01T00:00:00.000");
-    }
-
-    void assertParseException(String msg, String date, String exc) {
-        try {
-            parser.parse(date, () -> 0);
-            fail("Date: " + date + "\n" + msg);
-        } catch (ElasticsearchParseException e) {
-            assertThat(e.getMessage().contains(exc), equalTo(true));
-        }
-    }
-
-    public void testIllegalMathFormat() {
-        assertParseException("Expected date math unsupported operator exception", "2014-11-18||*5", "operator not supported");
-        assertParseException("Expected date math incompatible rounding exception", "2014-11-18||/2m", "rounding");
-        assertParseException("Expected date math illegal unit type exception", "2014-11-18||+2a", "unit [a] not supported");
-        assertParseException("Expected date math truncation exception", "2014-11-18||+12", "truncated");
-        assertParseException("Expected date math truncation exception", "2014-11-18||-", "truncated");
-    }
-
-    public void testIllegalDateFormat() {
-        assertParseException("Expected bad timestamp exception", Long.toString(Long.MAX_VALUE) + "0", "failed to parse date field");
-        assertParseException("Expected bad date format exception", "123bogus", "with format");
-    }
-
-    public void testOnlyCallsNowIfNecessary() {
-        final AtomicBoolean called = new AtomicBoolean();
-        final LongSupplier now = () -> {
-            called.set(true);
-            return 42L;
-        };
-        parser.parse("2014-11-18T14:27:32", now, false, (ZoneId) null);
-        assertFalse(called.get());
-        parser.parse("now/d", now, false, (ZoneId) null);
-        assertTrue(called.get());
-    }
-
-    public void testThatUnixTimestampMayNotHaveTimeZone() {
-        JodaDateMathParser parser = new JodaDateMathParser(Joda.forPattern("epoch_millis"));
-        try {
-            parser.parse("1234567890123", () -> 42, false, ZoneId.of("CET"));
-            fail("Expected ElasticsearchParseException");
-        } catch(ElasticsearchParseException e) {
-            assertThat(e.getMessage(), containsString("failed to parse date field"));
-            assertThat(e.getMessage(), containsString("with format [epoch_millis]"));
-        }
-    }
-}

+ 0 - 58
server/src/test/java/org/elasticsearch/common/joda/JodaTests.java

@@ -1,58 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.common.joda;
-
-import org.elasticsearch.common.time.DateFormatter;
-import org.elasticsearch.test.ESTestCase;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
-import java.time.ZoneOffset;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-
-
-public class JodaTests extends ESTestCase {
-
-    public void testBasicTTimePattern() {
-        DateFormatter formatter1 = Joda.forPattern("basic_t_time");
-        assertEquals(formatter1.pattern(), "basic_t_time");
-        assertEquals(formatter1.zone(), ZoneOffset.UTC);
-
-        DateFormatter formatter2 = Joda.forPattern("basic_t_time");
-        assertEquals(formatter2.pattern(), "basic_t_time");
-        assertEquals(formatter2.zone(), ZoneOffset.UTC);
-
-        DateTime dt = new DateTime(2004, 6, 9, 10, 20, 30, 40, DateTimeZone.UTC);
-        assertEquals("T102030.040Z", formatter1.formatJoda(dt));
-        assertEquals("T102030.040Z", formatter1.formatJoda(dt));
-
-        expectThrows(IllegalArgumentException.class, () -> Joda.forPattern("basic_t_Time"));
-        expectThrows(IllegalArgumentException.class, () -> Joda.forPattern("basic_T_Time"));
-        expectThrows(IllegalArgumentException.class, () -> Joda.forPattern("basic_T_time"));
-    }
-
-    public void testEqualsAndHashcode() {
-        String format = randomFrom("yyyy/MM/dd HH:mm:ss", "basic_t_time");
-        JodaDateFormatter first = Joda.forPattern(format);
-        JodaDateFormatter second = Joda.forPattern(format);
-        JodaDateFormatter third = Joda.forPattern(" HH:mm:ss, yyyy/MM/dd");
-
-        assertThat(first, is(second));
-        assertThat(second, is(first));
-        assertThat(first, is(not(third)));
-        assertThat(second, is(not(third)));
-
-        assertThat(first.hashCode(), is(second.hashCode()));
-        assertThat(second.hashCode(), is(first.hashCode()));
-        assertThat(first.hashCode(), is(not(third.hashCode())));
-        assertThat(second.hashCode(), is(not(third.hashCode())));
-    }
-}

+ 1 - 10
server/src/test/java/org/elasticsearch/common/time/DateFormattersTests.java

@@ -9,11 +9,9 @@
 package org.elasticsearch.common.time;
 
 import org.elasticsearch.ElasticsearchParseException;
-import org.elasticsearch.common.joda.Joda;
 import org.elasticsearch.common.util.LocaleUtils;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.test.ESTestCase;
-import org.hamcrest.CoreMatchers;
 
 import java.time.Clock;
 import java.time.Instant;
@@ -502,11 +500,6 @@ public class DateFormattersTests extends ESTestCase {
             () -> dateMathToMillis(text, DateFormatter.forPattern(pattern)));
         assertThat(e1.getMessage(), containsString(pattern));
         assertThat(e1.getMessage(), containsString(text));
-
-        ElasticsearchParseException e2 = expectThrows(ElasticsearchParseException.class,
-            () -> dateMathToMillis(text, Joda.forPattern(pattern)));
-        assertThat(e2.getMessage(), containsString(pattern));
-        assertThat(e2.getMessage(), containsString(text));
     }
 
     private long dateMathToMillis(String text, DateFormatter dateFormatter) {
@@ -519,9 +512,8 @@ public class DateFormattersTests extends ESTestCase {
         //7 (ok joda) vs 1 (java by default) but 7 with customized org.elasticsearch.common.time.IsoLocale.ISO8601
         ZonedDateTime now = LocalDateTime.of(2009,11,15,1,32,8,328402)
             .atZone(ZoneOffset.UTC); //Sunday
-        DateFormatter jodaFormatter = Joda.forPattern("e").withLocale(Locale.ROOT).withZone(ZoneOffset.UTC);
         DateFormatter javaFormatter = DateFormatter.forPattern("8e").withZone(ZoneOffset.UTC);
-        assertThat(jodaFormatter.format(now), CoreMatchers.equalTo(javaFormatter.format(now)));
+        assertThat(javaFormatter.format(now), equalTo("7"));
     }
 
     public void testStartOfWeek() {
@@ -541,7 +533,6 @@ public class DateFormattersTests extends ESTestCase {
         assertParses("2001-01-01T00:00:00,123Z", "date_optional_time");
 
         // only java.time has nanos parsing, but the results for 3digits should be the same
-        DateFormatter jodaFormatter = Joda.forPattern("strict_date_optional_time");
         DateFormatter javaFormatter = DateFormatter.forPattern("strict_date_optional_time_nanos");
         assertParses("2001-01-01T00:00:00.123Z", javaFormatter);
         assertParses("2001-01-01T00:00:00,123Z", javaFormatter);