Treat timestamps without timezone as UTC (elastic/elasticsearch#753)

Original commit: elastic/x-pack-elasticsearch@33ab2fb781
This commit is contained in:
Dimitris Athanasiou 2017-01-19 13:49:14 +00:00 committed by GitHub
parent 36bdcaff5d
commit 0b084ea0e6
4 changed files with 18 additions and 32 deletions

View File

@ -19,6 +19,7 @@ import org.elasticsearch.xpack.ml.utils.ExceptionsHelper;
import org.elasticsearch.xpack.ml.utils.time.DateTimeFormatterTimestampConverter; import org.elasticsearch.xpack.ml.utils.time.DateTimeFormatterTimestampConverter;
import java.io.IOException; import java.io.IOException;
import java.time.ZoneOffset;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@ -331,7 +332,7 @@ public class DataDescription extends ToXContentToBytes implements Writeable {
break; break;
default: default:
try { try {
DateTimeFormatterTimestampConverter.ofPattern(format); DateTimeFormatterTimestampConverter.ofPattern(format, ZoneOffset.UTC);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new IllegalArgumentException(Messages.getMessage(Messages.JOB_CONFIG_INVALID_TIMEFORMAT, format)); throw new IllegalArgumentException(Messages.getMessage(Messages.JOB_CONFIG_INVALID_TIMEFORMAT, format));
} }

View File

@ -28,7 +28,7 @@ public class DateFormatTransform extends DateTransform {
super(readIndexes, writeIndexes, logger); super(readIndexes, writeIndexes, logger);
this.timeFormat = timeFormat; this.timeFormat = timeFormat;
dateToEpochConverter = DateTimeFormatterTimestampConverter.ofPattern(timeFormat, ZoneOffset.systemDefault()); dateToEpochConverter = DateTimeFormatterTimestampConverter.ofPattern(timeFormat, ZoneOffset.UTC);
} }
@Override @Override

View File

@ -36,19 +36,6 @@ public class DateTimeFormatterTimestampConverter implements TimestampConverter {
defaultZoneId = defaultTimezone; defaultZoneId = defaultTimezone;
} }
/**
* Creates a formatter according to the given pattern. The system's default timezone
* is used for dates without timezone information.
* @param pattern the pattern to be used by the formatter, not null.
* See {@link DateTimeFormatter} for the syntax of the accepted patterns
* @return a {@code TimestampConverter}
* @throws IllegalArgumentException if the pattern is invalid or cannot produce a full timestamp
* (e.g. contains a date but not a time)
*/
public static TimestampConverter ofPattern(String pattern) {
return ofPattern(pattern, ZoneOffset.systemDefault());
}
/** /**
* Creates a formatter according to the given pattern * Creates a formatter according to the given pattern
* @param pattern the pattern to be used by the formatter, not null. * @param pattern the pattern to be used by the formatter, not null.

View File

@ -18,45 +18,45 @@ import java.time.format.DateTimeParseException;
public class DateTimeFormatterTimestampConverterTests extends ESTestCase { public class DateTimeFormatterTimestampConverterTests extends ESTestCase {
public void testOfPattern_GivenPatternIsOnlyYear() { public void testOfPattern_GivenPatternIsOnlyYear() {
ESTestCase.expectThrows(IllegalArgumentException.class, () -> DateTimeFormatterTimestampConverter.ofPattern("y")); ESTestCase.expectThrows(IllegalArgumentException.class, () -> DateTimeFormatterTimestampConverter.ofPattern("y", ZoneOffset.UTC));
} }
public void testOfPattern_GivenPatternIsOnlyDate() { public void testOfPattern_GivenPatternIsOnlyDate() {
ESTestCase.expectThrows(IllegalArgumentException.class, () -> DateTimeFormatterTimestampConverter.ofPattern("y-M-d")); ESTestCase.expectThrows(IllegalArgumentException.class,
() -> DateTimeFormatterTimestampConverter.ofPattern("y-M-d", ZoneOffset.UTC));
} }
public void testOfPattern_GivenPatternIsOnlyTime() { public void testOfPattern_GivenPatternIsOnlyTime() {
ESTestCase.expectThrows(IllegalArgumentException.class, () -> DateTimeFormatterTimestampConverter.ofPattern("HH:mm:ss")); ESTestCase.expectThrows(IllegalArgumentException.class,
() -> DateTimeFormatterTimestampConverter.ofPattern("HH:mm:ss", ZoneOffset.UTC));
} }
public void testOfPattern_GivenPatternIsUsingYearInsteadOfYearOfEra() { public void testOfPattern_GivenPatternIsUsingYearInsteadOfYearOfEra() {
ESTestCase.expectThrows(IllegalArgumentException.class, () -> DateTimeFormatterTimestampConverter.ofPattern("uuuu-MM-dd HH:mm:ss")); ESTestCase.expectThrows(IllegalArgumentException.class,
() -> DateTimeFormatterTimestampConverter.ofPattern("uuuu-MM-dd HH:mm:ss", ZoneOffset.UTC));
} }
public void testToEpochSeconds_GivenValidTimestampDoesNotFollowPattern() { public void testToEpochSeconds_GivenValidTimestampDoesNotFollowPattern() {
TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern("yyyy-MM-dd HH:mm:ss"); TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern("yyyy-MM-dd HH:mm:ss", ZoneOffset.UTC);
ESTestCase.expectThrows(DateTimeParseException.class, () -> formatter.toEpochSeconds("14:00:22")); ESTestCase.expectThrows(DateTimeParseException.class, () -> formatter.toEpochSeconds("14:00:22"));
} }
public void testToEpochMillis_GivenValidTimestampDoesNotFollowPattern() { public void testToEpochMillis_GivenValidTimestampDoesNotFollowPattern() {
TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", ZoneOffset.UTC);
ESTestCase.expectThrows(DateTimeParseException.class, () -> formatter.toEpochMillis("2015-01-01 14:00:22")); ESTestCase.expectThrows(DateTimeParseException.class, () -> formatter.toEpochMillis("2015-01-01 14:00:22"));
} }
public void testToEpochSeconds_GivenPatternHasFullDateAndOnlyHours() { public void testToEpochSeconds_GivenPatternHasFullDateAndOnlyHours() {
long expected = ZonedDateTime.of(2014, 3, 22, 1, 0, 0, 0, ZoneOffset.systemDefault()).toEpochSecond(); long expected = ZonedDateTime.of(2014, 3, 22, 1, 0, 0, 0, ZoneOffset.UTC).toEpochSecond();
assertEquals(expected, toEpochSeconds("2014-03-22 01", "y-M-d HH")); assertEquals(expected, toEpochSeconds("2014-03-22 01", "y-M-d HH"));
} }
public void testToEpochSeconds_GivenPatternHasFullDateAndTimeWithoutTimeZone() { public void testToEpochSeconds_GivenPatternHasFullDateAndTimeWithoutTimeZone() {
long expected = ZonedDateTime.of(1985, 8, 18, 20, 15, 40, 0, ZoneOffset.systemDefault()).toEpochSecond(); long expected = ZonedDateTime.of(1985, 8, 18, 20, 15, 40, 0, ZoneOffset.UTC).toEpochSecond();
assertEquals(expected, toEpochSeconds("1985-08-18 20:15:40", "yyyy-MM-dd HH:mm:ss")); assertEquals(expected, toEpochSeconds("1985-08-18 20:15:40", "yyyy-MM-dd HH:mm:ss"));
expected = ZonedDateTime.of(1985, 8, 18, 20, 15, 40, 0, ZoneOffset.UTC).toEpochSecond();
assertEquals(expected, toEpochSeconds("1985-08-18 20:15:40", "yyyy-MM-dd HH:mm:ss", ZoneOffset.UTC));
expected = ZonedDateTime.of(1985, 8, 18, 20, 15, 40, 0, ZoneOffset.MIN).toEpochSecond(); expected = ZonedDateTime.of(1985, 8, 18, 20, 15, 40, 0, ZoneOffset.MIN).toEpochSecond();
assertEquals(expected, toEpochSeconds("1985-08-18 20:15:40", "yyyy-MM-dd HH:mm:ss", ZoneOffset.MIN)); assertEquals(expected, toEpochSeconds("1985-08-18 20:15:40", "yyyy-MM-dd HH:mm:ss", ZoneOffset.MIN));
@ -74,13 +74,11 @@ public class DateTimeFormatterTimestampConverterTests extends ESTestCase {
public void testToEpochSeconds_GivenPatternHasDateWithoutYearAndTimeWithoutTimeZone() throws ParseException { public void testToEpochSeconds_GivenPatternHasDateWithoutYearAndTimeWithoutTimeZone() throws ParseException {
// Summertime // Summertime
long expected = ZonedDateTime.of(LocalDate.now(ZoneId.systemDefault()).getYear(), 8, 14, 1, 30, 20, 0, long expected = ZonedDateTime.of(LocalDate.now(ZoneOffset.UTC).getYear(), 8, 14, 1, 30, 20, 0, ZoneOffset.UTC).toEpochSecond();
ZoneOffset.systemDefault()).toEpochSecond();
assertEquals(expected, toEpochSeconds("08 14 01:30:20", "MM dd HH:mm:ss")); assertEquals(expected, toEpochSeconds("08 14 01:30:20", "MM dd HH:mm:ss"));
// Non-summertime // Non-summertime
expected = ZonedDateTime.of(LocalDate.now(ZoneId.systemDefault()).getYear(), 12, 14, 1, 30, 20, 0, expected = ZonedDateTime.of(LocalDate.now(ZoneOffset.UTC).getYear(), 12, 14, 1, 30, 20, 0, ZoneOffset.UTC).toEpochSecond();
ZoneOffset.systemDefault()).toEpochSecond();
assertEquals(expected, toEpochSeconds("12 14 01:30:20", "MM dd HH:mm:ss")); assertEquals(expected, toEpochSeconds("12 14 01:30:20", "MM dd HH:mm:ss"));
} }
@ -90,7 +88,7 @@ public class DateTimeFormatterTimestampConverterTests extends ESTestCase {
} }
private static long toEpochSeconds(String timestamp, String pattern) { private static long toEpochSeconds(String timestamp, String pattern) {
TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern(pattern); TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern(pattern, ZoneOffset.UTC);
return formatter.toEpochSeconds(timestamp); return formatter.toEpochSeconds(timestamp);
} }
@ -100,7 +98,7 @@ public class DateTimeFormatterTimestampConverterTests extends ESTestCase {
} }
private static long toEpochMillis(String timestamp, String pattern) { private static long toEpochMillis(String timestamp, String pattern) {
TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern(pattern); TimestampConverter formatter = DateTimeFormatterTimestampConverter.ofPattern(pattern, ZoneOffset.UTC);
return formatter.toEpochMillis(timestamp); return formatter.toEpochMillis(timestamp);
} }
} }