3737import static org .hamcrest .Matchers .not ;
3838import static org .hamcrest .Matchers .nullValue ;
3939import static org .hamcrest .Matchers .sameInstance ;
40+ import static org .hamcrest .Matchers .startsWith ;
4041
4142public class DateFormattersTests extends ESTestCase {
4243
@@ -55,35 +56,50 @@ public void testEpochMillisParser() {
5556 assertThat (instant .getEpochSecond (), is (0L ));
5657 assertThat (instant .getNano (), is (0 ));
5758 }
59+ {
60+ Instant instant = Instant .from (formatter .parse ("123.123456" ));
61+ assertThat (instant .getEpochSecond (), is (0L ));
62+ assertThat (instant .getNano (), is (123123456 ));
63+ }
5864 }
5965
6066 public void testEpochMilliParser () {
61- DateFormatter formatter = DateFormatters .forPattern ("epoch_millis " );
67+ DateFormatter formatter = DateFormatter .forPattern ("8epoch_millis " );
6268 DateTimeParseException e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("invalid" ));
6369 assertThat (e .getMessage (), containsString ("could not be parsed" ));
6470
6571 e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("123.1234567" ));
66- assertThat (e .getMessage (), containsString ("unparsed text found at index 3 " ));
72+ assertThat (e .getMessage (), containsString ("unparsed text found" ));
6773 }
6874
6975 // this is not in the duelling tests, because the epoch second parser in joda time drops the milliseconds after the comma
7076 // but is able to parse the rest
7177 // as this feature is supported it also makes sense to make it exact
72- public void testEpochSecondParser () {
78+ public void testEpochSecondParserWithFraction () {
7379 DateFormatter formatter = DateFormatters .forPattern ("epoch_second" );
7480
75- DateTimeParseException e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("1234.1" ));
76- assertThat (e .getMessage (), is ("Text '1234.1' could not be parsed, unparsed text found at index 4" ));
77- e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("1234." ));
78- assertThat (e .getMessage (), is ("Text '1234.' could not be parsed, unparsed text found at index 4" ));
79- e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("abc" ));
81+ TemporalAccessor accessor = formatter .parse ("1234.1" );
82+ Instant instant = DateFormatters .toZonedDateTime (accessor ).toInstant ();
83+ assertThat (instant .getEpochSecond (), is (1234L ));
84+ assertThat (DateFormatters .toZonedDateTime (accessor ).toInstant ().getNano (), is (100_000_000 ));
85+
86+ accessor = formatter .parse ("1234" );
87+ instant = DateFormatters .toZonedDateTime (accessor ).toInstant ();
88+ assertThat (instant .getEpochSecond (), is (1234L ));
89+ assertThat (instant .getNano (), is (0 ));
90+
91+ DateTimeParseException e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("abc" ));
8092 assertThat (e .getMessage (), is ("Text 'abc' could not be parsed, unparsed text found at index 0" ));
93+
8194 e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("1234.abc" ));
82- assertThat (e .getMessage (), is ("Text '1234.abc' could not be parsed, unparsed text found at index 4" ));
95+ assertThat (e .getMessage (), is ("Text '1234.abc' could not be parsed, unparsed text found at index 5" ));
96+
97+ e = expectThrows (DateTimeParseException .class , () -> formatter .parse ("1234.1234567890" ));
98+ assertThat (e .getMessage (), is ("Text '1234.1234567890' could not be parsed, unparsed text found at index 14" ));
8399 }
84100
85101 public void testEpochMilliParsersWithDifferentFormatters () {
86- DateFormatter formatter = DateFormatter .forPattern ("strict_date_optional_time ||epoch_millis" );
102+ DateFormatter formatter = DateFormatter .forPattern ("8strict_date_optional_time ||epoch_millis" );
87103 TemporalAccessor accessor = formatter .parse ("123" );
88104 assertThat (DateFormatters .toZonedDateTime (accessor ).toInstant ().toEpochMilli (), is (123L ));
89105 assertThat (formatter .pattern (), is ("strict_date_optional_time||epoch_millis" ));
@@ -148,6 +164,26 @@ public void testForceJava8() {
148164 assertThat (formatter , instanceOf (JavaDateFormatter .class ));
149165 }
150166
167+ public void testEpochFormatting () {
168+ long seconds = randomLongBetween (0 , 130L * 365 * 86400 ); // from 1970 epoch till around 2100
169+ long nanos = randomLongBetween (0 , 999_999_999L );
170+ Instant instant = Instant .ofEpochSecond (seconds , nanos );
171+
172+ DateFormatter millisFormatter = DateFormatter .forPattern ("8epoch_millis" );
173+ String millis = millisFormatter .format (instant );
174+ Instant millisInstant = Instant .from (millisFormatter .parse (millis ));
175+ assertThat (millisInstant .toEpochMilli (), is (instant .toEpochMilli ()));
176+ assertThat (millisFormatter .format (Instant .ofEpochSecond (42 , 0 )), is ("42000" ));
177+ assertThat (millisFormatter .format (Instant .ofEpochSecond (42 , 123456789L )), is ("42123.456789" ));
178+
179+ DateFormatter secondsFormatter = DateFormatter .forPattern ("8epoch_second" );
180+ String formattedSeconds = secondsFormatter .format (instant );
181+ Instant secondsInstant = Instant .from (secondsFormatter .parse (formattedSeconds ));
182+ assertThat (secondsInstant .getEpochSecond (), is (instant .getEpochSecond ()));
183+
184+ assertThat (secondsFormatter .format (Instant .ofEpochSecond (42 , 0 )), is ("42" ));
185+ }
186+
151187 public void testParsingStrictNanoDates () {
152188 DateFormatter formatter = DateFormatters .forPattern ("strict_date_optional_time_nanos" );
153189 formatter .format (formatter .parse ("2016-01-01T00:00:00.000" ));
@@ -185,6 +221,7 @@ public void testRoundupFormatterWithEpochDates() {
185221 }
186222
187223 private void assertRoundupFormatter (String format , String input , long expectedMilliSeconds ) {
224+ assertThat (format , startsWith ("8" ));
188225 JavaDateFormatter dateFormatter = (JavaDateFormatter ) DateFormatter .forPattern (format );
189226 dateFormatter .parse (input );
190227 DateTimeFormatter roundUpFormatter = dateFormatter .getRoundupParser ();
0 commit comments