Core: Abstract DateMathParser in an interface (#33905)

This commits creates a DateMathParser interface, which is already
implemented for both joda and java time. While currently the java time
DateMathParser is not used, this change will allow a followup which will
create a DateMathParser from a DateFormatter, so the caller does not
need to know the internals of the DateFormatter they have.
This commit is contained in:
Ryan Ernst 2018-09-26 07:56:25 -07:00 committed by GitHub
parent ff2bbdf765
commit 7800b4fa91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 476 additions and 293 deletions

View File

@ -27,10 +27,11 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNotFoundException;
@ -923,8 +924,9 @@ public class IndexNameExpressionResolver extends AbstractComponent {
}
DateTimeFormatter parser = dateFormatter.withZone(timeZone);
FormatDateTimeFormatter formatter = new FormatDateTimeFormatter(dateFormatterPattern, parser, Locale.ROOT);
DateMathParser dateMathParser = new DateMathParser(formatter);
long millis = dateMathParser.parse(mathExpression, context::getStartTime, false, timeZone);
DateMathParser dateMathParser = formatter.toDateMathParser();
long millis = dateMathParser.parse(mathExpression, context::getStartTime, false,
DateUtils.dateTimeZoneToZoneId(timeZone));
String time = formatter.printer().print(millis);
beforePlaceHolderSb.append(time);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.common.joda;
import org.elasticsearch.common.time.DateMathParser;
import org.joda.time.format.DateTimeFormatter;
import java.util.Locale;
@ -64,4 +65,8 @@ public class FormatDateTimeFormatter {
public Locale locale() {
return locale;
}
public DateMathParser toDateMathParser() {
return new JodaDateMathParser(this);
}
}

View File

@ -20,10 +20,13 @@
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.ZoneId;
import java.util.Objects;
import java.util.function.LongSupplier;
@ -34,23 +37,21 @@ import java.util.function.LongSupplier;
* is appended to a datetime with the following syntax:
* <code>||[+-/](\d+)?[yMwdhHms]</code>.
*/
public class DateMathParser {
public class JodaDateMathParser implements DateMathParser {
private final FormatDateTimeFormatter dateTimeFormatter;
public DateMathParser(FormatDateTimeFormatter dateTimeFormatter) {
public JodaDateMathParser(FormatDateTimeFormatter dateTimeFormatter) {
Objects.requireNonNull(dateTimeFormatter);
this.dateTimeFormatter = dateTimeFormatter;
}
public long parse(String text, LongSupplier now) {
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`.
public long parse(String text, LongSupplier now, boolean roundUp, DateTimeZone timeZone) {
@Override
public long 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")) {

View File

@ -19,56 +19,31 @@
package org.elasticsearch.common.time;
import org.elasticsearch.ElasticsearchParseException;
import org.joda.time.DateTimeZone;
import java.time.DateTimeException;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
import java.util.HashMap;
import java.util.Map;
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>.
* An abstraction over date math parsing to allow different implementation for joda and java time.
*/
public class DateMathParser {
public interface DateMathParser {
// base fields which should be used for default parsing, when we round up
private static final Map<TemporalField, Long> ROUND_UP_BASE_FIELDS = new HashMap<>(6);
{
ROUND_UP_BASE_FIELDS.put(ChronoField.MONTH_OF_YEAR, 1L);
ROUND_UP_BASE_FIELDS.put(ChronoField.DAY_OF_MONTH, 1L);
ROUND_UP_BASE_FIELDS.put(ChronoField.HOUR_OF_DAY, 23L);
ROUND_UP_BASE_FIELDS.put(ChronoField.MINUTE_OF_HOUR, 59L);
ROUND_UP_BASE_FIELDS.put(ChronoField.SECOND_OF_MINUTE, 59L);
ROUND_UP_BASE_FIELDS.put(ChronoField.MILLI_OF_SECOND, 999L);
/**
* Parse a date math expression without timzeone info and rounding down.
*/
default long parse(String text, LongSupplier now) {
return parse(text, now, false, (ZoneId) null);
}
private final DateFormatter formatter;
private final DateFormatter roundUpFormatter;
// 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`.
public DateMathParser(DateFormatter formatter) {
Objects.requireNonNull(formatter);
this.formatter = formatter;
this.roundUpFormatter = formatter.parseDefaulting(ROUND_UP_BASE_FIELDS);
}
public long parse(String text, LongSupplier now) {
return parse(text, now, false, null);
// exists for backcompat, do not use!
@Deprecated
default long parse(String text, LongSupplier now, boolean roundUp, DateTimeZone tz) {
return parse(text, now, roundUp, tz == null ? null : ZoneId.of(tz.getID()));
}
/**
@ -92,176 +67,8 @@ public class DateMathParser {
* @param text the input
* @param now a supplier to retrieve the current date in milliseconds, if needed for additions
* @param roundUp should the result be rounded up
* @param timeZone an optional timezone that should be applied before returning the milliseconds since the epoch
* @param tz an optional timezone that should be applied before returning the milliseconds since the epoch
* @return the parsed date in milliseconds since the epoch
*/
public long parse(String text, LongSupplier now, boolean roundUp, ZoneId timeZone) {
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 parseDateTime(text, timeZone, roundUp);
}
time = parseDateTime(text.substring(0, index), timeZone, false);
mathString = text.substring(index + 2);
}
return parseMath(mathString, time, roundUp, timeZone);
}
private long parseMath(final String mathString, final long time, final boolean roundUp,
ZoneId timeZone) throws ElasticsearchParseException {
if (timeZone == null) {
timeZone = ZoneOffset.UTC;
}
ZonedDateTime dateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(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))) {
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++);
switch (unit) {
case 'y':
if (round) {
dateTime = dateTime.withDayOfYear(1).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusYears(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusYears(1);
}
break;
case 'M':
if (round) {
dateTime = dateTime.withDayOfMonth(1).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusMonths(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusMonths(1);
}
break;
case 'w':
if (round) {
dateTime = dateTime.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusWeeks(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusWeeks(1);
}
break;
case 'd':
if (round) {
dateTime = dateTime.with(LocalTime.MIN);
} else {
dateTime = dateTime.plusDays(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusDays(1);
}
break;
case 'h':
case 'H':
if (round) {
dateTime = dateTime.withMinute(0).withSecond(0).withNano(0);
} else {
dateTime = dateTime.plusHours(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusHours(1);
}
break;
case 'm':
if (round) {
dateTime = dateTime.withSecond(0).withNano(0);
} else {
dateTime = dateTime.plusMinutes(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusMinutes(1);
}
break;
case 's':
if (round) {
dateTime = dateTime.withNano(0);
} else {
dateTime = dateTime.plusSeconds(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusSeconds(1);
}
break;
default:
throw new ElasticsearchParseException("unit [{}] not supported for date math [{}]", unit, mathString);
}
if (roundUp) {
dateTime = dateTime.minus(1, ChronoField.MILLI_OF_SECOND.getBaseUnit());
}
}
return dateTime.toInstant().toEpochMilli();
}
private long parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNoTime) {
DateFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter;
try {
if (timeZone == null) {
return DateFormatters.toZonedDateTime(formatter.parse(value)).toInstant().toEpochMilli();
} else {
TemporalAccessor accessor = formatter.parse(value);
ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor);
if (zoneId != null) {
timeZone = zoneId;
}
return DateFormatters.toZonedDateTime(accessor).withZoneSameLocal(timeZone).toInstant().toEpochMilli();
}
} catch (IllegalArgumentException | DateTimeException e) {
throw new ElasticsearchParseException("failed to parse date field [{}]: [{}]", e, value, e.getMessage());
}
}
long parse(String text, LongSupplier now, boolean roundUp, ZoneId tz);
}

View File

@ -0,0 +1,70 @@
/*
* 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.common.time;
import org.apache.logging.log4j.LogManager;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.joda.time.DateTimeZone;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class DateUtils {
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 DEPRECATION_LOGGER = new DeprecationLogger(LogManager.getLogger(DateFormatters.class));
// pkg private for tests
static final Map<String, String> DEPRECATED_SHORT_TIMEZONES;
static {
Map<String, String> tzs = new HashMap<>();
tzs.put("EST", "-05:00"); // eastern time without daylight savings
tzs.put("HST", "-10:00");
tzs.put("MST", "-07:00");
tzs.put("ROC", "Asia/Taipei");
tzs.put("Eire", "Europe/London");
DEPRECATED_SHORT_TIMEZONES = Collections.unmodifiableMap(tzs);
}
public static ZoneId dateTimeZoneToZoneId(DateTimeZone timeZone) {
if (timeZone == null) {
return null;
}
String deprecatedId = DEPRECATED_SHORT_TIMEZONES.get(timeZone.getID());
if (deprecatedId != null) {
DEPRECATION_LOGGER.deprecatedAndMaybeLog("timezone",
"Use of short timezone id " + timeZone.getID() + " is deprecated. Use " + deprecatedId + " instead");
return ZoneId.of(deprecatedId);
}
return ZoneId.of(timeZone.getID());
}
}

View File

@ -0,0 +1,240 @@
/*
* 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.common.time;
import org.elasticsearch.ElasticsearchParseException;
import java.time.DateTimeException;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
import java.util.HashMap;
import java.util.Map;
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 JavaDateMathParser implements DateMathParser {
// base fields which should be used for default parsing, when we round up
private static final Map<TemporalField, Long> ROUND_UP_BASE_FIELDS = new HashMap<>(6);
{
ROUND_UP_BASE_FIELDS.put(ChronoField.MONTH_OF_YEAR, 1L);
ROUND_UP_BASE_FIELDS.put(ChronoField.DAY_OF_MONTH, 1L);
ROUND_UP_BASE_FIELDS.put(ChronoField.HOUR_OF_DAY, 23L);
ROUND_UP_BASE_FIELDS.put(ChronoField.MINUTE_OF_HOUR, 59L);
ROUND_UP_BASE_FIELDS.put(ChronoField.SECOND_OF_MINUTE, 59L);
ROUND_UP_BASE_FIELDS.put(ChronoField.MILLI_OF_SECOND, 999L);
}
private final DateFormatter formatter;
private final DateFormatter roundUpFormatter;
public JavaDateMathParser(DateFormatter formatter) {
Objects.requireNonNull(formatter);
this.formatter = formatter;
this.roundUpFormatter = formatter.parseDefaulting(ROUND_UP_BASE_FIELDS);
}
@Override
public long parse(String text, LongSupplier now, boolean roundUp, ZoneId timeZone) {
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 parseDateTime(text, timeZone, roundUp);
}
time = parseDateTime(text.substring(0, index), timeZone, false);
mathString = text.substring(index + 2);
}
return parseMath(mathString, time, roundUp, timeZone);
}
private long parseMath(final String mathString, final long time, final boolean roundUp,
ZoneId timeZone) throws ElasticsearchParseException {
if (timeZone == null) {
timeZone = ZoneOffset.UTC;
}
ZonedDateTime dateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(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))) {
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++);
switch (unit) {
case 'y':
if (round) {
dateTime = dateTime.withDayOfYear(1).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusYears(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusYears(1);
}
break;
case 'M':
if (round) {
dateTime = dateTime.withDayOfMonth(1).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusMonths(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusMonths(1);
}
break;
case 'w':
if (round) {
dateTime = dateTime.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).with(LocalTime.MIN);
} else {
dateTime = dateTime.plusWeeks(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusWeeks(1);
}
break;
case 'd':
if (round) {
dateTime = dateTime.with(LocalTime.MIN);
} else {
dateTime = dateTime.plusDays(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusDays(1);
}
break;
case 'h':
case 'H':
if (round) {
dateTime = dateTime.withMinute(0).withSecond(0).withNano(0);
} else {
dateTime = dateTime.plusHours(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusHours(1);
}
break;
case 'm':
if (round) {
dateTime = dateTime.withSecond(0).withNano(0);
} else {
dateTime = dateTime.plusMinutes(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusMinutes(1);
}
break;
case 's':
if (round) {
dateTime = dateTime.withNano(0);
} else {
dateTime = dateTime.plusSeconds(sign * num);
}
if (roundUp) {
dateTime = dateTime.plusSeconds(1);
}
break;
default:
throw new ElasticsearchParseException("unit [{}] not supported for date math [{}]", unit, mathString);
}
if (roundUp) {
dateTime = dateTime.minus(1, ChronoField.MILLI_OF_SECOND.getBaseUnit());
}
}
return dateTime.toInstant().toEpochMilli();
}
private long parseDateTime(String value, ZoneId timeZone, boolean roundUpIfNoTime) {
DateFormatter formatter = roundUpIfNoTime ? this.roundUpFormatter : this.formatter;
try {
if (timeZone == null) {
return DateFormatters.toZonedDateTime(formatter.parse(value)).toInstant().toEpochMilli();
} else {
TemporalAccessor accessor = formatter.parse(value);
ZoneId zoneId = TemporalQueries.zone().queryFrom(accessor);
if (zoneId != null) {
timeZone = zoneId;
}
return DateFormatters.toZonedDateTime(accessor).withZoneSameLocal(timeZone).toInstant().toEpochMilli();
}
} catch (IllegalArgumentException | DateTimeException e) {
throw new ElasticsearchParseException("failed to parse date field [{}]: [{}]", e, value, e.getMessage());
}
}
}

View File

@ -36,10 +36,11 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.LocaleUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
@ -231,7 +232,7 @@ public class DateFieldMapper extends FieldMapper {
public void setDateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
checkIfFrozen();
this.dateTimeFormatter = dateTimeFormatter;
this.dateMathParser = new DateMathParser(dateTimeFormatter);
this.dateMathParser = dateTimeFormatter.toDateMathParser();
}
protected DateMathParser dateMathParser() {
@ -262,7 +263,7 @@ public class DateFieldMapper extends FieldMapper {
@Override
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, ShapeRelation relation,
@Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) {
@Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) {
failIfNotIndexed();
if (relation == ShapeRelation.DISJOINT) {
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() +
@ -296,8 +297,8 @@ public class DateFieldMapper extends FieldMapper {
return query;
}
public long parseToMilliseconds(Object value, boolean roundUp,
@Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser, QueryRewriteContext context) {
public long parseToMilliseconds(Object value, boolean roundUp, @Nullable DateTimeZone zone,
@Nullable DateMathParser forcedDateParser, QueryRewriteContext context) {
DateMathParser dateParser = dateMathParser();
if (forcedDateParser != null) {
dateParser = forcedDateParser;
@ -309,13 +310,13 @@ public class DateFieldMapper extends FieldMapper {
} else {
strValue = value.toString();
}
return dateParser.parse(strValue, context::nowInMillis, roundUp, zone);
return dateParser.parse(strValue, context::nowInMillis, roundUp, DateUtils.dateTimeZoneToZoneId(zone));
}
@Override
public Relation isFieldWithinQuery(IndexReader reader,
Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateParser, QueryRewriteContext context) throws IOException {
public Relation isFieldWithinQuery(IndexReader reader, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateParser,
QueryRewriteContext context) throws IOException {
if (dateParser == null) {
dateParser = this.dateMathParser;
}

View File

@ -38,7 +38,7 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.fielddata.IndexFieldData;

View File

@ -44,11 +44,12 @@ import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.LocaleUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -60,6 +61,7 @@ import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@ -257,7 +259,7 @@ public class RangeFieldMapper extends FieldMapper {
public void setDateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
checkIfFrozen();
this.dateTimeFormatter = dateTimeFormatter;
this.dateMathParser = new DateMathParser(dateTimeFormatter);
this.dateMathParser = dateTimeFormatter.toDateMathParser();
}
protected DateMathParser dateMathParser() {
@ -587,15 +589,16 @@ public class RangeFieldMapper extends FieldMapper {
public Query rangeQuery(String field, boolean hasDocValues, Object lowerTerm, Object upperTerm, boolean includeLower,
boolean includeUpper, ShapeRelation relation, @Nullable DateTimeZone timeZone,
@Nullable DateMathParser parser, QueryShardContext context) {
DateTimeZone zone = (timeZone == null) ? DateTimeZone.UTC : timeZone;
DateTimeZone zone = (timeZone == null) ? DateTimeZone.UTC : timeZone;
ZoneId zoneId = DateUtils.dateTimeZoneToZoneId(zone);
DateMathParser dateMathParser = (parser == null) ?
new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER) : parser;
DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser() : parser;
Long low = lowerTerm == null ? Long.MIN_VALUE :
dateMathParser.parse(lowerTerm instanceof BytesRef ? ((BytesRef) lowerTerm).utf8ToString() : lowerTerm.toString(),
context::nowInMillis, false, zone);
context::nowInMillis, false, zoneId);
Long high = upperTerm == null ? Long.MAX_VALUE :
dateMathParser.parse(upperTerm instanceof BytesRef ? ((BytesRef) upperTerm).utf8ToString() : upperTerm.toString(),
context::nowInMillis, false, zone);
context::nowInMillis, false, zoneId);
return super.rangeQuery(field, hasDocValues, low, high, includeLower, includeUpper, relation, zone,
dateMathParser, context);

View File

@ -21,7 +21,7 @@ package org.elasticsearch.index.mapper;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.index.query.QueryShardContext;
import org.joda.time.DateTimeZone;
@ -40,7 +40,7 @@ public abstract class SimpleMappedFieldType extends MappedFieldType {
@Override
public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,
ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) {
ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) {
if (relation == ShapeRelation.DISJOINT) {
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() +
"] does not support DISJOINT ranges");

View File

@ -29,10 +29,10 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
@ -302,7 +302,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
DateMathParser getForceDateParser() { // pkg private for testing
if (this.format != null) {
return new DateMathParser(this.format);
return this.format.toDateMathParser();
}
return null;
}

View File

@ -25,11 +25,12 @@ import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.time.DateUtils;
import org.joda.time.DateTimeZone;
import java.io.IOException;
@ -171,13 +172,14 @@ public interface DocValueFormat extends NamedWriteable {
public static final String NAME = "date_time";
final FormatDateTimeFormatter formatter;
// TODO: change this to ZoneId, but will require careful change to serialization
final DateTimeZone timeZone;
private final DateMathParser parser;
public DateTime(FormatDateTimeFormatter formatter, DateTimeZone timeZone) {
this.formatter = Objects.requireNonNull(formatter);
this.timeZone = Objects.requireNonNull(timeZone);
this.parser = new DateMathParser(formatter);
this.parser = formatter.toDateMathParser();
}
public DateTime(StreamInput in) throws IOException {
@ -212,7 +214,7 @@ public interface DocValueFormat extends NamedWriteable {
@Override
public long parseLong(String value, boolean roundUp, LongSupplier now) {
return parser.parse(value, now, roundUp, timeZone);
return parser.parse(value, now, roundUp, DateUtils.dateTimeZoneToZoneId(timeZone));
}
@Override

View File

@ -25,10 +25,10 @@ import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.DocIdSetIterator;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.rounding.DateTimeUnit;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -72,7 +72,7 @@ import static java.util.Collections.unmodifiableMap;
public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuilder<ValuesSource.Numeric, DateHistogramAggregationBuilder>
implements MultiBucketAggregationBuilder {
public static final String NAME = "date_histogram";
private static DateMathParser EPOCH_MILLIS_PARSER = new DateMathParser(Joda.forPattern("epoch_millis", Locale.ROOT));
private static DateMathParser EPOCH_MILLIS_PARSER = Joda.forPattern("epoch_millis", Locale.ROOT).toDateMathParser();
public static final Map<String, DateTimeUnit> DATE_FIELD_UNITS;

View File

@ -24,17 +24,17 @@ import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTimeZone;
import java.util.TimeZone;
import java.time.ZoneId;
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 DateMathParserTests extends ESTestCase {
public class JodaDateMathParserTests extends ESTestCase {
FormatDateTimeFormatter formatter = Joda.forPattern("dateOptionalTime||epoch_millis");
DateMathParser parser = new DateMathParser(formatter);
JodaDateMathParser parser = new JodaDateMathParser(formatter);
void assertDateMathEquals(String toTest, String expected) {
assertDateMathEquals(toTest, expected, 0, false, null);
@ -145,7 +145,7 @@ public class DateMathParserTests extends ESTestCase {
public void testNow() {
final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, null);
final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, (ZoneId) null);
assertDateMathEquals("now", "2014-11-18T14:27:32", now, false, null);
assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, false, null);
@ -159,13 +159,13 @@ public class DateMathParserTests extends ESTestCase {
public void testRoundingPreservesEpochAsBaseDate() {
// If a user only specifies times, then the date needs to always be 1970-01-01 regardless of rounding
FormatDateTimeFormatter formatter = Joda.forPattern("HH:mm:ss");
DateMathParser parser = new DateMathParser(formatter);
JodaDateMathParser parser = new JodaDateMathParser(formatter);
assertEquals(
this.formatter.parser().parseMillis("1970-01-01T04:52:20.000Z"),
parser.parse("04:52:20", () -> 0, false, null));
parser.parse("04:52:20", () -> 0, false, (ZoneId) null));
assertEquals(
this.formatter.parser().parseMillis("1970-01-01T04:52:20.999Z"),
parser.parse("04:52:20", () -> 0, true, null));
parser.parse("04:52:20", () -> 0, true, (ZoneId) null));
}
// Implicit rounding happening when parts of the date are not specified
@ -184,10 +184,10 @@ public class DateMathParserTests extends ESTestCase {
// implicit rounding with explicit timezone in the date format
FormatDateTimeFormatter formatter = Joda.forPattern("YYYY-MM-ddZ");
DateMathParser parser = new DateMathParser(formatter);
long time = parser.parse("2011-10-09+01:00", () -> 0, false, null);
JodaDateMathParser parser = new JodaDateMathParser(formatter);
long 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, null);
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);
}
@ -258,7 +258,7 @@ public class DateMathParserTests extends ESTestCase {
assertDateMathEquals("1418248078000||/m", "2014-12-10T21:47:00.000");
// also check other time units
DateMathParser parser = new DateMathParser(Joda.forPattern("epoch_second||dateOptionalTime"));
JodaDateMathParser parser = new JodaDateMathParser(Joda.forPattern("epoch_second||dateOptionalTime"));
long datetime = parser.parse("1418248078", () -> 0);
assertDateEquals(datetime, "1418248078", "2014-12-10T21:47:58.000");
@ -298,16 +298,16 @@ public class DateMathParserTests extends ESTestCase {
called.set(true);
return 42L;
};
parser.parse("2014-11-18T14:27:32", now, false, null);
parser.parse("2014-11-18T14:27:32", now, false, (ZoneId) null);
assertFalse(called.get());
parser.parse("now/d", now, false, null);
parser.parse("now/d", now, false, (ZoneId) null);
assertTrue(called.get());
}
public void testThatUnixTimestampMayNotHaveTimeZone() {
DateMathParser parser = new DateMathParser(Joda.forPattern("epoch_millis"));
JodaDateMathParser parser = new JodaDateMathParser(Joda.forPattern("epoch_millis"));
try {
parser.parse("1234567890123", () -> 42, false, DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")));
parser.parse("1234567890123", () -> 42, false, ZoneId.of("CET"));
fail("Expected ElasticsearchParseException");
} catch(ElasticsearchParseException e) {
assertThat(e.getMessage(), containsString("failed to parse date field"));

View File

@ -0,0 +1,54 @@
/*
* 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.common.time;
import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTimeZone;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
public class DateUtilsTests extends ESTestCase {
private static final Set<String> IGNORE = new HashSet<>(Arrays.asList(
"Eire", "Europe/Dublin" // dublin timezone in joda does not account for DST
));
public void testTimezoneIds() {
assertNull(DateUtils.dateTimeZoneToZoneId(null));
assertNull(DateUtils.zoneIdToDateTimeZone(null));
for (String jodaId : DateTimeZone.getAvailableIDs()) {
if (IGNORE.contains(jodaId)) continue;
DateTimeZone jodaTz = DateTimeZone.forID(jodaId);
ZoneId zoneId = DateUtils.dateTimeZoneToZoneId(jodaTz); // does not throw
long now = 0;
assertThat(jodaId, zoneId.getRules().getOffset(Instant.ofEpochMilli(now)).getTotalSeconds() * 1000,
equalTo(jodaTz.getOffset(now)));
if (DateUtils.DEPRECATED_SHORT_TIMEZONES.containsKey(jodaTz.getID())) {
assertWarnings("Use of short timezone id " + jodaId + " is deprecated. Use " + zoneId.getId() + " instead");
}
// roundtrip does not throw either
assertNotNull(DateUtils.zoneIdToDateTimeZone(zoneId));
}
}
}

View File

@ -33,10 +33,10 @@ import java.util.function.LongSupplier;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
public class DateMathParserTests extends ESTestCase {
public class JavaDateMathParserTests extends ESTestCase {
private final DateFormatter formatter = DateFormatters.forPattern("dateOptionalTime||epoch_millis");
private final DateMathParser parser = new DateMathParser(formatter);
private final JavaDateMathParser parser = new JavaDateMathParser(formatter);
public void testBasicDates() {
assertDateMathEquals("2014", "2014-01-01T00:00:00.000");
@ -125,7 +125,7 @@ public class DateMathParserTests extends ESTestCase {
}
public void testNow() {
final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, null);
final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, (ZoneId) null);
assertDateMathEquals("now", "2014-11-18T14:27:32", now, false, null);
assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, false, null);
@ -139,14 +139,14 @@ public class DateMathParserTests extends ESTestCase {
public void testRoundingPreservesEpochAsBaseDate() {
// 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");
DateMathParser parser = new DateMathParser(formatter);
JavaDateMathParser parser = new JavaDateMathParser(formatter);
ZonedDateTime zonedDateTime = DateFormatters.toZonedDateTime(formatter.parse("04:52:20"));
assertThat(zonedDateTime.getYear(), is(1970));
long millisStart = zonedDateTime.toInstant().toEpochMilli();
assertEquals(millisStart, parser.parse("04:52:20", () -> 0, false, 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
long millisEnd = DateFormatters.toZonedDateTime(formatter.parse("04:52:20")).toInstant().toEpochMilli() + 999;
assertEquals(millisEnd, parser.parse("04:52:20", () -> 0, true, null));
assertEquals(millisEnd, parser.parse("04:52:20", () -> 0, true, (ZoneId) null));
}
// Implicit rounding happening when parts of the date are not specified
@ -165,10 +165,10 @@ public class DateMathParserTests extends ESTestCase {
// implicit rounding with explicit timezone in the date format
DateFormatter formatter = DateFormatters.forPattern("yyyy-MM-ddXXX");
DateMathParser parser = new DateMathParser(formatter);
long time = parser.parse("2011-10-09+01:00", () -> 0, false, null);
JavaDateMathParser parser = new JavaDateMathParser(formatter);
long 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, null);
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);
}
@ -239,7 +239,7 @@ public class DateMathParserTests extends ESTestCase {
assertDateMathEquals("1418248078000||/m", "2014-12-10T21:47:00.000");
// also check other time units
DateMathParser parser = new DateMathParser(DateFormatters.forPattern("epoch_second||dateOptionalTime"));
JavaDateMathParser parser = new JavaDateMathParser(DateFormatters.forPattern("epoch_second||dateOptionalTime"));
long datetime = parser.parse("1418248078", () -> 0);
assertDateEquals(datetime, "1418248078", "2014-12-10T21:47:58.000");
@ -279,9 +279,9 @@ public class DateMathParserTests extends ESTestCase {
called.set(true);
return 42L;
};
parser.parse("2014-11-18T14:27:32", now, false, null);
parser.parse("2014-11-18T14:27:32", now, false, (ZoneId) null);
assertFalse(called.get());
parser.parse("now/d", now, false, null);
parser.parse("now/d", now, false, (ZoneId) null);
assertTrue(called.get());
}

View File

@ -29,12 +29,12 @@ import org.apache.lucene.index.MultiReader;
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
@ -121,7 +121,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
DirectoryReader reader = DirectoryReader.open(w);
DateFieldType ft = new DateFieldType();
ft.setName("my_date");
DateMathParser alternateFormat = new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
DateMathParser alternateFormat = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
doTestIsFieldWithinQuery(ft, reader, null, null);
doTestIsFieldWithinQuery(ft, reader, null, alternateFormat);
doTestIsFieldWithinQuery(ft, reader, DateTimeZone.UTC, null);

View File

@ -31,8 +31,8 @@ import org.apache.lucene.search.Query;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.internal.SearchContext;

View File

@ -23,9 +23,9 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
@ -1120,7 +1120,7 @@ public class DateHistogramIT extends ESIntegTestCase {
.setSettings(Settings.builder().put(indexSettings()).put("index.number_of_shards", 1).put("index.number_of_replicas", 0))
.execute().actionGet();
DateMathParser parser = new DateMathParser(Joda.getStrictStandardDateFormatter());
DateMathParser parser = Joda.getStrictStandardDateFormatter().toDateMathParser();
// we pick a random timezone offset of +12/-12 hours and insert two documents
// one at 00:00 in that time zone and one at 12:00

View File

@ -408,7 +408,7 @@ public abstract class ESTestCase extends LuceneTestCase {
}
try {
final List<String> actualWarnings = threadContext.getResponseHeaders().get("Warning");
assertNotNull(actualWarnings);
assertNotNull("no warnings, expected: " + Arrays.asList(expectedWarnings), actualWarnings);
final Set<String> actualWarningValues =
actualWarnings.stream().map(DeprecationLogger::extractWarningValueFromWarningHeader).collect(Collectors.toSet());
for (String msg : expectedWarnings) {

View File

@ -6,9 +6,9 @@
package org.elasticsearch.license.licensor;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -38,8 +38,7 @@ public class TestUtils {
private static final FormatDateTimeFormatter formatDateTimeFormatter =
Joda.forPattern("yyyy-MM-dd");
private static final DateMathParser dateMathParser =
new DateMathParser(formatDateTimeFormatter);
private static final DateMathParser dateMathParser = formatDateTimeFormatter.toDateMathParser();
private static final DateTimeFormatter dateTimeFormatter = formatDateTimeFormatter.printer();
public static String dumpLicense(License license) throws Exception {

View File

@ -16,7 +16,7 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
@ -88,7 +88,7 @@ public class GetOverallBucketsAction extends Action<GetOverallBucketsAction.Resp
}
static long parseDateOrThrow(String date, ParseField paramName, LongSupplier now) {
DateMathParser dateMathParser = new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
DateMathParser dateMathParser = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
try {
return dateMathParser.parse(date, now);

View File

@ -17,7 +17,7 @@ import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContent;
@ -153,7 +153,7 @@ public class StartDatafeedAction extends Action<AcknowledgedResponse> {
}
static long parseDateOrThrow(String date, ParseField paramName, LongSupplier now) {
DateMathParser dateMathParser = new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
DateMathParser dateMathParser = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
try {
return dateMathParser.parse(date, now);

View File

@ -9,8 +9,8 @@ import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
public class WatcherDateTimeUtils {
public static final FormatDateTimeFormatter dateTimeFormatter = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER;
public static final DateMathParser dateMathParser = new DateMathParser(dateTimeFormatter);
public static final DateMathParser dateMathParser = dateTimeFormatter.toDateMathParser();
private WatcherDateTimeUtils() {
}

View File

@ -10,10 +10,10 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -50,7 +50,7 @@ import static org.junit.Assert.assertThat;
public class TestUtils {
private static final FormatDateTimeFormatter formatDateTimeFormatter = Joda.forPattern("yyyy-MM-dd");
private static final DateMathParser dateMathParser = new DateMathParser(formatDateTimeFormatter);
private static final DateMathParser dateMathParser = formatDateTimeFormatter.toDateMathParser();
private static final DateTimeFormatter dateTimeFormatter = formatDateTimeFormatter.printer();
public static String dateMathString(String time, final long now) {

View File

@ -29,7 +29,6 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchResponseSections;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.unit.TimeValue;
@ -47,13 +46,13 @@ import org.elasticsearch.search.aggregations.AggregatorTestCase;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregation;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.xpack.core.indexing.IndexerState;
import org.elasticsearch.xpack.core.rollup.ConfigTestHelpers;
import org.elasticsearch.xpack.core.rollup.job.DateHistogramGroupConfig;
import org.elasticsearch.xpack.core.rollup.job.GroupConfig;
import org.elasticsearch.xpack.core.rollup.job.MetricConfig;
import org.elasticsearch.xpack.core.rollup.job.RollupJob;
import org.elasticsearch.xpack.core.rollup.job.RollupJobConfig;
import org.elasticsearch.xpack.core.indexing.IndexerState;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;
@ -601,7 +600,7 @@ public class RollupIndexerIndexingTests extends AggregatorTestCase {
RangeQueryBuilder range = (RangeQueryBuilder) request.source().query();
final DateTimeZone timeZone = range.timeZone() != null ? DateTimeZone.forID(range.timeZone()) : null;
Query query = timestampField.rangeQuery(range.from(), range.to(), range.includeLower(), range.includeUpper(),
null, timeZone, new DateMathParser(Joda.forPattern(range.format())), queryShardContext);
null, timeZone, Joda.forPattern(range.format()).toDateMathParser(), queryShardContext);
// extract composite agg
assertThat(request.source().aggregations().getAggregatorFactories().size(), equalTo(1));