diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8b35bc5c2eb7..6338f803838dc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -53,6 +53,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [Remote Store] Add support to reload repository metadata inplace ([#9569](https://github.com/opensearch-project/OpenSearch/pull/9569))
- [Metrics Framework] Add Metrics framework. ([#10241](https://github.com/opensearch-project/OpenSearch/pull/10241))
- Updating the separator for RemoteStoreLockManager since underscore is allowed in base64UUID url charset ([#10379](https://github.com/opensearch-project/OpenSearch/pull/10379))
+- Performance improvement for Datetime field caching ([#4558](https://github.com/opensearch-project/OpenSearch/issues/4558))
### Deprecated
diff --git a/distribution/src/config/opensearch.yml b/distribution/src/config/opensearch.yml
index 1d2cfe7eccae6..b7ab2e1c2309b 100644
--- a/distribution/src/config/opensearch.yml
+++ b/distribution/src/config/opensearch.yml
@@ -121,3 +121,9 @@ ${path.logs}
# index searcher threadpool.
#
#opensearch.experimental.feature.concurrent_segment_search.enabled: false
+#
+#
+# Gates the optimization of datetime formatters caching along with change in default datetime formatter
+# Once there is no observed impact on performance, this feature flag can be removed.
+#
+#opensearch.experimental.optimization.datetime_formatter_caching.enabled: false
diff --git a/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramIT.java b/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramIT.java
index 4ce8af3e0f081..895e24ba65132 100644
--- a/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramIT.java
+++ b/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramIT.java
@@ -124,7 +124,7 @@ protected Settings featureFlagSettings() {
}
private ZonedDateTime date(String date) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date));
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date));
}
private static String format(ZonedDateTime date, String pattern) {
@@ -1624,8 +1624,8 @@ public void testScriptCaching() throws Exception {
.setSettings(Settings.builder().put("requests.cache.enable", true).put("number_of_shards", 1).put("number_of_replicas", 1))
.get()
);
- String date = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.format(date(1, 1));
- String date2 = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.format(date(2, 1));
+ String date = DateFieldMapper.getDefaultDateTimeFormatter().format(date(1, 1));
+ String date2 = DateFieldMapper.getDefaultDateTimeFormatter().format(date(2, 1));
indexRandom(
true,
client().prepareIndex("cache_test_idx").setId("1").setSource("d", date),
diff --git a/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramOffsetIT.java b/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramOffsetIT.java
index 04115f69172da..d44071e1ef9c5 100644
--- a/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramOffsetIT.java
+++ b/server/src/internalClusterTest/java/org/opensearch/search/aggregations/bucket/DateHistogramOffsetIT.java
@@ -92,7 +92,7 @@ protected Settings featureFlagSettings() {
}
private ZonedDateTime date(String date) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date));
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date));
}
@Before
diff --git a/server/src/main/java/org/opensearch/common/joda/JodaDateFormatter.java b/server/src/main/java/org/opensearch/common/joda/JodaDateFormatter.java
index 12d48a0b362ce..bf25e5b1b3923 100644
--- a/server/src/main/java/org/opensearch/common/joda/JodaDateFormatter.java
+++ b/server/src/main/java/org/opensearch/common/joda/JodaDateFormatter.java
@@ -125,6 +125,11 @@ public String pattern() {
return pattern;
}
+ @Override
+ public String printPattern() {
+ throw new UnsupportedOperationException("JodaDateFormatter does not have a print pattern");
+ }
+
@Override
public Locale locale() {
return printer.getLocale();
diff --git a/server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java b/server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
index 90abc0a0765c1..387b0c9753574 100644
--- a/server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
+++ b/server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
@@ -39,7 +39,8 @@ protected FeatureFlagSettings(
FeatureFlags.EXTENSIONS_SETTING,
FeatureFlags.IDENTITY_SETTING,
FeatureFlags.CONCURRENT_SEGMENT_SEARCH_SETTING,
- FeatureFlags.TELEMETRY_SETTING
+ FeatureFlags.TELEMETRY_SETTING,
+ FeatureFlags.DATETIME_FORMATTER_CACHING_SETTING
)
)
);
diff --git a/server/src/main/java/org/opensearch/common/time/DateFormatter.java b/server/src/main/java/org/opensearch/common/time/DateFormatter.java
index d57fd441b9bf4..c98bd853dfced 100644
--- a/server/src/main/java/org/opensearch/common/time/DateFormatter.java
+++ b/server/src/main/java/org/opensearch/common/time/DateFormatter.java
@@ -126,6 +126,14 @@ default String formatJoda(DateTime dateTime) {
*/
String pattern();
+ /**
+ * A name based format for this formatter. Can be one of the registered formatters like epoch_millis
or
+ * a configured format like HH:mm:ss
+ *
+ * @return The name of this formatter
+ */
+ String printPattern();
+
/**
* Returns the configured locale of the date formatter
*
@@ -147,7 +155,7 @@ default String formatJoda(DateTime dateTime) {
*/
DateMathParser toDateMathParser();
- static DateFormatter forPattern(String input) {
+ static DateFormatter forPattern(String input, String printPattern, Boolean canCacheFormatter) {
if (Strings.hasLength(input) == false) {
throw new IllegalArgumentException("No date pattern provided");
@@ -158,7 +166,28 @@ static DateFormatter forPattern(String input) {
List patterns = splitCombinedPatterns(format);
List formatters = patterns.stream().map(DateFormatters::forPattern).collect(Collectors.toList());
- return JavaDateFormatter.combined(input, formatters);
+ DateFormatter printFormatter = formatters.get(0);
+ if (Strings.hasLength(printPattern)) {
+ String printFormat = strip8Prefix(printPattern);
+ try {
+ printFormatter = DateFormatters.forPattern(printFormat);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid print format: " + e.getMessage(), e);
+ }
+ }
+ return JavaDateFormatter.combined(input, formatters, printFormatter, canCacheFormatter);
+ }
+
+ static DateFormatter forPattern(String input) {
+ return forPattern(input, null, false);
+ }
+
+ static DateFormatter forPattern(String input, String printPattern) {
+ return forPattern(input, printPattern, false);
+ }
+
+ static DateFormatter forPattern(String input, Boolean canCacheFormatter) {
+ return forPattern(input, null, canCacheFormatter);
}
static String strip8Prefix(String input) {
diff --git a/server/src/main/java/org/opensearch/common/time/JavaDateFormatter.java b/server/src/main/java/org/opensearch/common/time/JavaDateFormatter.java
index 07013a3dc75f2..14191357fb8aa 100644
--- a/server/src/main/java/org/opensearch/common/time/JavaDateFormatter.java
+++ b/server/src/main/java/org/opensearch/common/time/JavaDateFormatter.java
@@ -32,6 +32,7 @@
package org.opensearch.common.time;
+import org.opensearch.common.util.FeatureFlags;
import org.opensearch.core.common.Strings;
import java.text.ParsePosition;
@@ -51,6 +52,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@@ -67,9 +69,12 @@ class JavaDateFormatter implements DateFormatter {
}
private final String format;
+ private final String printFormat;
private final DateTimeFormatter printer;
private final List parsers;
private final JavaDateFormatter roundupParser;
+ private final Boolean canCacheLastParsedFormatter;
+ private volatile DateTimeFormatter lastParsedformatter = null;
/**
* A round up formatter
@@ -93,8 +98,18 @@ JavaDateFormatter getRoundupParser() {
}
// named formatters use default roundUpParser
+ JavaDateFormatter(
+ String format,
+ String printFormat,
+ DateTimeFormatter printer,
+ Boolean canCacheLastParsedFormatter,
+ DateTimeFormatter... parsers
+ ) {
+ this(format, printFormat, printer, ROUND_UP_BASE_FIELDS, canCacheLastParsedFormatter, parsers);
+ }
+
JavaDateFormatter(String format, DateTimeFormatter printer, DateTimeFormatter... parsers) {
- this(format, printer, ROUND_UP_BASE_FIELDS, parsers);
+ this(format, format, printer, false, parsers);
}
private static final BiConsumer ROUND_UP_BASE_FIELDS = (builder, parser) -> {
@@ -111,8 +126,10 @@ JavaDateFormatter getRoundupParser() {
// subclasses override roundUpParser
JavaDateFormatter(
String format,
+ String printFormat,
DateTimeFormatter printer,
BiConsumer roundupParserConsumer,
+ Boolean canCacheLastParsedFormatter,
DateTimeFormatter... parsers
) {
if (printer == null) {
@@ -128,6 +145,8 @@ JavaDateFormatter getRoundupParser() {
}
this.printer = printer;
this.format = format;
+ this.printFormat = printFormat;
+ this.canCacheLastParsedFormatter = canCacheLastParsedFormatter;
if (parsers.length == 0) {
this.parsers = Collections.singletonList(printer);
@@ -138,6 +157,15 @@ JavaDateFormatter getRoundupParser() {
this.roundupParser = new RoundUpFormatter(format, roundUp);
}
+ JavaDateFormatter(
+ String format,
+ DateTimeFormatter printer,
+ BiConsumer roundupParserConsumer,
+ DateTimeFormatter... parsers
+ ) {
+ this(format, format, printer, roundupParserConsumer, false, parsers);
+ }
+
/**
* This is when the RoundUp Formatters are created. In further merges (with ||) it will only append them to a list.
* || is not expected to be provided as format when a RoundUp formatter is created. It will be splitted before in
@@ -164,36 +192,61 @@ private List createRoundUpParser(
return null;
}
- public static DateFormatter combined(String input, List formatters) {
+ public static DateFormatter combined(
+ String input,
+ List formatters,
+ DateFormatter printFormatter,
+ Boolean canCacheLastParsedFormatter
+ ) {
assert formatters.size() > 0;
+ assert printFormatter != null;
List parsers = new ArrayList<>(formatters.size());
List roundUpParsers = new ArrayList<>(formatters.size());
- DateTimeFormatter printer = null;
+ assert printFormatter instanceof JavaDateFormatter;
+ JavaDateFormatter javaPrintFormatter = (JavaDateFormatter) printFormatter;
+ DateTimeFormatter printer = javaPrintFormatter.getPrinter();
for (DateFormatter formatter : formatters) {
assert formatter instanceof JavaDateFormatter;
JavaDateFormatter javaDateFormatter = (JavaDateFormatter) formatter;
- if (printer == null) {
- printer = javaDateFormatter.getPrinter();
- }
parsers.addAll(javaDateFormatter.getParsers());
roundUpParsers.addAll(javaDateFormatter.getRoundupParser().getParsers());
}
- return new JavaDateFormatter(input, printer, roundUpParsers, parsers);
+ return new JavaDateFormatter(
+ input,
+ javaPrintFormatter.format,
+ printer,
+ roundUpParsers,
+ parsers,
+ canCacheLastParsedFormatter & FeatureFlags.isEnabled(FeatureFlags.DATETIME_FORMATTER_CACHING_SETTING)
+ ); // check if caching is enabled
}
private JavaDateFormatter(
String format,
+ String printFormat,
DateTimeFormatter printer,
List roundUpParsers,
- List parsers
+ List parsers,
+ Boolean canCacheLastParsedFormatter
) {
this.format = format;
+ this.printFormat = printFormat;
this.printer = printer;
this.roundupParser = roundUpParsers != null ? new RoundUpFormatter(format, roundUpParsers) : null;
this.parsers = parsers;
+ this.canCacheLastParsedFormatter = canCacheLastParsedFormatter;
+ }
+
+ private JavaDateFormatter(
+ String format,
+ DateTimeFormatter printer,
+ List roundUpParsers,
+ List parsers
+ ) {
+ this(format, format, printer, roundUpParsers, parsers, false);
}
JavaDateFormatter getRoundupParser() {
@@ -233,13 +286,23 @@ public TemporalAccessor parse(String input) {
*/
private TemporalAccessor doParse(String input) {
if (parsers.size() > 1) {
+ Object object = null;
+ if (canCacheLastParsedFormatter && lastParsedformatter != null) {
+ ParsePosition pos = new ParsePosition(0);
+ object = lastParsedformatter.toFormat().parseObject(input, pos);
+ if (parsingSucceeded(object, input, pos)) {
+ return (TemporalAccessor) object;
+ }
+ }
for (DateTimeFormatter formatter : parsers) {
ParsePosition pos = new ParsePosition(0);
- Object object = formatter.toFormat().parseObject(input, pos);
+ object = formatter.toFormat().parseObject(input, pos);
if (parsingSucceeded(object, input, pos)) {
+ lastParsedformatter = formatter;
return (TemporalAccessor) object;
}
}
+
throw new DateTimeParseException("Failed to parse with all enclosed parsers", input, 0);
}
return this.parsers.get(0).parse(input);
@@ -255,12 +318,14 @@ public DateFormatter withZone(ZoneId zoneId) {
if (zoneId.equals(zone())) {
return this;
}
- List parsers = this.parsers.stream().map(p -> p.withZone(zoneId)).collect(Collectors.toList());
+ List parsers = new CopyOnWriteArrayList<>(
+ this.parsers.stream().map(p -> p.withZone(zoneId)).collect(Collectors.toList())
+ );
List roundUpParsers = this.roundupParser.getParsers()
.stream()
.map(p -> p.withZone(zoneId))
.collect(Collectors.toList());
- return new JavaDateFormatter(format, printer.withZone(zoneId), roundUpParsers, parsers);
+ return new JavaDateFormatter(format, printFormat, printer.withZone(zoneId), roundUpParsers, parsers, canCacheLastParsedFormatter);
}
@Override
@@ -269,12 +334,14 @@ public DateFormatter withLocale(Locale locale) {
if (locale.equals(locale())) {
return this;
}
- List parsers = this.parsers.stream().map(p -> p.withLocale(locale)).collect(Collectors.toList());
+ List parsers = new CopyOnWriteArrayList<>(
+ this.parsers.stream().map(p -> p.withLocale(locale)).collect(Collectors.toList())
+ );
List roundUpParsers = this.roundupParser.getParsers()
.stream()
.map(p -> p.withLocale(locale))
.collect(Collectors.toList());
- return new JavaDateFormatter(format, printer.withLocale(locale), roundUpParsers, parsers);
+ return new JavaDateFormatter(format, printFormat, printer.withLocale(locale), roundUpParsers, parsers, canCacheLastParsedFormatter);
}
@Override
@@ -287,6 +354,11 @@ public String pattern() {
return format;
}
+ @Override
+ public String printPattern() {
+ return printFormat;
+ }
+
@Override
public Locale locale() {
return this.printer.getLocale();
diff --git a/server/src/main/java/org/opensearch/common/util/FeatureFlags.java b/server/src/main/java/org/opensearch/common/util/FeatureFlags.java
index b89d2d0549823..4e9b417e3433b 100644
--- a/server/src/main/java/org/opensearch/common/util/FeatureFlags.java
+++ b/server/src/main/java/org/opensearch/common/util/FeatureFlags.java
@@ -55,6 +55,11 @@ public class FeatureFlags {
*/
public static final String TELEMETRY = "opensearch.experimental.feature.telemetry.enabled";
+ /**
+ * Gates the optimization of datetime formatters caching along with change in default datetime formatter.
+ */
+ public static final String DATETIME_FORMATTER_CACHING = "opensearch.experimental.optimization.datetime_formatter_caching.enabled";
+
/**
* Should store the settings from opensearch.yml.
*/
@@ -83,6 +88,17 @@ public static boolean isEnabled(String featureFlagName) {
return settings != null && settings.getAsBoolean(featureFlagName, false);
}
+ public static boolean isEnabled(Setting featureFlag) {
+ if ("true".equalsIgnoreCase(System.getProperty(featureFlag.getKey()))) {
+ // TODO: Remove the if condition once FeatureFlags are only supported via opensearch.yml
+ return true;
+ } else if (settings != null) {
+ return featureFlag.get(settings);
+ } else {
+ return featureFlag.getDefault(Settings.EMPTY);
+ }
+ }
+
public static final Setting SEGMENT_REPLICATION_EXPERIMENTAL_SETTING = Setting.boolSetting(
SEGMENT_REPLICATION_EXPERIMENTAL,
false,
@@ -100,4 +116,10 @@ public static boolean isEnabled(String featureFlagName) {
false,
Property.NodeScope
);
+
+ public static final Setting DATETIME_FORMATTER_CACHING_SETTING = Setting.boolSetting(
+ DATETIME_FORMATTER_CACHING,
+ true,
+ Property.NodeScope
+ );
}
diff --git a/server/src/main/java/org/opensearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/DateFieldMapper.java
index d9b26cce3735c..4c374f02bba52 100644
--- a/server/src/main/java/org/opensearch/index/mapper/DateFieldMapper.java
+++ b/server/src/main/java/org/opensearch/index/mapper/DateFieldMapper.java
@@ -53,6 +53,7 @@
import org.opensearch.common.time.DateMathParser;
import org.opensearch.common.time.DateUtils;
import org.opensearch.common.unit.TimeValue;
+import org.opensearch.common.util.FeatureFlags;
import org.opensearch.common.util.LocaleUtils;
import org.opensearch.index.fielddata.IndexFieldData;
import org.opensearch.index.fielddata.IndexNumericFieldData.NumericType;
@@ -92,7 +93,21 @@ public final class DateFieldMapper extends ParametrizedFieldMapper {
public static final String CONTENT_TYPE = "date";
public static final String DATE_NANOS_CONTENT_TYPE = "date_nanos";
- public static final DateFormatter DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time||epoch_millis");
+ @Deprecated
+ public static final DateFormatter LEGACY_DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern(
+ // TODO remove in 3.0 after backporting
+ "strict_date_optional_time||epoch_millis"
+ );
+ public static final DateFormatter DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern(
+ "strict_date_time_no_millis||strict_date_optional_time||epoch_millis",
+ "strict_date_optional_time"
+ );
+
+ public static DateFormatter getDefaultDateTimeFormatter() {
+ return FeatureFlags.isEnabled(FeatureFlags.DATETIME_FORMATTER_CACHING_SETTING)
+ ? DEFAULT_DATE_TIME_FORMATTER
+ : LEGACY_DEFAULT_DATE_TIME_FORMATTER;
+ }
/**
* Resolution of the date time
@@ -224,8 +239,14 @@ public static class Builder extends ParametrizedFieldMapper.Builder {
"format",
false,
m -> toType(m).format,
- DEFAULT_DATE_TIME_FORMATTER.pattern()
+ getDefaultDateTimeFormatter().pattern()
);
+ private final Parameter printFormat = Parameter.stringParam(
+ "print_format",
+ false,
+ m -> toType(m).printFormat,
+ getDefaultDateTimeFormatter().printPattern()
+ ).acceptsNull();
private final Parameter locale = new Parameter<>(
"locale",
false,
@@ -254,6 +275,7 @@ public Builder(
this.ignoreMalformed = Parameter.boolParam("ignore_malformed", true, m -> toType(m).ignoreMalformed, ignoreMalformedByDefault);
if (dateFormatter != null) {
this.format.setValue(dateFormatter.pattern());
+ this.printFormat.setValue(dateFormatter.printPattern());
this.locale.setValue(dateFormatter.locale());
}
}
@@ -262,9 +284,13 @@ private DateFormatter buildFormatter() {
try {
if (Joda.isJodaPattern(indexCreatedVersion, format.getValue())) {
return Joda.forPattern(format.getValue()).withLocale(locale.getValue());
- } else {
- return DateFormatter.forPattern(format.getValue()).withLocale(locale.getValue());
}
+ if (format.isConfigured() && !printFormat.isConfigured()) {
+ return DateFormatter.forPattern(format.getValue(), null, !format.isConfigured()).withLocale(locale.getValue());
+ }
+ return DateFormatter.forPattern(format.getValue(), printFormat.getValue(), !format.isConfigured())
+ .withLocale(locale.getValue());
+
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Error parsing [format] on field [" + name() + "]: " + e.getMessage(), e);
}
@@ -272,7 +298,7 @@ private DateFormatter buildFormatter() {
@Override
protected List> getParameters() {
- return Arrays.asList(index, docValues, store, format, locale, nullValue, ignoreMalformed, boost, meta);
+ return Arrays.asList(index, docValues, store, format, printFormat, locale, nullValue, ignoreMalformed, boost, meta);
}
private Long parseNullValue(DateFieldType fieldType) {
@@ -351,7 +377,7 @@ public DateFieldType(
}
public DateFieldType(String name) {
- this(name, true, false, true, DEFAULT_DATE_TIME_FORMATTER, Resolution.MILLISECONDS, null, Collections.emptyMap());
+ this(name, true, false, true, getDefaultDateTimeFormatter(), Resolution.MILLISECONDS, null, Collections.emptyMap());
}
public DateFieldType(String name, DateFormatter dateFormatter) {
@@ -359,7 +385,7 @@ public DateFieldType(String name, DateFormatter dateFormatter) {
}
public DateFieldType(String name, Resolution resolution) {
- this(name, true, false, true, DEFAULT_DATE_TIME_FORMATTER, resolution, null, Collections.emptyMap());
+ this(name, true, false, true, getDefaultDateTimeFormatter(), resolution, null, Collections.emptyMap());
}
public DateFieldType(String name, Resolution resolution, DateFormatter dateFormatter) {
@@ -615,6 +641,7 @@ public DocValueFormat docValueFormat(@Nullable String format, ZoneId timeZone) {
private final boolean hasDocValues;
private final Locale locale;
private final String format;
+ private final String printFormat;
private final boolean ignoreMalformed;
private final Long nullValue;
private final String nullValueAsString;
@@ -638,6 +665,7 @@ private DateFieldMapper(
this.hasDocValues = builder.docValues.getValue();
this.locale = builder.locale.getValue();
this.format = builder.format.getValue();
+ this.printFormat = builder.printFormat.getValue();
this.ignoreMalformed = builder.ignoreMalformed.getValue();
this.nullValueAsString = builder.nullValue.getValue();
this.nullValue = nullValue;
diff --git a/server/src/main/java/org/opensearch/index/mapper/RangeFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/RangeFieldMapper.java
index 3723e469d3049..539a4d048246c 100644
--- a/server/src/main/java/org/opensearch/index/mapper/RangeFieldMapper.java
+++ b/server/src/main/java/org/opensearch/index/mapper/RangeFieldMapper.java
@@ -96,7 +96,7 @@ public class RangeFieldMapper extends ParametrizedFieldMapper {
*/
public static class Defaults {
public static final Explicit COERCE = new Explicit<>(true, false);
- public static final DateFormatter DATE_FORMATTER = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER;
+ public static final DateFormatter DATE_FORMATTER = DateFieldMapper.getDefaultDateTimeFormatter();
}
// this is private since it has a different default
diff --git a/server/src/main/java/org/opensearch/index/mapper/RangeType.java b/server/src/main/java/org/opensearch/index/mapper/RangeType.java
index c8cd317779c7c..7e29fd417845b 100644
--- a/server/src/main/java/org/opensearch/index/mapper/RangeType.java
+++ b/server/src/main/java/org/opensearch/index/mapper/RangeType.java
@@ -313,7 +313,7 @@ public Query rangeQuery(
) {
ZoneId zone = (timeZone == null) ? ZoneOffset.UTC : timeZone;
- DateMathParser dateMathParser = (parser == null) ? DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser() : parser;
+ DateMathParser dateMathParser = (parser == null) ? DateFieldMapper.getDefaultDateTimeFormatter().toDateMathParser() : parser;
boolean roundUp = includeLower == false; // using "gt" should round lower bound up
Long low = lowerTerm == null
? minValue()
diff --git a/server/src/main/java/org/opensearch/index/mapper/RootObjectMapper.java b/server/src/main/java/org/opensearch/index/mapper/RootObjectMapper.java
index f9a7d7c72565e..4f4a5b55dd029 100644
--- a/server/src/main/java/org/opensearch/index/mapper/RootObjectMapper.java
+++ b/server/src/main/java/org/opensearch/index/mapper/RootObjectMapper.java
@@ -73,7 +73,7 @@ public class RootObjectMapper extends ObjectMapper {
*/
public static class Defaults {
public static final DateFormatter[] DYNAMIC_DATE_TIME_FORMATTERS = new DateFormatter[] {
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
DateFormatter.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis") };
public static final boolean DATE_DETECTION = true;
public static final boolean NUMERIC_DETECTION = false;
diff --git a/server/src/main/java/org/opensearch/script/ScoreScriptUtils.java b/server/src/main/java/org/opensearch/script/ScoreScriptUtils.java
index 141e4e21b647a..51f3a64846f4d 100644
--- a/server/src/main/java/org/opensearch/script/ScoreScriptUtils.java
+++ b/server/src/main/java/org/opensearch/script/ScoreScriptUtils.java
@@ -342,11 +342,14 @@ public double decayNumericGauss(double docValue) {
/**
* Limitations: since script functions don't have access to DateFieldMapper,
* decay functions on dates are limited to dates in the default format and default time zone,
+ * Further, since script module gets initialized before the featureflags are loaded,
+ * we cannot use the feature flag to gate the usage of the new default date format.
* Also, using calculations with now
are not allowed.
*
*/
private static final ZoneId defaultZoneId = ZoneId.of("UTC");
- private static final DateMathParser dateParser = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
+ // ToDo: use new default date formatter once feature flag is removed
+ private static final DateMathParser dateParser = DateFieldMapper.LEGACY_DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
/**
* Linear date decay
diff --git a/server/src/main/java/org/opensearch/search/DocValueFormat.java b/server/src/main/java/org/opensearch/search/DocValueFormat.java
index febb270ea917c..b8daa206fa0e9 100644
--- a/server/src/main/java/org/opensearch/search/DocValueFormat.java
+++ b/server/src/main/java/org/opensearch/search/DocValueFormat.java
@@ -35,6 +35,7 @@
import org.apache.lucene.document.InetAddressPoint;
import org.apache.lucene.util.BytesRef;
import org.opensearch.LegacyESVersion;
+import org.opensearch.Version;
import org.opensearch.common.Numbers;
import org.opensearch.common.joda.Joda;
import org.opensearch.common.joda.JodaDateFormatter;
@@ -247,7 +248,10 @@ public DateTime(DateFormatter formatter, ZoneId timeZone, DateFieldMapper.Resolu
public DateTime(StreamInput in) throws IOException {
String datePattern = in.readString();
-
+ String printPattern = null;
+ if (in.getVersion().onOrAfter(Version.V_2_11_0)) {
+ printPattern = in.readOptionalString();
+ }
String zoneId = in.readString();
if (in.getVersion().before(LegacyESVersion.V_7_0_0)) {
this.timeZone = DateUtils.of(zoneId);
@@ -271,7 +275,7 @@ public DateTime(StreamInput in) throws IOException {
*/
isJoda = Joda.isJodaPattern(in.getVersion(), datePattern);
}
- this.formatter = isJoda ? Joda.forPattern(datePattern) : DateFormatter.forPattern(datePattern);
+ this.formatter = isJoda ? Joda.forPattern(datePattern) : DateFormatter.forPattern(datePattern, printPattern);
this.parser = formatter.toDateMathParser();
@@ -284,7 +288,14 @@ public String getWriteableName() {
@Override
public void writeTo(StreamOutput out) throws IOException {
- out.writeString(formatter.pattern());
+ if (out.getVersion().before(Version.V_2_11_0) && formatter.equals(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER)) {
+ out.writeString(DateFieldMapper.LEGACY_DEFAULT_DATE_TIME_FORMATTER.pattern()); // required for backwards compatibility
+ } else {
+ out.writeString(formatter.pattern());
+ }
+ if (out.getVersion().onOrAfter(Version.V_2_11_0)) {
+ out.writeOptionalString(formatter.printPattern());
+ }
if (out.getVersion().before(LegacyESVersion.V_7_0_0)) {
out.writeString(DateUtils.zoneIdToDateTimeZone(timeZone).getID());
} else {
diff --git a/server/src/main/java/org/opensearch/search/aggregations/support/CoreValuesSourceType.java b/server/src/main/java/org/opensearch/search/aggregations/support/CoreValuesSourceType.java
index 224f9281705e1..00c769c015fbc 100644
--- a/server/src/main/java/org/opensearch/search/aggregations/support/CoreValuesSourceType.java
+++ b/server/src/main/java/org/opensearch/search/aggregations/support/CoreValuesSourceType.java
@@ -411,7 +411,7 @@ public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing,
@Override
public DocValueFormat getFormatter(String format, ZoneId tz) {
return new DocValueFormat.DateTime(
- format == null ? DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER : DateFormatter.forPattern(format),
+ format == null ? DateFieldMapper.getDefaultDateTimeFormatter() : DateFormatter.forPattern(format),
tz == null ? ZoneOffset.UTC : tz,
// If we were just looking at fields, we could read the resolution from the field settings, but we need to deal with script
// output, which has no way to indicate the resolution, so we need to default to something. Milliseconds is the standard.
diff --git a/server/src/main/java/org/opensearch/search/aggregations/support/ValueType.java b/server/src/main/java/org/opensearch/search/aggregations/support/ValueType.java
index 59fa2e03f0bc3..33fefa57d50f0 100644
--- a/server/src/main/java/org/opensearch/search/aggregations/support/ValueType.java
+++ b/server/src/main/java/org/opensearch/search/aggregations/support/ValueType.java
@@ -61,7 +61,7 @@ public enum ValueType implements Writeable {
"date",
"date",
CoreValuesSourceType.DATE,
- new DocValueFormat.DateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER, ZoneOffset.UTC, DateFieldMapper.Resolution.MILLISECONDS)
+ new DocValueFormat.DateTime(DateFieldMapper.getDefaultDateTimeFormatter(), ZoneOffset.UTC, DateFieldMapper.Resolution.MILLISECONDS)
),
IP((byte) 6, "ip", "ip", CoreValuesSourceType.IP, DocValueFormat.IP),
// TODO: what is the difference between "number" and "numeric"?
diff --git a/server/src/test/java/org/opensearch/action/search/BottomSortValuesCollectorTests.java b/server/src/test/java/org/opensearch/action/search/BottomSortValuesCollectorTests.java
index 3efcadbfb320d..8042a7e296869 100644
--- a/server/src/test/java/org/opensearch/action/search/BottomSortValuesCollectorTests.java
+++ b/server/src/test/java/org/opensearch/action/search/BottomSortValuesCollectorTests.java
@@ -46,7 +46,6 @@
import java.time.ZoneId;
import java.util.Arrays;
-import static org.opensearch.index.mapper.DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.apache.lucene.search.TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
@@ -136,7 +135,11 @@ public void testWithDates() {
for (boolean reverse : new boolean[] { true, false }) {
SortField[] sortFields = new SortField[] { new SortField("foo", SortField.Type.LONG, reverse) };
DocValueFormat[] sortFormats = new DocValueFormat[] {
- new DocValueFormat.DateTime(DEFAULT_DATE_TIME_FORMATTER, ZoneId.of("UTC"), DateFieldMapper.Resolution.MILLISECONDS) };
+ new DocValueFormat.DateTime(
+ DateFieldMapper.getDefaultDateTimeFormatter(),
+ ZoneId.of("UTC"),
+ DateFieldMapper.Resolution.MILLISECONDS
+ ) };
BottomSortValuesCollector collector = new BottomSortValuesCollector(3, sortFields);
collector.consumeTopDocs(
createTopDocs(sortFields[0], 100, newDateArray("2017-06-01T12:18:20Z", "2018-04-03T15:10:27Z", "2013-06-01T13:10:20Z")),
@@ -170,7 +173,11 @@ public void testWithDateNanos() {
for (boolean reverse : new boolean[] { true, false }) {
SortField[] sortFields = new SortField[] { new SortField("foo", SortField.Type.LONG, reverse) };
DocValueFormat[] sortFormats = new DocValueFormat[] {
- new DocValueFormat.DateTime(DEFAULT_DATE_TIME_FORMATTER, ZoneId.of("UTC"), DateFieldMapper.Resolution.NANOSECONDS) };
+ new DocValueFormat.DateTime(
+ DateFieldMapper.getDefaultDateTimeFormatter(),
+ ZoneId.of("UTC"),
+ DateFieldMapper.Resolution.NANOSECONDS
+ ) };
BottomSortValuesCollector collector = new BottomSortValuesCollector(3, sortFields);
collector.consumeTopDocs(
createTopDocs(sortFields[0], 100, newDateNanoArray("2017-06-01T12:18:20Z", "2018-04-03T15:10:27Z", "2013-06-01T13:10:20Z")),
@@ -242,7 +249,7 @@ private Object[] newBytesArray(String... values) {
private Object[] newDateArray(String... values) {
Long[] longs = new Long[values.length];
for (int i = 0; i < values.length; i++) {
- longs[i] = DEFAULT_DATE_TIME_FORMATTER.parseMillis(values[i]);
+ longs[i] = DateFieldMapper.getDefaultDateTimeFormatter().parseMillis(values[i]);
}
return longs;
}
@@ -250,7 +257,7 @@ private Object[] newDateArray(String... values) {
private Object[] newDateNanoArray(String... values) {
Long[] longs = new Long[values.length];
for (int i = 0; i < values.length; i++) {
- longs[i] = DateUtils.toNanoSeconds(DEFAULT_DATE_TIME_FORMATTER.parseMillis(values[i]));
+ longs[i] = DateUtils.toNanoSeconds(DateFieldMapper.getDefaultDateTimeFormatter().parseMillis(values[i]));
}
return longs;
}
diff --git a/server/src/test/java/org/opensearch/index/mapper/DateFieldMapperTests.java b/server/src/test/java/org/opensearch/index/mapper/DateFieldMapperTests.java
index 2afd6773b15d4..054d3956596af 100644
--- a/server/src/test/java/org/opensearch/index/mapper/DateFieldMapperTests.java
+++ b/server/src/test/java/org/opensearch/index/mapper/DateFieldMapperTests.java
@@ -66,6 +66,7 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
checker.registerConflictCheck("index", b -> b.field("index", false));
checker.registerConflictCheck("store", b -> b.field("store", true));
checker.registerConflictCheck("format", b -> b.field("format", "yyyy-MM-dd"));
+ checker.registerConflictCheck("print_format", b -> b.field("print_format", "yyyy-MM-dd"));
checker.registerConflictCheck("locale", b -> b.field("locale", "es"));
checker.registerConflictCheck("null_value", b -> b.field("null_value", "34500000"));
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true), m -> assertTrue(((DateFieldMapper) m).getIgnoreMalformed()));
@@ -148,7 +149,7 @@ public void testStore() throws Exception {
public void testIgnoreMalformed() throws IOException {
testIgnoreMalformedForValue(
"2016-03-99",
- "failed to parse date field [2016-03-99] with format [strict_date_optional_time||epoch_millis]"
+ "failed to parse date field [2016-03-99] with format [strict_date_time_no_millis||strict_date_optional_time||epoch_millis]"
);
testIgnoreMalformedForValue("-2147483648", "Invalid value for Year (valid values -999999999 - 999999999): -2147483648");
testIgnoreMalformedForValue("-522000000", "long overflow");
diff --git a/server/src/test/java/org/opensearch/index/mapper/DateFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/DateFieldTypeTests.java
index ae4de156b1cd3..e6ce5e9f2cd84 100644
--- a/server/src/test/java/org/opensearch/index/mapper/DateFieldTypeTests.java
+++ b/server/src/test/java/org/opensearch/index/mapper/DateFieldTypeTests.java
@@ -108,7 +108,7 @@ public void isFieldWithinRangeTestCase(DateFieldType ft) throws IOException {
w.addDocument(doc);
DirectoryReader reader = DirectoryReader.open(w);
- DateMathParser alternateFormat = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.toDateMathParser();
+ DateMathParser alternateFormat = DateFieldMapper.getDefaultDateTimeFormatter().toDateMathParser();
doTestIsFieldWithinQuery(ft, reader, null, null);
doTestIsFieldWithinQuery(ft, reader, null, alternateFormat);
doTestIsFieldWithinQuery(ft, reader, DateTimeZone.UTC, null);
@@ -159,7 +159,7 @@ private void doTestIsFieldWithinQuery(DateFieldType ft, DirectoryReader reader,
public void testValueFormat() {
MappedFieldType ft = new DateFieldType("field");
- long instant = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-12T14:10:55"))
+ long instant = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse("2015-10-12T14:10:55"))
.toInstant()
.toEpochMilli();
@@ -168,14 +168,14 @@ public void testValueFormat() {
assertEquals("2015", new DateFieldType("field").docValueFormat("YYYY", ZoneOffset.UTC).format(instant));
assertEquals(instant, ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", false, null));
assertEquals(instant + 999, ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12T14:10:55", true, null));
- long i = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2015-10-13")).toInstant().toEpochMilli();
+ long i = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse("2015-10-13")).toInstant().toEpochMilli();
assertEquals(i - 1, ft.docValueFormat(null, ZoneOffset.UTC).parseLong("2015-10-12||/d", true, null));
}
public void testValueForSearch() {
MappedFieldType ft = new DateFieldType("field");
String date = "2015-10-12T12:09:55.000Z";
- long instant = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parseMillis(date);
+ long instant = DateFieldMapper.getDefaultDateTimeFormatter().parseMillis(date);
assertEquals(date, ft.valueForDisplay(instant));
}
@@ -206,7 +206,7 @@ public void testTermQuery() {
);
MappedFieldType ft = new DateFieldType("field");
String date = "2015-10-12T14:10:55";
- long instant = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date)).toInstant().toEpochMilli();
+ long instant = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date)).toInstant().toEpochMilli();
Query expected = new IndexOrDocValuesQuery(
LongPoint.newRangeQuery("field", instant, instant + 999),
SortedNumericDocValuesField.newSlowRangeQuery("field", instant, instant + 999)
@@ -218,7 +218,7 @@ public void testTermQuery() {
false,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
Resolution.MILLISECONDS,
null,
Collections.emptyMap()
@@ -255,8 +255,8 @@ public void testRangeQuery() throws IOException {
MappedFieldType ft = new DateFieldType("field");
String date1 = "2015-10-12T14:10:55";
String date2 = "2016-04-28T11:33:52";
- long instant1 = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date1)).toInstant().toEpochMilli();
- long instant2 = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date2)).toInstant().toEpochMilli() + 999;
+ long instant1 = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date1)).toInstant().toEpochMilli();
+ long instant2 = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date2)).toInstant().toEpochMilli() + 999;
Query expected = new IndexOrDocValuesQuery(
LongPoint.newRangeQuery("field", instant1, instant2),
SortedNumericDocValuesField.newSlowRangeQuery("field", instant1, instant2)
@@ -281,7 +281,7 @@ public void testRangeQuery() throws IOException {
false,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
Resolution.MILLISECONDS,
null,
Collections.emptyMap()
@@ -327,8 +327,8 @@ public void testRangeQueryWithIndexSort() {
MappedFieldType ft = new DateFieldType("field");
String date1 = "2015-10-12T14:10:55";
String date2 = "2016-04-28T11:33:52";
- long instant1 = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date1)).toInstant().toEpochMilli();
- long instant2 = DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(date2)).toInstant().toEpochMilli() + 999;
+ long instant1 = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date1)).toInstant().toEpochMilli();
+ long instant2 = DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(date2)).toInstant().toEpochMilli() + 999;
Query pointQuery = LongPoint.newRangeQuery("field", instant1, instant2);
Query dvQuery = SortedNumericDocValuesField.newSlowRangeQuery("field", instant1, instant2);
diff --git a/server/src/test/java/org/opensearch/index/mapper/RangeFieldMapperTests.java b/server/src/test/java/org/opensearch/index/mapper/RangeFieldMapperTests.java
index 4ebb160c07c8e..331bfb7b2ddf4 100644
--- a/server/src/test/java/org/opensearch/index/mapper/RangeFieldMapperTests.java
+++ b/server/src/test/java/org/opensearch/index/mapper/RangeFieldMapperTests.java
@@ -361,7 +361,12 @@ public void testSerializeDefaults() throws Exception {
// if type is date_range we check that the mapper contains the default format and locale
// otherwise it should not contain a locale or format
- assertTrue(got, got.contains("\"format\":\"strict_date_optional_time||epoch_millis\"") == type.equals("date_range"));
+ assertTrue(
+ got,
+ got.contains("\"format\":\"strict_date_time_no_millis||strict_date_optional_time||epoch_millis\"") == type.equals(
+ "date_range"
+ )
+ );
assertTrue(got, got.contains("\"locale\":" + "\"" + Locale.ROOT + "\"") == type.equals("date_range"));
}
}
diff --git a/server/src/test/java/org/opensearch/index/mapper/RangeFieldTypeTests.java b/server/src/test/java/org/opensearch/index/mapper/RangeFieldTypeTests.java
index 668666a53cd7c..755d77c6ae392 100644
--- a/server/src/test/java/org/opensearch/index/mapper/RangeFieldTypeTests.java
+++ b/server/src/test/java/org/opensearch/index/mapper/RangeFieldTypeTests.java
@@ -265,7 +265,9 @@ public void testDateRangeQueryUsingMappingFormat() {
);
assertThat(
ex.getMessage(),
- containsString("failed to parse date field [2016-15-06T15:29:50+08:00] with format [strict_date_optional_time||epoch_millis]")
+ containsString(
+ "failed to parse date field [2016-15-06T15:29:50+08:00] with format [strict_date_time_no_millis||strict_date_optional_time||epoch_millis]"
+ )
);
// setting mapping format which is compatible with those dates
diff --git a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java
index 2ac5ea8c585ea..64b3eea029bd1 100644
--- a/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java
+++ b/server/src/test/java/org/opensearch/index/query/RangeQueryBuilderTests.java
@@ -87,8 +87,8 @@ protected RangeQueryBuilder doCreateTestQueryBuilder() {
ZonedDateTime start = now.minusMillis(randomIntBetween(0, 1000000)).atZone(ZoneOffset.UTC);
ZonedDateTime end = now.plusMillis(randomIntBetween(0, 1000000)).atZone(ZoneOffset.UTC);
query = new RangeQueryBuilder(randomFrom(DATE_FIELD_NAME, DATE_RANGE_FIELD_NAME, DATE_ALIAS_FIELD_NAME));
- query.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.format(start));
- query.to(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.format(end));
+ query.from(DateFieldMapper.getDefaultDateTimeFormatter().format(start));
+ query.to(DateFieldMapper.getDefaultDateTimeFormatter().format(end));
// Create timestamp option only then we have a date mapper,
// otherwise we could trigger exception.
if (createShardContext().getMapperService().fieldType(DATE_FIELD_NAME) != null) {
diff --git a/server/src/test/java/org/opensearch/search/aggregations/AggregatorBaseTests.java b/server/src/test/java/org/opensearch/search/aggregations/AggregatorBaseTests.java
index 728b7162bf478..ce96623ea06df 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/AggregatorBaseTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/AggregatorBaseTests.java
@@ -135,7 +135,7 @@ private ValuesSourceConfig getVSConfig(
indexed,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
resolution,
null,
Collections.emptyMap()
@@ -184,7 +184,7 @@ public void testShortcutIsApplicable() throws IOException {
assertNull(pointReaderShim(mockSearchContext(null), null, getVSConfig("number", resolution, false, context)));
}
// Check that we decode a dates "just like" the doc values instance.
- Instant expected = Instant.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse("2020-01-01T00:00:00Z"));
+ Instant expected = Instant.from(DateFieldMapper.getDefaultDateTimeFormatter().parse("2020-01-01T00:00:00Z"));
byte[] scratch = new byte[8];
LongPoint.encodeDimension(DateFieldMapper.Resolution.MILLISECONDS.convert(expected), scratch, 0);
assertThat(
diff --git a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTestCase.java b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTestCase.java
index f5f4f3d4b0723..fdbc0160e51a3 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTestCase.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTestCase.java
@@ -125,7 +125,7 @@ protected final DateFieldMapper.DateFieldType aggregableDateFieldType(boolean us
isSearchable,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
useNanosecondResolution ? DateFieldMapper.Resolution.NANOSECONDS : DateFieldMapper.Resolution.MILLISECONDS,
null,
Collections.emptyMap()
diff --git a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java
index 4e8dc20c465a9..bca6623e66104 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java
@@ -1245,7 +1245,7 @@ private void testSearchCase(
}
private static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
private static long asLong(String dateTime, DateFieldMapper.DateFieldType fieldType) {
diff --git a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateRangeHistogramAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateRangeHistogramAggregatorTests.java
index 08adc6e3d550a..5c12d070824f2 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateRangeHistogramAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/bucket/histogram/DateRangeHistogramAggregatorTests.java
@@ -1086,7 +1086,7 @@ private void testCase(
}
private static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
private static ZonedDateTime asZDT(String dateTime) {
diff --git a/server/src/test/java/org/opensearch/search/aggregations/bucket/range/DateRangeAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/bucket/range/DateRangeAggregatorTests.java
index 26ccc1075220b..96c8be1a25cc3 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/bucket/range/DateRangeAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/bucket/range/DateRangeAggregatorTests.java
@@ -273,7 +273,7 @@ private void testCase(
true,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
resolution,
null,
Collections.emptyMap()
diff --git a/server/src/test/java/org/opensearch/search/aggregations/bucket/range/RangeAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/bucket/range/RangeAggregatorTests.java
index 761615ad1d7eb..dd7ae915c3b45 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/bucket/range/RangeAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/bucket/range/RangeAggregatorTests.java
@@ -136,7 +136,7 @@ public void testDateFieldNanosecondResolution() throws IOException {
true,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
DateFieldMapper.Resolution.NANOSECONDS,
null,
Collections.emptyMap()
@@ -167,7 +167,7 @@ public void testMissingDateWithDateField() throws IOException {
true,
false,
true,
- DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER,
+ DateFieldMapper.getDefaultDateTimeFormatter(),
DateFieldMapper.Resolution.NANOSECONDS,
null,
Collections.emptyMap()
diff --git a/server/src/test/java/org/opensearch/search/aggregations/pipeline/AvgBucketAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/pipeline/AvgBucketAggregatorTests.java
index 3073cb6d35ddf..4b8d0ef83dd1b 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/pipeline/AvgBucketAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/pipeline/AvgBucketAggregatorTests.java
@@ -144,6 +144,6 @@ public void testSameAggNames() throws IOException {
}
private static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
}
diff --git a/server/src/test/java/org/opensearch/search/aggregations/pipeline/CumulativeSumAggregatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/pipeline/CumulativeSumAggregatorTests.java
index 17846234a09d1..5d7636208bd70 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/pipeline/CumulativeSumAggregatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/pipeline/CumulativeSumAggregatorTests.java
@@ -344,6 +344,6 @@ private void executeTestCase(
}
private static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
}
diff --git a/server/src/test/java/org/opensearch/search/aggregations/pipeline/MovFnAggrgatorTests.java b/server/src/test/java/org/opensearch/search/aggregations/pipeline/MovFnAggrgatorTests.java
index 3ae00efaa6da3..d6abe50ea5201 100644
--- a/server/src/test/java/org/opensearch/search/aggregations/pipeline/MovFnAggrgatorTests.java
+++ b/server/src/test/java/org/opensearch/search/aggregations/pipeline/MovFnAggrgatorTests.java
@@ -169,6 +169,6 @@ private void executeTestCase(Query query, DateHistogramAggregationBuilder aggBui
}
private static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
}
diff --git a/test/framework/src/main/java/org/opensearch/search/aggregations/composite/BaseCompositeAggregatorTestCase.java b/test/framework/src/main/java/org/opensearch/search/aggregations/composite/BaseCompositeAggregatorTestCase.java
index 1b348dc7d41a7..6b5ec838f401d 100644
--- a/test/framework/src/main/java/org/opensearch/search/aggregations/composite/BaseCompositeAggregatorTestCase.java
+++ b/test/framework/src/main/java/org/opensearch/search/aggregations/composite/BaseCompositeAggregatorTestCase.java
@@ -305,6 +305,6 @@ protected static Map createAfterKey(Object... fields) {
}
protected static long asLong(String dateTime) {
- return DateFormatters.from(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parse(dateTime)).toInstant().toEpochMilli();
+ return DateFormatters.from(DateFieldMapper.getDefaultDateTimeFormatter().parse(dateTime)).toInstant().toEpochMilli();
}
}