Skip to content

Commit

Permalink
Merge pull request #18509 from terradatum/epoch
Browse files Browse the repository at this point in the history
Support full range of Java Long for epoch DateTime
  • Loading branch information
jpountz committed May 23, 2016
2 parents d2afe75 + cf54903 commit 31e4c16
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 17 deletions.
12 changes: 3 additions & 9 deletions core/src/main/java/org/elasticsearch/common/joda/Joda.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,20 +321,15 @@ public DateTimeField getField(Chronology chronology) {

public static class EpochTimeParser implements DateTimeParser {

private static final Pattern MILLI_SECOND_PRECISION_PATTERN = Pattern.compile("^-?\\d{1,13}$");
private static final Pattern SECOND_PRECISION_PATTERN = Pattern.compile("^-?\\d{1,10}$");

private final boolean hasMilliSecondPrecision;
private final Pattern pattern;

public EpochTimeParser(boolean hasMilliSecondPrecision) {
this.hasMilliSecondPrecision = hasMilliSecondPrecision;
this.pattern = hasMilliSecondPrecision ? MILLI_SECOND_PRECISION_PATTERN : SECOND_PRECISION_PATTERN;
}

@Override
public int estimateParsedLength() {
return hasMilliSecondPrecision ? 13 : 10;
return hasMilliSecondPrecision ? 19 : 16;
}

@Override
Expand All @@ -344,8 +339,7 @@ public int parseInto(DateTimeParserBucket bucket, String text, int position) {

if ((isPositive && isTooLong) ||
// timestamps have to have UTC timezone
bucket.getZone() != DateTimeZone.UTC ||
pattern.matcher(text).matches() == false) {
bucket.getZone() != DateTimeZone.UTC) {
return -1;
}

Expand Down Expand Up @@ -378,7 +372,7 @@ public EpochTimePrinter(boolean hasMilliSecondPrecision) {

@Override
public int estimatePrintedLength() {
return hasMilliSecondPrecision ? 13 : 10;
return hasMilliSecondPrecision ? 19 : 16;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ public void testRounding() {

public void testTimestamps() {
assertDateMathEquals("1418248078000", "2014-12-10T21:47:58.000");
assertDateMathEquals("32484216259000", "2999-05-20T17:24:19.000");
assertDateMathEquals("253382837059000", "9999-05-20T17:24:19.000");

// datemath still works on timestamps
assertDateMathEquals("1418248078000||/m", "2014-12-10T21:47:00.000");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,18 @@ public void testThatNegativeEpochsCanBeParsed() {
formatter.parser().parseDateTime("-100000000");
formatter.parser().parseDateTime("-999999999999");
formatter.parser().parseDateTime("-1234567890123");
formatter.parser().parseDateTime("-1234567890123456789");
} else {
formatter.parser().parseDateTime("-100000000");
formatter.parser().parseDateTime("-1234567890");
formatter.parser().parseDateTime("-1234567890123456");
}
}

public void testForInvalidDatesInEpochSecond() {
FormatDateTimeFormatter formatter = Joda.forPattern("epoch_second");
try {
formatter.parser().parseDateTime(randomFrom("invalid date", "12345678901", "12345678901234"));
formatter.parser().parseDateTime(randomFrom("invalid date", "12345678901234567", "12345678901234567890"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), containsString("Invalid format"));
Expand All @@ -308,7 +310,7 @@ public void testForInvalidDatesInEpochSecond() {
public void testForInvalidDatesInEpochMillis() {
FormatDateTimeFormatter formatter = Joda.forPattern("epoch_millis");
try {
formatter.parser().parseDateTime(randomFrom("invalid date", "12345678901234"));
formatter.parser().parseDateTime(randomFrom("invalid date", "12345678901234567890"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), containsString("Invalid format"));
Expand Down Expand Up @@ -350,6 +352,8 @@ public void testThatEpochParserIsIdempotent() {
assertThat(dateTime.getMillis(), is(1234567890456L));
dateTime = formatter.parser().parseDateTime("1234567890789");
assertThat(dateTime.getMillis(), is(1234567890789L));
dateTime = formatter.parser().parseDateTime("1234567890123456789");
assertThat(dateTime.getMillis(), is(1234567890123456789L));

FormatDateTimeFormatter secondsFormatter = Joda.forPattern("epoch_second");
DateTime secondsDateTime = secondsFormatter.parser().parseDateTime("1234567890");
Expand All @@ -358,6 +362,8 @@ public void testThatEpochParserIsIdempotent() {
assertThat(secondsDateTime.getMillis(), is(1234567890000L));
secondsDateTime = secondsFormatter.parser().parseDateTime("1234567890");
assertThat(secondsDateTime.getMillis(), is(1234567890000L));
secondsDateTime = secondsFormatter.parser().parseDateTime("1234567890123456");
assertThat(secondsDateTime.getMillis(), is(1234567890123456000L));
}

public void testThatDefaultFormatterChecksForCorrectYearLength() throws Exception {
Expand Down
10 changes: 4 additions & 6 deletions docs/reference/mapping/params/format.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,14 @@ The following tables lists all the defaults ISO formats supported:
`epoch_millis`::

A formatter for the number of milliseconds since the epoch. Note, that
this timestamp allows a max length of 13 chars, so only dates between 1653
and 2286 are supported. You should use a different date formatter in
that case.
this timestamp is subject to the limits of a Java `Long.MIN_VALUE` and
`Long.MAX_VALUE`.

`epoch_second`::

A formatter for the number of seconds since the epoch. Note, that this
timestamp allows a max length of 10 chars, so only dates between 1653 and
2286 are supported. You should use a different date formatter in that
case.
timestamp is subject to the limits of a Java `Long.MIN_VALUE` and `Long.
MAX_VALUE` divided by 1000 (the number of milliseconds in a second).

[[strict-date-time]]`date_optional_time` or `strict_date_optional_time`::

Expand Down

0 comments on commit 31e4c16

Please sign in to comment.