diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java index a5f01f74ed70c..25403c84ec17d 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java @@ -36,8 +36,6 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.text.Text; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import java.io.ByteArrayInputStream; import java.io.EOFException; @@ -562,9 +560,9 @@ private List readArrayList() throws IOException { return list; } - private DateTime readDateTime() throws IOException { + private ZonedDateTime readDateTime() throws IOException { final String timeZoneId = readString(); - return new DateTime(readLong(), DateTimeZone.forID(timeZoneId)); + return ZonedDateTime.ofInstant(Instant.ofEpochMilli(readLong()), ZoneId.of(timeZoneId)); } private ZonedDateTime readZonedDateTime() throws IOException { @@ -611,18 +609,18 @@ public GeoPoint readGeoPoint() throws IOException { } /** - * Read a {@linkplain DateTimeZone}. + * Read a {@linkplain ZoneId}. */ - public DateTimeZone readTimeZone() throws IOException { - return DateTimeZone.forID(readString()); + public ZoneId readTimeZone() throws IOException { + return ZoneId.of(readString()); } /** - * Read an optional {@linkplain DateTimeZone}. + * Read an optional {@linkplain ZoneId}. */ - public DateTimeZone readOptionalTimeZone() throws IOException { + public ZoneId readOptionalTimeZone() throws IOException { if (readBoolean()) { - return DateTimeZone.forID(readString()); + return ZoneId.of(readString()); } return null; } diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java index 98a126e75e5c3..9060bb59c9617 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java @@ -35,7 +35,6 @@ import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.io.stream.Writeable.Writer; import org.elasticsearch.common.text.Text; -import org.joda.time.DateTimeZone; import org.joda.time.ReadableInstant; import java.io.EOFException; @@ -50,6 +49,7 @@ import java.nio.file.FileSystemLoopException; import java.nio.file.NoSuchFileException; import java.nio.file.NotDirectoryException; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Collections; import java.util.Date; @@ -625,7 +625,6 @@ public final void writeMap(final Map map, final Writer keyWriter writers.put(ZonedDateTime.class, (o, v) -> { o.writeByte((byte) 23); final ZonedDateTime zonedDateTime = (ZonedDateTime) v; - zonedDateTime.getZone().getId(); o.writeString(zonedDateTime.getZone().getId()); o.writeLong(zonedDateTime.toInstant().toEpochMilli()); }); @@ -650,6 +649,8 @@ public void writeGenericValue(@Nullable Object value) throws IOException { type = Object[].class; } else if (value instanceof Map) { type = Map.class; + } else if (value instanceof ZonedDateTime) { + type = ZonedDateTime.class; } else if (value instanceof ReadableInstant) { type = ReadableInstant.class; } else if (value instanceof BytesReference) { @@ -904,16 +905,16 @@ public void writeGeoPoint(GeoPoint geoPoint) throws IOException { } /** - * Write a {@linkplain DateTimeZone} to the stream. + * Write a {@linkplain ZoneId} to the stream. */ - public void writeTimeZone(DateTimeZone timeZone) throws IOException { - writeString(timeZone.getID()); + public void writeTimeZone(ZoneId timeZone) throws IOException { + writeString(timeZone.getId()); } /** - * Write an optional {@linkplain DateTimeZone} to the stream. + * Write an optional {@linkplain ZoneId} to the stream. */ - public void writeOptionalTimeZone(@Nullable DateTimeZone timeZone) throws IOException { + public void writeOptionalTimeZone(@Nullable ZoneId timeZone) throws IOException { if (timeZone == null) { writeBoolean(false); } else { diff --git a/server/src/main/java/org/elasticsearch/common/joda/DateMathParser.java b/server/src/main/java/org/elasticsearch/common/joda/DateMathParser.java index ba5531c813c12..2c1b7e6805b44 100644 --- a/server/src/main/java/org/elasticsearch/common/joda/DateMathParser.java +++ b/server/src/main/java/org/elasticsearch/common/joda/DateMathParser.java @@ -24,6 +24,8 @@ import org.joda.time.MutableDateTime; import org.joda.time.format.DateTimeFormatter; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.util.Objects; import java.util.function.LongSupplier; @@ -44,7 +46,20 @@ public DateMathParser(FormatDateTimeFormatter dateTimeFormatter) { } public long parse(String text, LongSupplier now) { - return parse(text, now, false, null); + return parse(text, now, false, (DateTimeZone) null); + } + + public long parse(String text, LongSupplier now, boolean roundUp, ZoneId timeZone) { + if (timeZone != null) { + // special handling of UTC, because the text interpretation of "Z" does not work for joda time + if (timeZone.equals(ZoneOffset.UTC)) { + return parse(text, now, roundUp, DateTimeZone.UTC); + } else { + return parse(text, now, roundUp, DateTimeZone.forID(timeZone.getId())); + } + } else { + return parse(text, now, roundUp, (DateTimeZone) null); + } } // Note: we take a callable here for the timestamp in order to be able to figure out diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java b/server/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java index 070510e13ff69..9ebbabeac2489 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java +++ b/server/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java @@ -28,16 +28,18 @@ import org.elasticsearch.common.text.Text; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; -import org.joda.time.DateTimeZone; -import org.joda.time.ReadableInstant; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; import java.io.Flushable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Path; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.SignStyle; +import java.time.temporal.ChronoField; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; @@ -86,7 +88,28 @@ public static XContentBuilder builder(XContent xContent, Set includes, S return new XContentBuilder(xContent, new BytesStreamOutput(), includes, excludes); } - public static final DateTimeFormatter DEFAULT_DATE_PRINTER = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC); + // this can be changed to DateTimeFormatter.ISO_OFFSET_DATE_TIME over time, when nanosecond precision is about to be used + // for now this emulates the same behaviour in format like the joda time date printer + public static final DateTimeFormatter DEFAULT_DATE_PRINTER = + new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD) + .appendLiteral('-') + .appendValue(ChronoField.MONTH_OF_YEAR, 2) + .appendLiteral('-') + .appendValue(ChronoField.DAY_OF_MONTH, 2) + .appendLiteral('T') + .appendValue(ChronoField.HOUR_OF_DAY, 2) + .appendLiteral(':') + .appendValue(ChronoField.MINUTE_OF_HOUR, 2) + .appendLiteral(':') + .appendValue(ChronoField.SECOND_OF_MINUTE, 2, 2, SignStyle.EXCEEDS_PAD) + .appendFraction(ChronoField.MILLI_OF_SECOND, 3, 3, true) + .parseLenient() + .appendOffsetId() + .parseStrict() + .toFormatter() + .withZone(ZoneOffset.UTC); private static final Map, Writer> WRITERS; static { @@ -667,24 +690,24 @@ public XContentBuilder value(Text value) throws IOException { // Date ////////////////////////////////// - public XContentBuilder field(String name, ReadableInstant value) throws IOException { + public XContentBuilder field(String name, Instant value) throws IOException { return field(name).value(value); } - public XContentBuilder field(String name, ReadableInstant value, DateTimeFormatter formatter) throws IOException { + public XContentBuilder field(String name, Instant value, DateTimeFormatter formatter) throws IOException { return field(name).value(value, formatter); } - public XContentBuilder value(ReadableInstant value) throws IOException { + public XContentBuilder value(Instant value) throws IOException { return value(value, DEFAULT_DATE_PRINTER); } - public XContentBuilder value(ReadableInstant value, DateTimeFormatter formatter) throws IOException { + public XContentBuilder value(Instant value, DateTimeFormatter formatter) throws IOException { if (value == null) { return nullValue(); } ensureFormatterNotNull(formatter); - return value(formatter.print(value)); + return value(formatter.format(value)); } public XContentBuilder field(String name, Date value) throws IOException { @@ -723,7 +746,7 @@ XContentBuilder value(Calendar value) throws IOException { XContentBuilder value(DateTimeFormatter formatter, long value) throws IOException { ensureFormatterNotNull(formatter); - return value(formatter.print(value)); + return value(formatter.format(Instant.ofEpochMilli(value))); } //////////////////////////////////////////////////////////////////////////// @@ -808,8 +831,8 @@ private void unknownValue(Object value, boolean ensureNoSelfReferences) throws I values((Object[]) value, ensureNoSelfReferences); } else if (value instanceof Calendar) { value((Calendar) value); - } else if (value instanceof ReadableInstant) { - value((ReadableInstant) value); + } else if (value instanceof Instant) { + value((Instant) value); } else if (value instanceof BytesReference) { value((BytesReference) value); } else if (value instanceof ToXContent) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java index 3b21a3bd7400b..d5b22a64171ea 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java @@ -52,6 +52,7 @@ import org.joda.time.DateTimeZone; import java.io.IOException; +import java.time.ZoneId; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -268,7 +269,7 @@ public Query termQuery(Object value, @Nullable QueryShardContext context) { @Override public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, ShapeRelation relation, - @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) { + @Nullable ZoneId timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) { failIfNotIndexed(); if (relation == ShapeRelation.DISJOINT) { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + @@ -303,7 +304,7 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower } public long parseToMilliseconds(Object value, boolean roundUp, - @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser, QueryRewriteContext context) { + @Nullable ZoneId zone, @Nullable DateMathParser forcedDateParser, QueryRewriteContext context) { DateMathParser dateParser = dateMathParser(); if (forcedDateParser != null) { dateParser = forcedDateParser; @@ -321,7 +322,7 @@ public long parseToMilliseconds(Object value, boolean roundUp, @Override public Relation isFieldWithinQuery(IndexReader reader, Object from, Object to, boolean includeLower, boolean includeUpper, - DateTimeZone timeZone, DateMathParser dateParser, QueryRewriteContext context) throws IOException { + ZoneId timeZone, DateMathParser dateParser, QueryRewriteContext context) throws IOException { if (dateParser == null) { dateParser = this.dateMathParser; } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java index 6eab90875345b..57d1dd64789b0 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java @@ -48,6 +48,7 @@ import org.joda.time.DateTimeZone; import java.io.IOException; +import java.time.ZoneId; import java.util.List; import java.util.Objects; @@ -355,7 +356,7 @@ public Query termsQuery(List values, @Nullable QueryShardContext context) { public Query rangeQuery( Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, - ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, + ShapeRelation relation, ZoneId timeZone, DateMathParser parser, QueryShardContext context) { throw new IllegalArgumentException("Field [" + name + "] of type [" + typeName() + "] does not support range queries"); } @@ -399,7 +400,7 @@ public Relation isFieldWithinQuery( IndexReader reader, Object from, Object to, boolean includeLower, boolean includeUpper, - DateTimeZone timeZone, DateMathParser dateMathParser, QueryRewriteContext context) throws IOException { + ZoneId timeZone, DateMathParser dateMathParser, QueryRewriteContext context) throws IOException { return Relation.INTERSECTS; } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java index 9a00ddebe83ba..7d3a912fae687 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java @@ -60,6 +60,7 @@ 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; @@ -313,7 +314,7 @@ public Query termQuery(Object value, QueryShardContext context) { @Override public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, - ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) { + ShapeRelation relation, ZoneId timeZone, DateMathParser parser, QueryShardContext context) { failIfNotIndexed(); return rangeType.rangeQuery(name(), hasDocValues(), lowerTerm, upperTerm, includeLower, includeUpper, relation, timeZone, parser, context); @@ -611,9 +612,11 @@ public Query dvRangeQuery(String field, QueryType queryType, Object from, Object @Override public Query rangeQuery(String field, boolean hasDocValues, Object lowerTerm, Object upperTerm, boolean includeLower, - boolean includeUpper, ShapeRelation relation, @Nullable DateTimeZone timeZone, + boolean includeUpper, ShapeRelation relation, @Nullable ZoneId timeZone, @Nullable DateMathParser parser, QueryShardContext context) { - DateTimeZone zone = (timeZone == null) ? DateTimeZone.UTC : timeZone; + // special treatment for Z timezone, which is not known by joda, but used by java time + DateTimeZone zone = + (timeZone == null || "Z".equals(timeZone.getId())) ? DateTimeZone.UTC : DateTimeZone.forID(timeZone.getId()); DateMathParser dateMathParser = (parser == null) ? new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER) : parser; Long low = lowerTerm == null ? Long.MIN_VALUE : @@ -623,7 +626,7 @@ public Query rangeQuery(String field, boolean hasDocValues, Object lowerTerm, Ob dateMathParser.parse(upperTerm instanceof BytesRef ? ((BytesRef) upperTerm).utf8ToString() : upperTerm.toString(), context::nowInMillis, false, zone); - return super.rangeQuery(field, hasDocValues, low, high, includeLower, includeUpper, relation, zone, + return super.rangeQuery(field, hasDocValues, low, high, includeLower, includeUpper, relation, timeZone, dateMathParser, context); } @Override @@ -934,7 +937,7 @@ public Object parse(Object value, boolean coerce) { return numberType.parse(value, coerce); } public Query rangeQuery(String field, boolean hasDocValues, Object from, Object to, boolean includeFrom, boolean includeTo, - ShapeRelation relation, @Nullable DateTimeZone timeZone, @Nullable DateMathParser dateMathParser, + ShapeRelation relation, @Nullable ZoneId timeZone, @Nullable DateMathParser dateMathParser, QueryShardContext context) { Object lower = from == null ? minValue() : parse(from, false); Object upper = to == null ? maxValue() : parse(to, false); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java index b91be82cd6b26..35bd548756153 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java @@ -25,6 +25,8 @@ import org.elasticsearch.index.query.QueryShardContext; import org.joda.time.DateTimeZone; +import java.time.ZoneId; + /** * {@link MappedFieldType} base impl for field types that are neither dates nor ranges. */ @@ -40,7 +42,7 @@ protected SimpleMappedFieldType(MappedFieldType ref) { @Override public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, - ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) { + ShapeRelation relation, ZoneId timeZone, DateMathParser parser, QueryShardContext context) { if (relation == ShapeRelation.DISJOINT) { throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support DISJOINT ranges"); @@ -52,7 +54,7 @@ public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includ } /** - * Same as {@link #rangeQuery(Object, Object, boolean, boolean, ShapeRelation, DateTimeZone, DateMathParser, QueryShardContext)} + * Same as {@link #rangeQuery(Object, Object, boolean, boolean, ShapeRelation, ZoneId, DateMathParser, QueryShardContext)} * but without the trouble of relations or date-specific options. */ protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, diff --git a/server/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java index 154060ec1a5b0..63b82c9065cc6 100644 --- a/server/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/QueryStringQueryBuilder.java @@ -37,11 +37,10 @@ import org.elasticsearch.index.query.support.QueryParsers; import org.elasticsearch.index.search.QueryParserHelper; import org.elasticsearch.index.search.QueryStringQueryParser; -import org.joda.time.DateTimeZone; import java.io.IOException; +import java.time.ZoneId; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; @@ -156,7 +155,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder i private Object to; - private DateTimeZone timeZone; + private ZoneId timeZone; private boolean includeLower = DEFAULT_INCLUDE_LOWER; @@ -272,7 +272,7 @@ public RangeQueryBuilder timeZone(String timeZone) { if (timeZone == null) { throw new IllegalArgumentException("timezone cannot be null"); } - this.timeZone = DateTimeZone.forID(timeZone); + this.timeZone = ZoneId.of(timeZone); return this; } @@ -280,10 +280,10 @@ public RangeQueryBuilder timeZone(String timeZone) { * In case of date field, gets the from/to fields timezone adjustment */ public String timeZone() { - return this.timeZone == null ? null : this.timeZone.getID(); + return this.timeZone == null ? null : this.timeZone.getId(); } - DateTimeZone getDateTimeZone() { // for testing + ZoneId getDateTimeZone() { // for testing return timeZone; } @@ -339,7 +339,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.field(INCLUDE_LOWER_FIELD.getPreferredName(), includeLower); builder.field(INCLUDE_UPPER_FIELD.getPreferredName(), includeUpper); if (timeZone != null) { - builder.field(TIME_ZONE_FIELD.getPreferredName(), timeZone.getID()); + builder.field(TIME_ZONE_FIELD.getPreferredName(), timeZone.getId()); } if (format != null) { builder.field(FORMAT_FIELD.getPreferredName(), format.format()); @@ -526,14 +526,14 @@ protected Query doToQuery(QueryShardContext context) throws IOException { @Override protected int doHashCode() { - String timeZoneId = timeZone == null ? null : timeZone.getID(); + String timeZoneId = timeZone == null ? null : timeZone.getId(); String formatString = format == null ? null : format.format(); return Objects.hash(fieldName, from, to, timeZoneId, includeLower, includeUpper, formatString); } @Override protected boolean doEquals(RangeQueryBuilder other) { - String timeZoneId = timeZone == null ? null : timeZone.getID(); + String timeZoneId = timeZone == null ? null : timeZone.getId(); String formatString = format == null ? null : format.format(); return Objects.equals(fieldName, other.fieldName) && Objects.equals(from, other.from) && diff --git a/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java b/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java index 5f453d49ab5cc..f7d8a6b7e810f 100644 --- a/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java +++ b/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java @@ -54,9 +54,9 @@ import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.support.QueryParsers; -import org.joda.time.DateTimeZone; import java.io.IOException; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -88,7 +88,7 @@ public class QueryStringQueryParser extends XQueryParser { private Analyzer forceQuoteAnalyzer; private String quoteFieldSuffix; private boolean analyzeWildcard; - private DateTimeZone timeZone; + private ZoneId timeZone; private Fuzziness fuzziness = Fuzziness.AUTO; private int fuzzyMaxExpansions = FuzzyQuery.defaultMaxExpansions; private MappedFieldType currentFieldType; @@ -219,7 +219,7 @@ public void setAnalyzeWildcard(boolean analyzeWildcard) { /** * @param timeZone Time Zone to be applied to any range query related to dates. */ - public void setTimeZone(DateTimeZone timeZone) { + public void setTimeZone(ZoneId timeZone) { this.timeZone = timeZone; } diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java index 9be087e0e5dbc..fdf82eb66e49c 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java @@ -21,9 +21,12 @@ import org.elasticsearch.Version; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.test.ESTestCase; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import static org.elasticsearch.test.VersionUtils.randomVersion; @@ -42,6 +45,8 @@ public void testHumanReadableSettings() { assertEquals(versionCreated.toString(), humanSettings.get(IndexMetaData.SETTING_VERSION_CREATED_STRING, null)); assertEquals(versionUpgraded.toString(), humanSettings.get(IndexMetaData.SETTING_VERSION_UPGRADED_STRING, null)); - assertEquals(new DateTime(created, DateTimeZone.UTC).toString(), humanSettings.get(IndexMetaData.SETTING_CREATION_DATE_STRING, null)); + String expectedDate = XContentBuilder.DEFAULT_DATE_PRINTER.format( + ZonedDateTime.ofInstant(Instant.ofEpochMilli(created), ZoneOffset.UTC)); + assertEquals(expectedDate, humanSettings.get(IndexMetaData.SETTING_CREATION_DATE_STRING, null)); } } diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexGraveyardTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexGraveyardTests.java index ef801dad28eb4..8ddd8aa5599cc 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexGraveyardTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexGraveyardTests.java @@ -31,6 +31,10 @@ import org.elasticsearch.test.ESTestCase; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -70,8 +74,10 @@ public void testXContent() throws IOException { builder.endObject(); if (graveyard.getTombstones().size() > 0) { // check that date properly printed - assertThat(Strings.toString(graveyard, false, true), - containsString(XContentBuilder.DEFAULT_DATE_PRINTER.print(graveyard.getTombstones().get(0).getDeleteDateInMillis()))); + long deleteDateInMillis = graveyard.getTombstones().get(0).getDeleteDateInMillis(); + String expectedDate = XContentBuilder.DEFAULT_DATE_PRINTER + .format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(deleteDateInMillis), ZoneOffset.UTC)); + assertThat(Strings.toString(graveyard, false, true), containsString(expectedDate)); } XContentParser parser = createParser(JsonXContent.jsonXContent, builder.bytes()); parser.nextToken(); // the beginning of the parser diff --git a/server/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java b/server/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java index 27656e9bc092d..f1c9bd0bee4a7 100644 --- a/server/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java +++ b/server/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java @@ -32,6 +32,7 @@ import java.io.EOFException; import java.io.IOException; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Base64; import java.util.Collections; @@ -297,8 +298,9 @@ public void testSimpleStreams() throws Exception { out.writeOptionalBytesReference(new BytesArray("test")); out.writeOptionalDouble(null); out.writeOptionalDouble(1.2); - out.writeTimeZone(DateTimeZone.forID("CET")); - out.writeOptionalTimeZone(DateTimeZone.getDefault()); + out.writeTimeZone(ZoneId.of("CET")); + // TODO not sure if system default is smart, maybe just pick some random + out.writeOptionalTimeZone(ZoneId.systemDefault()); out.writeOptionalTimeZone(null); final byte[] bytes = BytesReference.toBytes(out.bytes()); StreamInput in = StreamInput.wrap(BytesReference.toBytes(out.bytes())); @@ -327,8 +329,8 @@ public void testSimpleStreams() throws Exception { assertThat(in.readOptionalBytesReference(), equalTo(new BytesArray("test"))); assertNull(in.readOptionalDouble()); assertThat(in.readOptionalDouble(), closeTo(1.2, 0.0001)); - assertEquals(DateTimeZone.forID("CET"), in.readTimeZone()); - assertEquals(DateTimeZone.getDefault(), in.readOptionalTimeZone()); + assertEquals(ZoneId.of("CET"), in.readTimeZone()); + assertEquals(ZoneId.systemDefault(), in.readOptionalTimeZone()); assertNull(in.readOptionalTimeZone()); assertEquals(0, in.available()); in.close(); diff --git a/server/src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java b/server/src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java index ca9a6b3a1abf8..074feba65ded0 100644 --- a/server/src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java +++ b/server/src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java @@ -24,6 +24,7 @@ import org.elasticsearch.test.ESTestCase; import org.joda.time.DateTimeZone; +import java.util.Date; import java.util.TimeZone; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.LongSupplier; @@ -145,7 +146,7 @@ public void testMultipleAdjustments() { 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, (DateTimeZone) null); assertDateMathEquals("now", "2014-11-18T14:27:32", now, false, null); assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, false, null); @@ -162,10 +163,10 @@ public void testRoundingPreservesEpochAsBaseDate() { DateMathParser parser = new DateMathParser(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, (DateTimeZone) 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, (DateTimeZone) null)); } // Implicit rounding happening when parts of the date are not specified @@ -185,9 +186,9 @@ public void testImplicitRounding() { // 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); + long time = parser.parse("2011-10-09+01:00", () -> 0, false, (DateTimeZone) 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, (DateTimeZone) null); assertEquals(this.parser.parse("2011-10-09T23:59:59.999+01:00", () -> 0), time); } @@ -292,9 +293,9 @@ public void testOnlyCallsNowIfNecessary() { called.set(true); return 42L; }; - parser.parse("2014-11-18T14:27:32", now, false, null); + parser.parse("2014-11-18T14:27:32", now, false, (DateTimeZone) null); assertFalse(called.get()); - parser.parse("now/d", now, false, null); + parser.parse("now/d", now, false, (DateTimeZone) null); assertTrue(called.get()); } diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java b/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java index e368163a4e95c..a4485f328f1d8 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/BaseXContentTestCase.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParseException; - import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.Constants; import org.elasticsearch.ElasticsearchException; @@ -39,18 +38,17 @@ import org.elasticsearch.test.ESTestCase; import org.hamcrest.Matcher; import org.hamcrest.Matchers; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Instant; -import org.joda.time.ReadableInstant; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.file.Path; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -60,6 +58,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.TimeZone; import java.util.concurrent.TimeUnit; import static java.util.Collections.emptyMap; @@ -365,52 +364,56 @@ public void testText() throws Exception { } public void testReadableInstant() throws Exception { - assertResult("{'instant':null}", () -> builder().startObject().field("instant", (ReadableInstant) null).endObject()); - assertResult("{'instant':null}", () -> builder().startObject().field("instant").value((ReadableInstant) null).endObject()); + assertResult("{'zonedDateTime':null}", + () -> builder().startObject().field("zonedDateTime", (ZonedDateTime) null).endObject()); + assertResult("{'zonedDateTime':null}", + () -> builder().startObject().field("zonedDateTime").value((ZonedDateTime) null).endObject()); - final DateTime t1 = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC); + final Instant t1 = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant(); String expected = "{'t1':'2016-01-01T00:00:00.000Z'}"; assertResult(expected, () -> builder().startObject().field("t1", t1).endObject()); assertResult(expected, () -> builder().startObject().field("t1").value(t1).endObject()); - final DateTime t2 = new DateTime(2016, 12, 25, 7, 59, 42, 213, DateTimeZone.UTC); + final ZonedDateTime t2 = ZonedDateTime.of(2016, 12, 25, 7, 59, 42, 213000000, ZoneOffset.UTC); expected = "{'t2':'2016-12-25T07:59:42.213Z'}"; assertResult(expected, () -> builder().startObject().field("t2", t2).endObject()); assertResult(expected, () -> builder().startObject().field("t2").value(t2).endObject()); - final DateTimeFormatter formatter = randomFrom(ISODateTimeFormat.basicDate(), ISODateTimeFormat.dateTimeNoMillis()); - final DateTime t3 = DateTime.now(); + final DateTimeFormatter formatter = randomFrom(DateTimeFormatter.BASIC_ISO_DATE, DateTimeFormatter.ISO_OFFSET_DATE_TIME) + .withZone(ZoneOffset.UTC); + final Instant t3 = Instant.now(); - expected = "{'t3':'" + formatter.print(t3) + "'}"; + expected = "{'t3':'" + formatter.format(t3) + "'}"; assertResult(expected, () -> builder().startObject().field("t3", t3, formatter).endObject()); assertResult(expected, () -> builder().startObject().field("t3").value(t3, formatter).endObject()); - final DateTime t4 = new DateTime(randomDateTimeZone()); + ZoneId zone = randomZoneId(); + final Instant t4 = Instant.now().atZone(zone).toInstant(); - expected = "{'t4':'" + formatter.print(t4) + "'}"; + expected = "{'t4':'" + formatter.format(t4) + "'}"; assertResult(expected, () -> builder().startObject().field("t4", t4, formatter).endObject()); assertResult(expected, () -> builder().startObject().field("t4").value(t4, formatter).endObject()); long date = Math.abs(randomLong() % (2 * (long) 10e11)); // 1970-01-01T00:00:00Z - 2033-05-18T05:33:20.000+02:00 - final DateTime t5 = new DateTime(date, randomDateTimeZone()); + final Instant t5 = Instant.ofEpochMilli(date).atZone(randomZoneId()).toInstant(); - expected = "{'t5':'" + XContentBuilder.DEFAULT_DATE_PRINTER.print(t5) + "'}"; + expected = "{'t5':'" + XContentBuilder.DEFAULT_DATE_PRINTER.format(t5) + "'}"; assertResult(expected, () -> builder().startObject().field("t5", t5).endObject()); assertResult(expected, () -> builder().startObject().field("t5").value(t5).endObject()); - expected = "{'t5':'" + formatter.print(t5) + "'}"; + expected = "{'t5':'" + formatter.format(t5) + "'}"; assertResult(expected, () -> builder().startObject().field("t5", t5, formatter).endObject()); assertResult(expected, () -> builder().startObject().field("t5").value(t5, formatter).endObject()); - Instant i1 = new Instant(1451606400000L); // 2016-01-01T00:00:00.000Z + Instant i1 = Instant.ofEpochMilli(1451606400000L); // 2016-01-01T00:00:00.000Z expected = "{'i1':'2016-01-01T00:00:00.000Z'}"; assertResult(expected, () -> builder().startObject().field("i1", i1).endObject()); assertResult(expected, () -> builder().startObject().field("i1").value(i1).endObject()); - Instant i2 = new Instant(1482652782213L); // 2016-12-25T07:59:42.213Z - expected = "{'i2':'" + formatter.print(i2) + "'}"; + Instant i2 = Instant.ofEpochMilli(1482652782213L); // 2016-12-25T07:59:42.213Z + expected = "{'i2':'" + formatter.format(i2) + "'}"; assertResult(expected, () -> builder().startObject().field("i2", i2, formatter).endObject()); assertResult(expected, () -> builder().startObject().field("i2").value(i2, formatter).endObject()); @@ -422,18 +425,20 @@ public void testDate() throws Exception { assertResult("{'date':null}", () -> builder().startObject().field("date", (Date) null).endObject()); assertResult("{'date':null}", () -> builder().startObject().field("date").value((Date) null).endObject()); - final Date d1 = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC).toDate(); + + final Date d1 = new Date(ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli()); assertResult("{'d1':'2016-01-01T00:00:00.000Z'}", () -> builder().startObject().field("d1", d1).endObject()); assertResult("{'d1':'2016-01-01T00:00:00.000Z'}", () -> builder().startObject().field("d1").value(d1).endObject()); - final Date d2 = new DateTime(2016, 12, 25, 7, 59, 42, 213, DateTimeZone.UTC).toDate(); + final Date d2 = new Date(ZonedDateTime.of(2016, 12, 25, 7, 59, 42, 213000000, ZoneOffset.UTC).toInstant().toEpochMilli()); assertResult("{'d2':'2016-12-25T07:59:42.213Z'}", () -> builder().startObject().field("d2", d2).endObject()); assertResult("{'d2':'2016-12-25T07:59:42.213Z'}", () -> builder().startObject().field("d2").value(d2).endObject()); - final DateTimeFormatter formatter = randomFrom(ISODateTimeFormat.basicDate(), ISODateTimeFormat.dateTimeNoMillis()); - final Date d3 = DateTime.now().toDate(); + final DateTimeFormatter formatter = randomFrom(DateTimeFormatter.BASIC_ISO_DATE, DateTimeFormatter.ISO_OFFSET_DATE_TIME) + .withZone(ZoneOffset.UTC); + final Date d3 = new Date(Instant.now().toEpochMilli()); - String expected = "{'d3':'" + formatter.print(d3.getTime()) + "'}"; + String expected = "{'d3':'" + formatter.format(Instant.ofEpochMilli(d3.getTime())) + "'}"; assertResult(expected, () -> builder().startObject().field("d3", d3, formatter).endObject()); assertResult(expected, () -> builder().startObject().field("d3").value(d3, formatter).endObject()); @@ -443,7 +448,7 @@ public void testDate() throws Exception { } public void testDateField() throws Exception { - final Date d = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC).toDate(); + final Date d = new Date(ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli()); assertResult("{'date_in_millis':1451606400000}", () -> builder() .startObject() @@ -457,7 +462,9 @@ public void testDateField() throws Exception { } public void testCalendar() throws Exception { - Calendar calendar = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC).toCalendar(Locale.ROOT); + long millis = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 1000, ZoneOffset.UTC).toInstant().toEpochMilli(); + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC), Locale.ROOT); + calendar.setTimeInMillis(millis); assertResult("{'calendar':'2016-01-01T00:00:00.000Z'}", () -> builder() .startObject() .field("calendar") @@ -514,16 +521,20 @@ public void testObjects() throws Exception { objects.put(paths, new Object[]{PathUtils.get("a", "b", "c"), PathUtils.get("d", "e")}); final DateTimeFormatter formatter = XContentBuilder.DEFAULT_DATE_PRINTER; - final Date d1 = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC).toDate(); - final Date d2 = new DateTime(2015, 1, 1, 0, 0, DateTimeZone.UTC).toDate(); - objects.put("{'objects':['" + formatter.print(d1.getTime()) + "','" + formatter.print(d2.getTime()) + "']}", new Object[]{d1, d2}); - - final DateTime dt1 = DateTime.now(); - final DateTime dt2 = new DateTime(2016, 12, 25, 7, 59, 42, 213, DateTimeZone.UTC); - objects.put("{'objects':['" + formatter.print(dt1) + "','2016-12-25T07:59:42.213Z']}", new Object[]{dt1, dt2}); - - final Calendar c1 = new DateTime(2012, 7, 7, 10, 23, DateTimeZone.UTC).toCalendar(Locale.ROOT); - final Calendar c2 = new DateTime(2014, 11, 16, 19, 36, DateTimeZone.UTC).toCalendar(Locale.ROOT); + final ZonedDateTime d1 = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); + final ZonedDateTime d2 = ZonedDateTime.of(2015, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); + objects.put("{'objects':['" + formatter.format(d1) + "','" + formatter.format(d2) + "']}", + new Object[]{d1.toInstant(), d2.toInstant()}); + + final ZonedDateTime dt1 = ZonedDateTime.now(ZoneOffset.UTC); + final ZonedDateTime dt2 = ZonedDateTime.of(2016, 12, 25, 7, 59, 42, 213000000, ZoneOffset.UTC); + objects.put("{'objects':['" + formatter.format(dt1) + "','2016-12-25T07:59:42.213Z']}", + new Object[]{dt1.toInstant(), dt2.toInstant()}); + + final Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC), Locale.ROOT); + final Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC), Locale.ROOT); + c1.setTimeInMillis(ZonedDateTime.of(2012, 7, 7, 10, 23, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli()); + c2.setTimeInMillis(ZonedDateTime.of(2014, 11, 16, 19, 36, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli()); objects.put("{'objects':['2012-07-07T10:23:00.000Z','2014-11-16T19:36:00.000Z']}", new Object[]{c1, c2}); final ToXContent x1 = (builder, params) -> builder.startObject().field("f1", "v1").field("f2", 2).array("f3", 3, 4, 5).endObject(); @@ -562,13 +573,14 @@ public void testObject() throws Exception { object.put(path, PathUtils.get("a", "b", "c")); final DateTimeFormatter formatter = XContentBuilder.DEFAULT_DATE_PRINTER; - final Date d1 = new DateTime(2016, 1, 1, 0, 0, DateTimeZone.UTC).toDate(); - object.put("{'object':'" + formatter.print(d1.getTime()) + "'}", d1); + ZonedDateTime d1 = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); + object.put("{'object':'" + formatter.format(d1) + "'}", d1.toInstant()); - final DateTime d2 = DateTime.now(); - object.put("{'object':'" + formatter.print(d2) + "'}", d2); + final ZonedDateTime d2 = ZonedDateTime.now(ZoneOffset.UTC); + object.put("{'object':'" + formatter.format(d2) + "'}", d2.toInstant()); - final Calendar c1 = new DateTime(2010, 1, 1, 0, 0, DateTimeZone.UTC).toCalendar(Locale.ROOT); + final Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC), Locale.ROOT); + c1.setTimeInMillis(ZonedDateTime.of(2010, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli()); object.put("{'object':'2010-01-01T00:00:00.000Z'}", c1); final ToXContent x1 = (builder, params) -> builder.startObject().field("f1", "v1").field("f2", 2).array("f3", 3, 4, 5).endObject(); diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/builder/XContentBuilderTests.java b/server/src/test/java/org/elasticsearch/common/xcontent/builder/XContentBuilderTests.java index d3a5e44a89efd..8ee742d91cd13 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/builder/XContentBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/builder/XContentBuilderTests.java @@ -35,6 +35,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Path; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -174,9 +177,11 @@ public void testByteConversion() throws Exception { public void testDateTypesConversion() throws Exception { Date date = new Date(); - String expectedDate = XContentBuilder.DEFAULT_DATE_PRINTER.print(date.getTime()); + String expectedDate = XContentBuilder.DEFAULT_DATE_PRINTER + .format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneOffset.UTC)); Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ROOT); - String expectedCalendar = XContentBuilder.DEFAULT_DATE_PRINTER.print(calendar.getTimeInMillis()); + String expectedCalendar = XContentBuilder.DEFAULT_DATE_PRINTER + .format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(calendar.getTimeInMillis()), ZoneOffset.UTC)); XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); builder.startObject().field("date", date).endObject(); assertThat(builder.string(), equalTo("{\"date\":\"" + expectedDate + "\"}")); diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/yaml/YamlXContentTests.java b/server/src/test/java/org/elasticsearch/common/xcontent/yaml/YamlXContentTests.java index 3bfaa42188281..873a51ced879e 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/yaml/YamlXContentTests.java +++ b/server/src/test/java/org/elasticsearch/common/xcontent/yaml/YamlXContentTests.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - import org.elasticsearch.common.xcontent.BaseXContentTestCase; import org.elasticsearch.common.xcontent.XContentType; diff --git a/server/src/test/java/org/elasticsearch/explain/ExplainActionIT.java b/server/src/test/java/org/elasticsearch/explain/ExplainActionIT.java index 6d8e1a41c5b94..919af35fc3880 100644 --- a/server/src/test/java/org/elasticsearch/explain/ExplainActionIT.java +++ b/server/src/test/java/org/elasticsearch/explain/ExplainActionIT.java @@ -28,12 +28,12 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.test.ESIntegTestCase; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.ISODateTimeFormat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -249,8 +249,8 @@ public void testExplainWithFilteredAliasFetchSource() throws Exception { public void testExplainDateRangeInQueryString() { createIndex("test"); - String aMonthAgo = ISODateTimeFormat.yearMonthDay().print(new DateTime(DateTimeZone.UTC).minusMonths(1)); - String aMonthFromNow = ISODateTimeFormat.yearMonthDay().print(new DateTime(DateTimeZone.UTC).plusMonths(1)); + String aMonthAgo = DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC).minusMonths(1)); + String aMonthFromNow = DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC).plusMonths(1)); client().prepareIndex("test", "type", "1").setSource("past", aMonthAgo, "future", aMonthFromNow).get(); diff --git a/server/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java index 1b8cef1ab5355..129c01dea4e7b 100644 --- a/server/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/QueryStringQueryBuilderTests.java @@ -60,9 +60,10 @@ import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.test.AbstractQueryTestCase; import org.hamcrest.Matchers; -import org.joda.time.DateTimeZone; import java.io.IOException; +import java.time.DateTimeException; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -159,7 +160,7 @@ protected QueryStringQueryBuilder doCreateTestQueryBuilder() { queryStringQueryBuilder.useDisMax(randomBoolean()); } if (randomBoolean()) { - queryStringQueryBuilder.timeZone(randomDateTimeZone().getID()); + queryStringQueryBuilder.timeZone(randomZoneId()); } if (randomBoolean()) { queryStringQueryBuilder.autoGenerateSynonymsPhraseQuery(randomBoolean()); @@ -622,7 +623,7 @@ public void testTimezone() throws Exception { QueryBuilder queryBuilder = parseQuery(queryAsString); assertThat(queryBuilder, instanceOf(QueryStringQueryBuilder.class)); QueryStringQueryBuilder queryStringQueryBuilder = (QueryStringQueryBuilder) queryBuilder; - assertThat(queryStringQueryBuilder.timeZone(), equalTo(DateTimeZone.forID("Europe/Paris"))); + assertThat(queryStringQueryBuilder.timeZone(), equalTo(ZoneId.of("Europe/Paris"))); String invalidQueryAsString = "{\n" + " \"query_string\":{\n" + @@ -630,7 +631,7 @@ public void testTimezone() throws Exception { " \"query\":\"" + DATE_FIELD_NAME + ":[2012 TO 2014]\"\n" + " }\n" + "}"; - expectThrows(IllegalArgumentException.class, () -> parseQuery(invalidQueryAsString)); + expectThrows(DateTimeException.class, () -> parseQuery(invalidQueryAsString)); } public void testToQueryBooleanQueryMultipleBoosts() throws Exception { diff --git a/server/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java index 2230436b18ef4..8bd4d9415c8d7 100644 --- a/server/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/RangeQueryBuilderTests.java @@ -48,6 +48,7 @@ import org.joda.time.chrono.ISOChronology; import java.io.IOException; +import java.time.zone.ZoneRulesException; import java.util.HashMap; import java.util.Map; @@ -230,7 +231,7 @@ public void testIllegalArguments() { RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("test"); expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.timeZone(null)); - expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.timeZone("badID")); + expectThrows(ZoneRulesException.class, () -> rangeQueryBuilder.timeZone("badID")); expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.format(null)); expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.format("badFormat")); } diff --git a/server/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java b/server/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java index 71db66c7fb208..83fc6612a23fc 100644 --- a/server/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java +++ b/server/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java @@ -49,6 +49,9 @@ import org.joda.time.DateTimeZone; import org.joda.time.ReadableDateTime; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -817,7 +820,8 @@ public void testFieldsPulledFromFieldData() throws Exception { assertThat(searchResponse.getHits().getAt(0).getFields().get("long_field").getValue(), equalTo((Object) 4L)); assertThat(searchResponse.getHits().getAt(0).getFields().get("float_field").getValue(), equalTo((Object) 5.0)); assertThat(searchResponse.getHits().getAt(0).getFields().get("double_field").getValue(), equalTo((Object) 6.0d)); - assertThat(searchResponse.getHits().getAt(0).getFields().get("date_field").getValue(), equalTo(date)); + ZonedDateTime zonedDateTime = searchResponse.getHits().getAt(0).getFields().get("date_field").getValue(); + assertThat(zonedDateTime.toInstant().toEpochMilli(), equalTo(date.getMillis())); assertThat(searchResponse.getHits().getAt(0).getFields().get("boolean_field").getValue(), equalTo((Object) true)); assertThat(searchResponse.getHits().getAt(0).getFields().get("text_field").getValue(), equalTo("foo")); assertThat(searchResponse.getHits().getAt(0).getFields().get("keyword_field").getValue(), equalTo("foo")); diff --git a/server/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java b/server/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java index d6acdf11cb2ab..d1e21f04a930e 100644 --- a/server/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java +++ b/server/src/test/java/org/elasticsearch/search/functionscore/DecayFunctionScoreIT.java @@ -43,9 +43,9 @@ import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.InternalSettingsPlugin; import org.elasticsearch.test.VersionUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -562,27 +562,26 @@ public void testValueMissingLin() throws Exception { } public void testDateWithoutOrigin() throws Exception { - DateTime dt = new DateTime(DateTimeZone.UTC); - assertAcked(prepareCreate("test").addMapping( "type1", jsonBuilder().startObject().startObject("type1").startObject("properties").startObject("test").field("type", "text") .endObject().startObject("num1").field("type", "date").endObject().endObject().endObject().endObject())); - DateTime docDate = dt.minusDays(1); - String docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthOfYear()) + "-" + ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); + ZonedDateTime docDate = now.minusDays(1); + String docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthValue()) + "-" + String.format(Locale.ROOT, "%02d", docDate.getDayOfMonth()); client().index( indexRequest("test").type("type1").id("1") .source(jsonBuilder().startObject().field("test", "value").field("num1", docDateString).endObject())).actionGet(); - docDate = dt.minusDays(2); - docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthOfYear()) + "-" + docDate = now.minusDays(2); + docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthValue()) + "-" + String.format(Locale.ROOT, "%02d", docDate.getDayOfMonth()); client().index( indexRequest("test").type("type1").id("2") .source(jsonBuilder().startObject().field("test", "value").field("num1", docDateString).endObject())).actionGet(); - docDate = dt.minusDays(3); - docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthOfYear()) + "-" + docDate = now.minusDays(3); + docDateString = docDate.getYear() + "-" + String.format(Locale.ROOT, "%02d", docDate.getMonthValue()) + "-" + String.format(Locale.ROOT, "%02d", docDate.getDayOfMonth()); client().index( indexRequest("test").type("type1").id("3") diff --git a/server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java b/server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java index 4b56d2bc9e1fe..994dec70a33e5 100644 --- a/server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java +++ b/server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java @@ -53,6 +53,9 @@ import org.joda.time.format.ISODateTimeFormat; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Collections; import java.util.Random; @@ -507,14 +510,15 @@ public void testDateRangeInQueryStringWithTimeZone_7880() { "type", "past", "type=date" )); - DateTimeZone timeZone = randomDateTimeZone(); - String now = ISODateTimeFormat.dateTime().print(new DateTime(timeZone)); - logger.info(" --> Using time_zone [{}], now is [{}]", timeZone.getID(), now); + ZoneId timeZone = randomZoneId(); + String now = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(Instant.now().atZone(timeZone)); + + logger.info(" --> Using time_zone [{}], now is [{}]", timeZone.getId(), now); client().prepareIndex("test", "type", "1").setSource("past", now).get(); refresh(); SearchResponse searchResponse = client().prepareSearch().setQuery(queryStringQuery("past:[now-1m/m TO now+1m/m]") - .timeZone(timeZone.getID())).get(); + .timeZone(timeZone.getId())).get(); assertHitCount(searchResponse, 1L); } diff --git a/server/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java b/server/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java index 3c4666148d8f5..ca91fcd72e793 100644 --- a/server/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java +++ b/server/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java @@ -33,12 +33,14 @@ import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.Scope; import org.hamcrest.Matcher; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.ISODateTimeFormat; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.List; @@ -122,8 +124,8 @@ public void testExplainDateRangeInQueryString() { .put(indexSettings()) .put("index.number_of_shards", 1))); - String aMonthAgo = ISODateTimeFormat.yearMonthDay().print(new DateTime(DateTimeZone.UTC).minusMonths(1)); - String aMonthFromNow = ISODateTimeFormat.yearMonthDay().print(new DateTime(DateTimeZone.UTC).plusMonths(1)); + String aMonthAgo = DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC).minusMonths(1)); + String aMonthFromNow = DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC).plusMonths(1)); client().prepareIndex("test", "type", "1").setSource("past", aMonthAgo, "future", aMonthFromNow).get(); @@ -135,10 +137,12 @@ public void testExplainDateRangeInQueryString() { assertNoFailures(response); assertThat(response.getQueryExplanation().size(), equalTo(1)); assertThat(response.getQueryExplanation().get(0).getError(), nullValue()); - DateTime twoMonthsAgo = new DateTime(DateTimeZone.UTC).minusMonths(2).withTimeAtStartOfDay(); - DateTime now = new DateTime(DateTimeZone.UTC).plusDays(1).withTimeAtStartOfDay().minusMillis(1); - assertThat(response.getQueryExplanation().get(0).getExplanation(), - equalTo("past:[" + twoMonthsAgo.getMillis() + " TO " + now.getMillis() + "]")); + + long twoMonthsAgo = LocalDate.now(ZoneOffset.UTC).minusMonths(2).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(); + long now = LocalDate.now(ZoneOffset.UTC).plusDays(1).atStartOfDay().minus(1, ChronoUnit.MILLIS) + .toInstant(ZoneOffset.UTC).toEpochMilli(); + + assertThat(response.getQueryExplanation().get(0).getExplanation(), equalTo("past:[" + twoMonthsAgo + " TO " + now + "]")); assertThat(response.isValid(), equalTo(true)); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java index ccf32345f99ae..17875cdc3d817 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -121,6 +121,7 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -671,6 +672,15 @@ public static DateTimeZone randomDateTimeZone() { return DateTimeZone.forID(randomFrom(ids)); } + /** + * generate a random ZoneId from the ones available in java time + */ + public static ZoneId randomZoneId() { + List ids = new ArrayList<>(ZoneId.getAvailableZoneIds()); + Collections.sort(ids); + return ZoneId.of(randomFrom(ids)); + } + /** * helper to randomly perform on consumer with value */