diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DateFormat.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DateFormat.java index 3d943622cec5c..295e056a20b7e 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DateFormat.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DateFormat.java @@ -83,14 +83,9 @@ Function getFunction(String format, ZoneId zoneId, Locale format = format.substring(1); } - boolean isUtc = ZoneOffset.UTC.equals(zoneId); - DateFormatter dateFormatter = DateFormatter.forPattern(format) .withLocale(locale); - // if UTC zone is set here, the time zone specified in the format will be ignored, leading to wrong dates - if (isUtc == false) { - dateFormatter = dateFormatter.withZone(zoneId); - } + final DateFormatter formatter = dateFormatter; return text -> { TemporalAccessor accessor = formatter.parse(text); @@ -110,11 +105,9 @@ Function getFunction(String format, ZoneId zoneId, Locale accessor = newTime.withZoneSameLocal(zoneId); } - if (isUtc) { - return DateFormatters.from(accessor, locale).withZoneSameInstant(ZoneOffset.UTC); - } else { - return DateFormatters.from(accessor, locale); - } + return DateFormatters.from(accessor, locale, zoneId) + .withZoneSameInstant(zoneId); + }; } }; diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateFormatTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateFormatTests.java index 12645dd2c1203..d353364ee0ff7 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateFormatTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateFormatTests.java @@ -75,7 +75,7 @@ public void testParseWeekBasedYear() { } public void testParseWeekBasedWithLocale() { - String format = randomFrom("YYYY-ww"); + String format = "YYYY-ww"; ZoneId timezone = DateUtils.of("Europe/Amsterdam"); Function javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.US); ZonedDateTime dateTime = javaFunction.apply("2020-33"); @@ -83,6 +83,44 @@ public void testParseWeekBasedWithLocale() { assertThat(dateTime, equalTo(ZonedDateTime.of(2020,8,9,0,0,0,0,timezone))); } + public void testNoTimezoneOnPatternAndOverride() { + { + String format = "yyyy-MM-dd'T'HH:mm"; + ZoneId timezone = ZoneId.of("UTC"); + Function javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.ROOT); + // this means that hour will be 01:00 at UTC as timezone was not on a pattern, but provided as an ingest param + ZonedDateTime dateTime = javaFunction.apply("2020-01-01T01:00"); + assertThat(dateTime, equalTo(ZonedDateTime.of(2020, 01, 01, 01, 0, 0, 0, timezone))); + } + { + String format = "yyyy-MM-dd'T'HH:mm"; + ZoneId timezone = ZoneId.of("-01:00"); + Function javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.ROOT); + // this means that hour will be 01:00 at -01:00 as timezone was not on a pattern, but provided as an ingest param + ZonedDateTime dateTime = javaFunction.apply("2020-01-01T01:00"); + assertThat(dateTime, equalTo(ZonedDateTime.of(2020, 01, 01, 01, 0, 0, 0, timezone))); + } + } + + public void testTimezoneOnAPatternAndNonUTCOverride() { + String format = "yyyy-MM-dd'T'HH:mm XXX"; + ZoneId timezone = ZoneId.of("-01:00"); + Function javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.ROOT); + // this means that hour will be 01:00 at -02:00 as timezone on a pattern. Converted to -01:00 as requested on ingest param + + ZonedDateTime dateTime = javaFunction.apply("2020-01-01T01:00 -02:00"); + assertThat(dateTime, equalTo(ZonedDateTime.of(2020, 01, 01, 02, 0, 0, 0, timezone))); + } + + public void testDefaultHourDefaultedToTimezoneOverride() { + String format = "yyyy-MM-dd"; + ZoneId timezone = ZoneId.of("-01:00"); + Function javaFunction = DateFormat.Java.getFunction(format, timezone, Locale.ROOT); + // this means that hour will be 00:00 (default) at -01:00 as timezone was not on a pattern, but -01:00 was an ingest param + ZonedDateTime dateTime = javaFunction.apply("2020-01-01"); + assertThat(dateTime, equalTo(ZonedDateTime.of(2020, 01, 01, 0, 0, 0, 0, timezone))); + } + public void testParseUnixMs() { assertThat(DateFormat.UnixMs.getFunction(null, ZoneOffset.UTC, null).apply("1000500").toInstant().toEpochMilli(), equalTo(1000500L));