Speed up converting of temporal accessor to zoned date time ()

The existing implementation was slow due to exceptions being thrown if
an accessor did not have a time zone. This implementation queries for
having a timezone, local time and local date and also checks for an
instant preventing to throw an exception and thus speeding up the conversion.

This removes the existing method and create a new one named
DateFormatters.from(TemporalAccessor accessor) to resemble the naming of
the java time ones.

Before this change an epoch millis parser using the toZonedDateTime
method took approximately 50x longer.

Relates 
This commit is contained in:
Alexander Reelsen 2019-01-31 08:55:40 +01:00 committed by GitHub
parent 160d1bd4dd
commit b94acb608b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 223 additions and 142 deletions
benchmarks/src/main/java/org/elasticsearch/benchmark/time
client/rest-high-level/src/main/java/org/elasticsearch/client/ml/job/util
modules/ingest-common/src
main/java/org/elasticsearch/ingest/common
test/java/org/elasticsearch/ingest/common
server/src
x-pack/plugin/core/src/main/java/org/elasticsearch/license

@ -0,0 +1,53 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.
*/
package org.elasticsearch.benchmark.time;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateFormatters;
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 DateFormatterFromBenchmark {
private final TemporalAccessor accessor = DateFormatter.forPattern("epoch_millis").parse("1234567890");
@Benchmark
public TemporalAccessor benchmarkFrom() {
// benchmark an accessor that does not contain a timezone
// this used to throw an exception earlier and thus was very very slow
return DateFormatters.from(accessor);
}
}

@ -39,7 +39,7 @@ public final class TimeUtil {
if (parser.currentToken() == XContentParser.Token.VALUE_NUMBER) { if (parser.currentToken() == XContentParser.Token.VALUE_NUMBER) {
return new Date(parser.longValue()); return new Date(parser.longValue());
} else if (parser.currentToken() == XContentParser.Token.VALUE_STRING) { } else if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
return new Date(DateFormatters.toZonedDateTime(DateTimeFormatter.ISO_INSTANT.parse(parser.text())).toInstant().toEpochMilli()); return new Date(DateFormatters.from(DateTimeFormatter.ISO_INSTANT.parse(parser.text())).toInstant().toEpochMilli());
} }
throw new IllegalArgumentException( throw new IllegalArgumentException(
"unexpected token [" + parser.currentToken() + "] for [" + fieldName + "]"); "unexpected token [" + parser.currentToken() + "] for [" + fieldName + "]");

@ -28,12 +28,23 @@ import org.joda.time.format.ISODateTimeFormat;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.function.Function; import java.util.function.Function;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
import static java.time.temporal.ChronoField.SECOND_OF_DAY;
enum DateFormat { enum DateFormat {
Iso8601 { Iso8601 {
@Override @Override
@ -70,22 +81,37 @@ enum DateFormat {
} }
}, },
Java { Java {
private final List<ChronoField> FIELDS =
Arrays.asList(NANO_OF_SECOND, SECOND_OF_DAY, MINUTE_OF_DAY, HOUR_OF_DAY, DAY_OF_MONTH, MONTH_OF_YEAR);
@Override @Override
Function<String, DateTime> getFunction(String format, DateTimeZone timezone, Locale locale) { Function<String, DateTime> getFunction(String format, DateTimeZone timezone, Locale locale) {
// support the 6.x BWC compatible way of parsing java 8 dates // support the 6.x BWC compatible way of parsing java 8 dates
if (format.startsWith("8")) { if (format.startsWith("8")) {
format = format.substring(1); format = format.substring(1);
} }
ZoneId zoneId = DateUtils.dateTimeZoneToZoneId(timezone);
int year = LocalDate.now(ZoneOffset.UTC).getYear(); int year = LocalDate.now(ZoneOffset.UTC).getYear();
DateFormatter formatter = DateFormatter.forPattern(format) DateFormatter formatter = DateFormatter.forPattern(format)
.withLocale(locale) .withLocale(locale)
.withZone(DateUtils.dateTimeZoneToZoneId(timezone)); .withZone(zoneId);
return text -> { return text -> {
ZonedDateTime defaultZonedDateTime = Instant.EPOCH.atZone(ZoneOffset.UTC).withYear(year);
TemporalAccessor accessor = formatter.parse(text); TemporalAccessor accessor = formatter.parse(text);
long millis = DateFormatters.toZonedDateTime(accessor, defaultZonedDateTime).toInstant().toEpochMilli(); // if there is no year, we fall back to the current one and
// fill the rest of the date up with the parsed date
if (accessor.isSupported(ChronoField.YEAR) == false) {
ZonedDateTime newTime = Instant.EPOCH.atZone(ZoneOffset.UTC).withYear(year);
for (ChronoField field : FIELDS) {
if (accessor.isSupported(field)) {
newTime = newTime.with(field, accessor.get(field));
}
}
accessor = newTime.withZoneSameLocal(zoneId);
}
long millis = DateFormatters.from(accessor).toInstant().toEpochMilli();
return new DateTime(millis, timezone); return new DateTime(millis, timezone);
}; };
} }

@ -19,29 +19,43 @@
package org.elasticsearch.ingest.common; package org.elasticsearch.ingest.common;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Locale; import java.util.Locale;
import java.util.function.Function; import java.util.function.Function;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsEqual.equalTo; import static org.hamcrest.core.IsEqual.equalTo;
public class DateFormatTests extends ESTestCase { public class DateFormatTests extends ESTestCase {
public void testParseJoda() { public void testParseJava() {
Function<String, DateTime> jodaFunction = DateFormat.Java.getFunction("MMM dd HH:mm:ss Z", Function<String, DateTime> javaFunction = DateFormat.Java.getFunction("MMM dd HH:mm:ss Z",
DateTimeZone.forOffsetHours(-8), Locale.ENGLISH); DateTimeZone.forOffsetHours(-8), Locale.ENGLISH);
assertThat(Instant.ofEpochMilli(jodaFunction.apply("Nov 24 01:29:01 -0800").getMillis()) assertThat(Instant.ofEpochMilli(javaFunction.apply("Nov 24 01:29:01 -0800").getMillis())
.atZone(ZoneId.of("GMT-8")) .atZone(ZoneId.of("GMT-8"))
.format(DateTimeFormatter.ofPattern("MM dd HH:mm:ss", Locale.ENGLISH)), .format(DateTimeFormatter.ofPattern("MM dd HH:mm:ss", Locale.ENGLISH)),
equalTo("11 24 01:29:01")); equalTo("11 24 01:29:01"));
} }
public void testParseJavaDefaultYear() {
String format = randomFrom("8dd/MM", "dd/MM");
DateTimeZone timezone = DateUtils.zoneIdToDateTimeZone(ZoneId.of("Europe/Amsterdam"));
Function<String, DateTime> javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.ENGLISH);
int year = ZonedDateTime.now(ZoneOffset.UTC).getYear();
DateTime dateTime = javaFunction.apply("12/06");
assertThat(dateTime.getYear(), is(year));
assertThat(dateTime.toString(), is(year + "-06-12T00:00:00.000+02:00"));
}
public void testParseUnixMs() { public void testParseUnixMs() {
assertThat(DateFormat.UnixMs.getFunction(null, DateTimeZone.UTC, null).apply("1000500").getMillis(), equalTo(1000500L)); assertThat(DateFormat.UnixMs.getFunction(null, DateTimeZone.UTC, null).apply("1000500").getMillis(), equalTo(1000500L));
} }

@ -20,11 +20,13 @@
package org.elasticsearch.common.time; package org.elasticsearch.common.time;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.SuppressForbidden;
import java.time.DateTimeException;
import java.time.DayOfWeek; import java.time.DayOfWeek;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Year;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
@ -1550,105 +1552,91 @@ public class DateFormatters {
dateTimeFormatters.toArray(new DateTimeFormatter[0])); dateTimeFormatters.toArray(new DateTimeFormatter[0]));
} }
private static final ZonedDateTime EPOCH_ZONED_DATE_TIME = Instant.EPOCH.atZone(ZoneOffset.UTC); private static final LocalDate LOCALDATE_EPOCH = LocalDate.of(1970, 1, 1);
public static ZonedDateTime toZonedDateTime(TemporalAccessor accessor) { /**
return toZonedDateTime(accessor, EPOCH_ZONED_DATE_TIME); * Convert a temporal accessor to a zoned date time object - as performant as possible.
} * The .from() methods from the JDK are throwing exceptions when for example ZonedDateTime.from(accessor)
* or Instant.from(accessor). This results in a huge performance penalty and should be prevented
public static ZonedDateTime toZonedDateTime(TemporalAccessor accessor, ZonedDateTime defaults) { * This method prevents exceptions by querying the accessor for certain capabilities
try { * and then act on it accordingly
return ZonedDateTime.from(accessor); *
} catch (DateTimeException e ) { * This action assumes that we can reliably fall back to some defaults if not all parts of a
* zoned date time are set
*
* - If a zoned date time is passed, it is returned
* - If no timezone is found, ZoneOffset.UTC is used
* - If we find a time and a date, converting to a ZonedDateTime is straight forward,
* no defaults will be applied
* - If an accessor only containing of seconds and nanos is found (like epoch_millis/second)
* an Instant is created out of that, that becomes a ZonedDateTime with a time zone
* - If no time is given, the start of the day is used
* - If no month of the year is found, the first day of the year is used
* - If an iso based weekyear is found, but not week is specified, the first monday
* of the new year is chosen (reataining BWC to joda time)
* - If an iso based weekyear is found and an iso based weekyear week, the start
* of the day is used
*
* @param accessor The accessor returned from a parser
*
* @return The converted zoned date time
*/
public static ZonedDateTime from(TemporalAccessor accessor) {
if (accessor instanceof ZonedDateTime) {
return (ZonedDateTime) accessor;
} }
ZonedDateTime result = defaults; ZoneId zoneId = accessor.query(TemporalQueries.zone());
if (zoneId == null) {
zoneId = ZoneOffset.UTC;
}
LocalDate localDate = accessor.query(TemporalQueries.localDate());
LocalTime localTime = accessor.query(TemporalQueries.localTime());
boolean isLocalDateSet = localDate != null;
boolean isLocalTimeSet = localTime != null;
// special case epoch seconds // the first two cases are the most common, so this allows us to exit early when parsing dates
if (accessor.isSupported(ChronoField.INSTANT_SECONDS)) { if (isLocalDateSet && isLocalTimeSet) {
result = result.with(ChronoField.INSTANT_SECONDS, accessor.getLong(ChronoField.INSTANT_SECONDS)); return of(localDate, localTime, zoneId);
if (accessor.isSupported(ChronoField.NANO_OF_SECOND)) { } else if (accessor.isSupported(ChronoField.INSTANT_SECONDS) && accessor.isSupported(NANO_OF_SECOND)) {
result = result.with(ChronoField.NANO_OF_SECOND, accessor.getLong(ChronoField.NANO_OF_SECOND)); return Instant.from(accessor).atZone(zoneId);
} else if (isLocalDateSet) {
return localDate.atStartOfDay(zoneId);
} else if (isLocalTimeSet) {
return of(LOCALDATE_EPOCH, localTime, zoneId);
} else if (accessor.isSupported(ChronoField.YEAR)) {
if (accessor.isSupported(MONTH_OF_YEAR)) {
return getFirstOfMonth(accessor).atStartOfDay(zoneId);
} else {
return Year.of(accessor.get(ChronoField.YEAR)).atDay(1).atStartOfDay(zoneId);
} }
return result;
}
// try to set current year
if (accessor.isSupported(ChronoField.YEAR)) {
result = result.with(ChronoField.YEAR, accessor.getLong(ChronoField.YEAR));
} else if (accessor.isSupported(ChronoField.YEAR_OF_ERA)) {
result = result.with(ChronoField.YEAR_OF_ERA, accessor.getLong(ChronoField.YEAR_OF_ERA));
} else if (accessor.isSupported(WeekFields.ISO.weekBasedYear())) { } else if (accessor.isSupported(WeekFields.ISO.weekBasedYear())) {
if (accessor.isSupported(WeekFields.ISO.weekOfWeekBasedYear())) { if (accessor.isSupported(WeekFields.ISO.weekOfWeekBasedYear())) {
return LocalDate.from(result) return Year.of(accessor.get(WeekFields.ISO.weekBasedYear()))
.with(WeekFields.ISO.weekBasedYear(), accessor.getLong(WeekFields.ISO.weekBasedYear())) .atDay(1)
.withDayOfMonth(1) // makes this compatible with joda
.with(WeekFields.ISO.weekOfWeekBasedYear(), accessor.getLong(WeekFields.ISO.weekOfWeekBasedYear())) .with(WeekFields.ISO.weekOfWeekBasedYear(), accessor.getLong(WeekFields.ISO.weekOfWeekBasedYear()))
.atStartOfDay(ZoneOffset.UTC); .atStartOfDay(zoneId);
} else { } else {
return LocalDate.from(result) return Year.of(accessor.get(WeekFields.ISO.weekBasedYear()))
.with(WeekFields.ISO.weekBasedYear(), accessor.getLong(WeekFields.ISO.weekBasedYear())) .atDay(1)
// this exists solely to be BWC compatible with joda
// .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY))
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)) .with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))
.atStartOfDay(defaults.getZone()); .atStartOfDay(zoneId);
// return result.withHour(0).withMinute(0).withSecond(0)
// .with(WeekFields.ISO.weekBasedYear(), 0)
// .with(WeekFields.ISO.weekBasedYear(), accessor.getLong(WeekFields.ISO.weekBasedYear()));
// return ((ZonedDateTime) tmp).with(WeekFields.ISO.weekOfWeekBasedYear(), 1);
} }
} else if (accessor.isSupported(IsoFields.WEEK_BASED_YEAR)) {
// special case weekbased year
result = result.with(IsoFields.WEEK_BASED_YEAR, accessor.getLong(IsoFields.WEEK_BASED_YEAR));
if (accessor.isSupported(IsoFields.WEEK_OF_WEEK_BASED_YEAR)) {
result = result.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, accessor.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
}
return result;
} }
// month // we should not reach this piece of code, everything being parsed we should be able to
if (accessor.isSupported(ChronoField.MONTH_OF_YEAR)) { // convert to a zoned date time! If not, we have to extend the above methods
result = result.with(ChronoField.MONTH_OF_YEAR, accessor.getLong(ChronoField.MONTH_OF_YEAR)); throw new IllegalArgumentException("temporal accessor [" + accessor + "] cannot be converted to zoned date time");
} }
// day of month @SuppressForbidden(reason = "ZonedDateTime.of is fine here")
if (accessor.isSupported(ChronoField.DAY_OF_MONTH)) { private static ZonedDateTime of(LocalDate localDate, LocalTime localTime, ZoneId zoneId) {
result = result.with(ChronoField.DAY_OF_MONTH, accessor.getLong(ChronoField.DAY_OF_MONTH)); return ZonedDateTime.of(localDate, localTime, zoneId);
} }
// hour @SuppressForbidden(reason = "LocalDate.of is fine here")
if (accessor.isSupported(ChronoField.HOUR_OF_DAY)) { private static LocalDate getFirstOfMonth(TemporalAccessor accessor) {
result = result.with(ChronoField.HOUR_OF_DAY, accessor.getLong(ChronoField.HOUR_OF_DAY)); return LocalDate.of(accessor.get(ChronoField.YEAR), accessor.get(MONTH_OF_YEAR), 1);
}
// minute
if (accessor.isSupported(ChronoField.MINUTE_OF_HOUR)) {
result = result.with(ChronoField.MINUTE_OF_HOUR, accessor.getLong(ChronoField.MINUTE_OF_HOUR));
}
// second
if (accessor.isSupported(ChronoField.SECOND_OF_MINUTE)) {
result = result.with(ChronoField.SECOND_OF_MINUTE, accessor.getLong(ChronoField.SECOND_OF_MINUTE));
}
if (accessor.isSupported(ChronoField.OFFSET_SECONDS)) {
result = result.withZoneSameLocal(ZoneOffset.ofTotalSeconds(accessor.get(ChronoField.OFFSET_SECONDS)));
}
// millis
if (accessor.isSupported(ChronoField.MILLI_OF_SECOND)) {
result = result.with(ChronoField.MILLI_OF_SECOND, accessor.getLong(ChronoField.MILLI_OF_SECOND));
}
if (accessor.isSupported(ChronoField.NANO_OF_SECOND)) {
result = result.with(ChronoField.NANO_OF_SECOND, accessor.getLong(ChronoField.NANO_OF_SECOND));
}
ZoneId zoneOffset = accessor.query(TemporalQueries.zone());
if (zoneOffset != null) {
result = result.withZoneSameLocal(zoneOffset);
}
return result;
} }
} }

@ -218,7 +218,7 @@ public class JavaDateMathParser implements DateMathParser {
DateTimeFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter; DateTimeFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter;
try { try {
if (timeZone == null) { if (timeZone == null) {
return DateFormatters.toZonedDateTime(formatter.parse(value)).toInstant(); return DateFormatters.from(formatter.parse(value)).toInstant();
} else { } else {
TemporalAccessor accessor = formatter.parse(value); TemporalAccessor accessor = formatter.parse(value);
ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor); ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor);
@ -226,7 +226,7 @@ public class JavaDateMathParser implements DateMathParser {
timeZone = zoneId; timeZone = zoneId;
} }
return DateFormatters.toZonedDateTime(accessor).withZoneSameLocal(timeZone).toInstant(); return DateFormatters.from(accessor).withZoneSameLocal(timeZone).toInstant();
} }
} catch (DateTimeParseException e) { } catch (DateTimeParseException e) {
throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]: [{}]", throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]: [{}]",

@ -247,7 +247,7 @@ public class DateFieldMapper extends FieldMapper {
} }
long parse(String value) { long parse(String value) {
return DateFormatters.toZonedDateTime(dateTimeFormatter().parse(value)).toInstant().toEpochMilli(); return DateFormatters.from(dateTimeFormatter().parse(value)).toInstant().toEpochMilli();
} }
@Override @Override

@ -730,7 +730,7 @@ public class RoundingTests extends ESTestCase {
private static long time(String time, ZoneId zone) { private static long time(String time, ZoneId zone) {
TemporalAccessor accessor = DateFormatter.forPattern("date_optional_time").withZone(zone).parse(time); TemporalAccessor accessor = DateFormatter.forPattern("date_optional_time").withZone(zone).parse(time);
return DateFormatters.toZonedDateTime(accessor).toInstant().toEpochMilli(); return DateFormatters.from(accessor).toInstant().toEpochMilli();
} }
private static Matcher<Long> isDate(final long expected, ZoneId tz) { private static Matcher<Long> isDate(final long expected, ZoneId tz) {

@ -688,7 +688,7 @@ public class JavaJodaTimeDuellingTests extends ESTestCase {
DateTime jodaDateTime = jodaFormatter.parseJoda(input); DateTime jodaDateTime = jodaFormatter.parseJoda(input);
TemporalAccessor javaTimeAccessor = javaFormatter.parse(input); TemporalAccessor javaTimeAccessor = javaFormatter.parse(input);
ZonedDateTime zonedDateTime = DateFormatters.toZonedDateTime(javaTimeAccessor); ZonedDateTime zonedDateTime = DateFormatters.from(javaTimeAccessor);
String msg = String.format(Locale.ROOT, "Input [%s] Format [%s] Joda [%s], Java [%s]", input, format, jodaDateTime, String msg = String.format(Locale.ROOT, "Input [%s] Format [%s] Joda [%s], Java [%s]", input, format, jodaDateTime,
DateTimeFormatter.ISO_INSTANT.format(zonedDateTime.toInstant())); DateTimeFormatter.ISO_INSTANT.format(zonedDateTime.toInstant()));

@ -84,14 +84,14 @@ public class DateFormattersTests extends ESTestCase {
public void testEpochMilliParsersWithDifferentFormatters() { public void testEpochMilliParsersWithDifferentFormatters() {
DateFormatter formatter = DateFormatter.forPattern("strict_date_optional_time||epoch_millis"); DateFormatter formatter = DateFormatter.forPattern("strict_date_optional_time||epoch_millis");
TemporalAccessor accessor = formatter.parse("123"); TemporalAccessor accessor = formatter.parse("123");
assertThat(DateFormatters.toZonedDateTime(accessor).toInstant().toEpochMilli(), is(123L)); assertThat(DateFormatters.from(accessor).toInstant().toEpochMilli(), is(123L));
assertThat(formatter.pattern(), is("strict_date_optional_time||epoch_millis")); assertThat(formatter.pattern(), is("strict_date_optional_time||epoch_millis"));
} }
public void testParsersWithMultipleInternalFormats() throws Exception { public void testParsersWithMultipleInternalFormats() throws Exception {
ZonedDateTime first = DateFormatters.toZonedDateTime( ZonedDateTime first = DateFormatters.from(
DateFormatters.forPattern("strict_date_optional_time_nanos").parse("2018-05-15T17:14:56+0100")); DateFormatters.forPattern("strict_date_optional_time_nanos").parse("2018-05-15T17:14:56+0100"));
ZonedDateTime second = DateFormatters.toZonedDateTime( ZonedDateTime second = DateFormatters.from(
DateFormatters.forPattern("strict_date_optional_time_nanos").parse("2018-05-15T17:14:56+01:00")); DateFormatters.forPattern("strict_date_optional_time_nanos").parse("2018-05-15T17:14:56+01:00"));
assertThat(first, is(second)); assertThat(first, is(second));
} }
@ -163,7 +163,7 @@ public class DateFormattersTests extends ESTestCase {
assertRoundupFormatter("epoch_millis", "1234567890", 1234567890L); assertRoundupFormatter("epoch_millis", "1234567890", 1234567890L);
// also check nanos of the epoch_millis formatter if it is rounded up to the nano second // also check nanos of the epoch_millis formatter if it is rounded up to the nano second
DateTimeFormatter roundUpFormatter = ((JavaDateFormatter) DateFormatter.forPattern("8epoch_millis")).getRoundupParser(); DateTimeFormatter roundUpFormatter = ((JavaDateFormatter) DateFormatter.forPattern("8epoch_millis")).getRoundupParser();
Instant epochMilliInstant = DateFormatters.toZonedDateTime(roundUpFormatter.parse("1234567890")).toInstant(); Instant epochMilliInstant = DateFormatters.from(roundUpFormatter.parse("1234567890")).toInstant();
assertThat(epochMilliInstant.getLong(ChronoField.NANO_OF_SECOND), is(890_999_999L)); assertThat(epochMilliInstant.getLong(ChronoField.NANO_OF_SECOND), is(890_999_999L));
assertRoundupFormatter("strict_date_optional_time||epoch_millis", "2018-10-10T12:13:14.123Z", 1539173594123L); assertRoundupFormatter("strict_date_optional_time||epoch_millis", "2018-10-10T12:13:14.123Z", 1539173594123L);
@ -175,7 +175,7 @@ public class DateFormattersTests extends ESTestCase {
assertRoundupFormatter("epoch_second", "1234567890", 1234567890999L); assertRoundupFormatter("epoch_second", "1234567890", 1234567890999L);
// also check nanos of the epoch_millis formatter if it is rounded up to the nano second // also check nanos of the epoch_millis formatter if it is rounded up to the nano second
DateTimeFormatter epochSecondRoundupParser = ((JavaDateFormatter) DateFormatter.forPattern("8epoch_second")).getRoundupParser(); DateTimeFormatter epochSecondRoundupParser = ((JavaDateFormatter) DateFormatter.forPattern("8epoch_second")).getRoundupParser();
Instant epochSecondInstant = DateFormatters.toZonedDateTime(epochSecondRoundupParser.parse("1234567890")).toInstant(); Instant epochSecondInstant = DateFormatters.from(epochSecondRoundupParser.parse("1234567890")).toInstant();
assertThat(epochSecondInstant.getLong(ChronoField.NANO_OF_SECOND), is(999_999_999L)); assertThat(epochSecondInstant.getLong(ChronoField.NANO_OF_SECOND), is(999_999_999L));
assertRoundupFormatter("strict_date_optional_time||epoch_second", "2018-10-10T12:13:14.123Z", 1539173594123L); assertRoundupFormatter("strict_date_optional_time||epoch_second", "2018-10-10T12:13:14.123Z", 1539173594123L);
@ -189,7 +189,7 @@ public class DateFormattersTests extends ESTestCase {
JavaDateFormatter dateFormatter = (JavaDateFormatter) DateFormatter.forPattern(format); JavaDateFormatter dateFormatter = (JavaDateFormatter) DateFormatter.forPattern(format);
dateFormatter.parse(input); dateFormatter.parse(input);
DateTimeFormatter roundUpFormatter = dateFormatter.getRoundupParser(); DateTimeFormatter roundUpFormatter = dateFormatter.getRoundupParser();
long millis = DateFormatters.toZonedDateTime(roundUpFormatter.parse(input)).toInstant().toEpochMilli(); long millis = DateFormatters.from(roundUpFormatter.parse(input)).toInstant().toEpochMilli();
assertThat(millis, is(expectedMilliSeconds)); assertThat(millis, is(expectedMilliSeconds));
} }

@ -138,12 +138,12 @@ public class JavaDateMathParserTests extends ESTestCase {
// If a user only specifies times, then the date needs to always be 1970-01-01 regardless of rounding // If a user only specifies times, then the date needs to always be 1970-01-01 regardless of rounding
DateFormatter formatter = DateFormatters.forPattern("HH:mm:ss"); DateFormatter formatter = DateFormatters.forPattern("HH:mm:ss");
DateMathParser parser = formatter.toDateMathParser(); DateMathParser parser = formatter.toDateMathParser();
ZonedDateTime zonedDateTime = DateFormatters.toZonedDateTime(formatter.parse("04:52:20")); ZonedDateTime zonedDateTime = DateFormatters.from(formatter.parse("04:52:20"));
assertThat(zonedDateTime.getYear(), is(1970)); assertThat(zonedDateTime.getYear(), is(1970));
Instant millisStart = zonedDateTime.toInstant(); Instant millisStart = zonedDateTime.toInstant();
assertEquals(millisStart, parser.parse("04:52:20", () -> 0, false, (ZoneId) null)); assertEquals(millisStart, parser.parse("04:52:20", () -> 0, false, (ZoneId) null));
// due to rounding up, we have to add the number of milliseconds here manually // due to rounding up, we have to add the number of milliseconds here manually
long millisEnd = DateFormatters.toZonedDateTime(formatter.parse("04:52:20")).toInstant().toEpochMilli() + 999; long millisEnd = DateFormatters.from(formatter.parse("04:52:20")).toInstant().toEpochMilli() + 999;
assertEquals(millisEnd, parser.parse("04:52:20", () -> 0, true, (ZoneId) null).toEpochMilli()); assertEquals(millisEnd, parser.parse("04:52:20", () -> 0, true, (ZoneId) null).toEpochMilli());
} }

@ -113,9 +113,9 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
Directory dir = newDirectory(); Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null)); IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null));
long instant1 = long instant1 =
DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-12")).toInstant().toEpochMilli(); DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-12")).toInstant().toEpochMilli();
long instant2 = long instant2 =
DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2016-04-03")).toInstant().toEpochMilli(); DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2016-04-03")).toInstant().toEpochMilli();
Document doc = new Document(); Document doc = new Document();
LongPoint field = new LongPoint("my_date", instant1); LongPoint field = new LongPoint("my_date", instant1);
doc.add(field); doc.add(field);
@ -142,7 +142,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
public void testValueFormat() { public void testValueFormat() {
MappedFieldType ft = createDefaultFieldType(); MappedFieldType ft = createDefaultFieldType();
long instant = DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-12T14:10:55")) long instant = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-12T14:10:55"))
.toInstant().toEpochMilli(); .toInstant().toEpochMilli();
assertEquals("2015-10-12T14:10:55.000Z", assertEquals("2015-10-12T14:10:55.000Z",
@ -155,7 +155,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", false, null)); ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", false, null));
assertEquals(instant + 999, assertEquals(instant + 999,
ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", true, null)); ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", true, null));
long i = DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-13")).toInstant().toEpochMilli(); long i = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-13")).toInstant().toEpochMilli();
assertEquals(i - 1, ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12||/d", true, null)); assertEquals(i - 1, ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12||/d", true, null));
} }
@ -176,7 +176,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
MappedFieldType ft = createDefaultFieldType(); MappedFieldType ft = createDefaultFieldType();
ft.setName("field"); ft.setName("field");
String date = "2015-10-12T14:10:55"; String date = "2015-10-12T14:10:55";
long instant = DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date)).toInstant().toEpochMilli(); long instant = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date)).toInstant().toEpochMilli();
ft.setIndexOptions(IndexOptions.DOCS); ft.setIndexOptions(IndexOptions.DOCS);
Query expected = new IndexOrDocValuesQuery( Query expected = new IndexOrDocValuesQuery(
LongPoint.newRangeQuery("field", instant, instant + 999), LongPoint.newRangeQuery("field", instant, instant + 999),
@ -199,9 +199,9 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
ft.setName("field"); ft.setName("field");
String date1 = "2015-10-12T14:10:55"; String date1 = "2015-10-12T14:10:55";
String date2 = "2016-04-28T11:33:52"; String date2 = "2016-04-28T11:33:52";
long instant1 = DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date1)).toInstant().toEpochMilli(); long instant1 = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date1)).toInstant().toEpochMilli();
long instant2 = long instant2 =
DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date2)).toInstant().toEpochMilli() + 999; DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date2)).toInstant().toEpochMilli() + 999;
ft.setIndexOptions(IndexOptions.DOCS); ft.setIndexOptions(IndexOptions.DOCS);
Query expected = new IndexOrDocValuesQuery( Query expected = new IndexOrDocValuesQuery(
LongPoint.newRangeQuery("field", instant1, instant2), LongPoint.newRangeQuery("field", instant1, instant2),

@ -91,7 +91,7 @@ public class DateHistogramIT extends ESIntegTestCase {
} }
private ZonedDateTime date(String date) { private ZonedDateTime date(String date) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date)); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date));
} }
private static String format(ZonedDateTime date, String pattern) { private static String format(ZonedDateTime date, String pattern) {
@ -1191,10 +1191,10 @@ public class DateHistogramIT extends ESIntegTestCase {
List<IndexRequestBuilder> builders = new ArrayList<>(); List<IndexRequestBuilder> builders = new ArrayList<>();
DateFormatter formatter = DateFormatter.forPattern("date_optional_time"); DateFormatter formatter = DateFormatter.forPattern("date_optional_time");
builders.add(indexDoc(index, DateFormatters.toZonedDateTime(formatter.parse("2016-01-03T08:00:00.000Z")), 1)); builders.add(indexDoc(index, DateFormatters.from(formatter.parse("2016-01-03T08:00:00.000Z")), 1));
builders.add(indexDoc(index, DateFormatters.toZonedDateTime(formatter.parse("2016-01-03T08:00:00.000Z")), 2)); builders.add(indexDoc(index, DateFormatters.from(formatter.parse("2016-01-03T08:00:00.000Z")), 2));
builders.add(indexDoc(index, DateFormatters.toZonedDateTime(formatter.parse("2016-01-06T08:00:00.000Z")), 3)); builders.add(indexDoc(index, DateFormatters.from(formatter.parse("2016-01-06T08:00:00.000Z")), 3));
builders.add(indexDoc(index, DateFormatters.toZonedDateTime(formatter.parse("2016-01-06T08:00:00.000Z")), 4)); builders.add(indexDoc(index, DateFormatters.from(formatter.parse("2016-01-06T08:00:00.000Z")), 4));
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(index); ensureSearchable(index);

@ -54,7 +54,7 @@ public class DateHistogramOffsetIT extends ESIntegTestCase {
private static final DateFormatter FORMATTER = DateFormatter.forPattern(DATE_FORMAT); private static final DateFormatter FORMATTER = DateFormatter.forPattern(DATE_FORMAT);
private ZonedDateTime date(String date) { private ZonedDateTime date(String date) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date)); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date));
} }
@Before @Before

@ -1835,6 +1835,6 @@ public class CompositeAggregatorTests extends AggregatorTestCase {
} }
private static long asLong(String dateTime) { private static long asLong(String dateTime) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli(); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
} }
} }

@ -475,6 +475,6 @@ public class DateHistogramAggregatorTests extends AggregatorTestCase {
} }
private static long asLong(String dateTime) { private static long asLong(String dateTime) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli(); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
} }
} }

@ -143,14 +143,14 @@ public class DateHistogramTests extends BaseAggregationTestCase<DateHistogramAgg
try (Directory dir = newDirectory(); try (Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig())) { IndexWriter w = new IndexWriter(dir, newIndexWriterConfig())) {
long millis1 = DateFormatters.toZonedDateTime(format.parse("2018-03-11T11:55:00")).toInstant().toEpochMilli(); long millis1 = DateFormatters.from(format.parse("2018-03-11T11:55:00")).toInstant().toEpochMilli();
w.addDocument(documentForDate(DATE_FIELD_NAME, millis1)); w.addDocument(documentForDate(DATE_FIELD_NAME, millis1));
long millis2 = DateFormatters.toZonedDateTime(format.parse("2017-10-30T18:13:00")).toInstant().toEpochMilli(); long millis2 = DateFormatters.from(format.parse("2017-10-30T18:13:00")).toInstant().toEpochMilli();
w.addDocument(documentForDate(DATE_FIELD_NAME, millis2)); w.addDocument(documentForDate(DATE_FIELD_NAME, millis2));
try (IndexReader readerThatDoesntCross = DirectoryReader.open(w)) { try (IndexReader readerThatDoesntCross = DirectoryReader.open(w)) {
long millis3 = DateFormatters.toZonedDateTime(format.parse("2018-03-25T02:44:00")).toInstant().toEpochMilli(); long millis3 = DateFormatters.from(format.parse("2018-03-25T02:44:00")).toInstant().toEpochMilli();
w.addDocument(documentForDate(DATE_FIELD_NAME, millis3)); w.addDocument(documentForDate(DATE_FIELD_NAME, millis3));
try (IndexReader readerThatCrosses = DirectoryReader.open(w)) { try (IndexReader readerThatCrosses = DirectoryReader.open(w)) {

@ -140,6 +140,6 @@ public class AvgBucketAggregatorTests extends AggregatorTestCase {
} }
private static long asLong(String dateTime) { private static long asLong(String dateTime) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli(); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
} }
} }

@ -366,6 +366,6 @@ public class CumulativeSumAggregatorTests extends AggregatorTestCase {
} }
private static long asLong(String dateTime) { private static long asLong(String dateTime) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli(); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
} }
} }

@ -200,11 +200,11 @@ public class DateDerivativeIT extends ESIntegTestCase {
ZoneId timezone = ZoneId.of("CET"); ZoneId timezone = ZoneId.of("CET");
DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone); DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone);
// epoch millis: 1332547200000 // epoch millis: 1332547200000
addNTimes(1, IDX_DST_START, DateFormatters.toZonedDateTime(formatter.parse("2012-03-24T01:00:00")), builders); addNTimes(1, IDX_DST_START, DateFormatters.from(formatter.parse("2012-03-24T01:00:00")), builders);
// day with dst shift, only 23h long // day with dst shift, only 23h long
addNTimes(2, IDX_DST_START, DateFormatters.toZonedDateTime(formatter.parse("2012-03-25T01:00:00")), builders); addNTimes(2, IDX_DST_START, DateFormatters.from(formatter.parse("2012-03-25T01:00:00")), builders);
addNTimes(3, IDX_DST_START, DateFormatters.toZonedDateTime(formatter.parse("2012-03-26T01:00:00")), builders); addNTimes(3, IDX_DST_START, DateFormatters.from(formatter.parse("2012-03-26T01:00:00")), builders);
addNTimes(4, IDX_DST_START, DateFormatters.toZonedDateTime(formatter.parse("2012-03-27T01:00:00")), builders); addNTimes(4, IDX_DST_START, DateFormatters.from(formatter.parse("2012-03-27T01:00:00")), builders);
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(); ensureSearchable();
@ -251,11 +251,11 @@ public class DateDerivativeIT extends ESIntegTestCase {
List<IndexRequestBuilder> builders = new ArrayList<>(); List<IndexRequestBuilder> builders = new ArrayList<>();
DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone); DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone);
addNTimes(1, IDX_DST_END, DateFormatters.toZonedDateTime(formatter.parse("2012-10-27T01:00:00")), builders); addNTimes(1, IDX_DST_END, DateFormatters.from(formatter.parse("2012-10-27T01:00:00")), builders);
// day with dst shift -1h, 25h long // day with dst shift -1h, 25h long
addNTimes(2, IDX_DST_END, DateFormatters.toZonedDateTime(formatter.parse("2012-10-28T01:00:00")), builders); addNTimes(2, IDX_DST_END, DateFormatters.from(formatter.parse("2012-10-28T01:00:00")), builders);
addNTimes(3, IDX_DST_END, DateFormatters.toZonedDateTime(formatter.parse("2012-10-29T01:00:00")), builders); addNTimes(3, IDX_DST_END, DateFormatters.from(formatter.parse("2012-10-29T01:00:00")), builders);
addNTimes(4, IDX_DST_END, DateFormatters.toZonedDateTime(formatter.parse("2012-10-30T01:00:00")), builders); addNTimes(4, IDX_DST_END, DateFormatters.from(formatter.parse("2012-10-30T01:00:00")), builders);
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(); ensureSearchable();
@ -304,11 +304,11 @@ public class DateDerivativeIT extends ESIntegTestCase {
List<IndexRequestBuilder> builders = new ArrayList<>(); List<IndexRequestBuilder> builders = new ArrayList<>();
DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone); DateFormatter formatter = DateFormatter.forPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(timezone);
addNTimes(1, IDX_DST_KATHMANDU, DateFormatters.toZonedDateTime(formatter.parse("1985-12-31T22:30:00")), builders); addNTimes(1, IDX_DST_KATHMANDU, DateFormatters.from(formatter.parse("1985-12-31T22:30:00")), builders);
// the shift happens during the next bucket, which includes the 45min that do not start on the full hour // the shift happens during the next bucket, which includes the 45min that do not start on the full hour
addNTimes(2, IDX_DST_KATHMANDU, DateFormatters.toZonedDateTime(formatter.parse("1985-12-31T23:30:00")), builders); addNTimes(2, IDX_DST_KATHMANDU, DateFormatters.from(formatter.parse("1985-12-31T23:30:00")), builders);
addNTimes(3, IDX_DST_KATHMANDU, DateFormatters.toZonedDateTime(formatter.parse("1986-01-01T01:30:00")), builders); addNTimes(3, IDX_DST_KATHMANDU, DateFormatters.from(formatter.parse("1986-01-01T01:30:00")), builders);
addNTimes(4, IDX_DST_KATHMANDU, DateFormatters.toZonedDateTime(formatter.parse("1986-01-01T02:30:00")), builders); addNTimes(4, IDX_DST_KATHMANDU, DateFormatters.from(formatter.parse("1986-01-01T02:30:00")), builders);
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(); ensureSearchable();

@ -161,7 +161,7 @@ public class MovFnUnitTests extends AggregatorTestCase {
} }
private static long asLong(String dateTime) { private static long asLong(String dateTime) {
return DateFormatters.toZonedDateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli(); return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
} }
/** /**

@ -23,7 +23,7 @@ public class DateUtils {
// Try parsing using complete date/time format // Try parsing using complete date/time format
return dateTimeFormatter.parseMillis(date); return dateTimeFormatter.parseMillis(date);
} catch (ElasticsearchParseException | IllegalArgumentException ex) { } catch (ElasticsearchParseException | IllegalArgumentException ex) {
ZonedDateTime dateTime = DateFormatters.toZonedDateTime(dateOnlyFormatter.parse(date)); ZonedDateTime dateTime = DateFormatters.from(dateOnlyFormatter.parse(date));
dateTime.with(ChronoField.MILLI_OF_DAY, ChronoField.MILLI_OF_DAY.range().getMaximum()); dateTime.with(ChronoField.MILLI_OF_DAY, ChronoField.MILLI_OF_DAY.range().getMaximum());
return dateTime.toInstant().toEpochMilli(); return dateTime.toInstant().toEpochMilli();
} }
@ -35,7 +35,7 @@ public class DateUtils {
return dateTimeFormatter.parseMillis(date); return dateTimeFormatter.parseMillis(date);
} catch (ElasticsearchParseException | IllegalArgumentException ex) { } catch (ElasticsearchParseException | IllegalArgumentException ex) {
// Fall back to the date only format // Fall back to the date only format
return DateFormatters.toZonedDateTime(dateOnlyFormatter.parse(date)).toInstant().toEpochMilli(); return DateFormatters.from(dateOnlyFormatter.parse(date)).toInstant().toEpochMilli();
} }
} }
} }