|
25 | 25 | import java.time.format.DateTimeFormatter; |
26 | 26 | import java.time.format.DateTimeParseException; |
27 | 27 | import java.time.temporal.ChronoField; |
| 28 | +import java.time.temporal.ChronoUnit; |
28 | 29 | import java.time.temporal.TemporalAccessor; |
29 | 30 | import java.util.List; |
30 | 31 | import java.util.Locale; |
@@ -85,38 +86,32 @@ private void assertDateMathEquals(String text, String expected, String pattern) |
85 | 86 | } |
86 | 87 |
|
87 | 88 | private void assertDateMathEquals(String text, String expected, String pattern, Locale locale) { |
88 | | - long gotMillisJava = dateMathToMillis(text, DateFormatter.forPattern(pattern), locale); |
89 | | - long expectedMillis = DateFormatters.from(DateFormatter.forPattern("strict_date_optional_time").withLocale(locale).parse(expected)) |
90 | | - .toInstant() |
91 | | - .toEpochMilli(); |
| 89 | + Instant gotInstant = dateMathToInstant(text, DateFormatter.forPattern(pattern), locale).truncatedTo(ChronoUnit.MILLIS); |
| 90 | + Instant expectedInstant = DateFormatters.from( |
| 91 | + DateFormatter.forPattern("strict_date_optional_time").withLocale(locale).parse(expected) |
| 92 | + ).toInstant().truncatedTo(ChronoUnit.MILLIS); |
92 | 93 |
|
93 | | - assertThat(gotMillisJava, equalTo(expectedMillis)); |
| 94 | + assertThat(gotInstant, equalTo(expectedInstant)); |
94 | 95 | } |
95 | 96 |
|
96 | 97 | public void testWeekBasedDates() { |
97 | | - // as per WeekFields.ISO first week starts on Monday and has minimum 4 days |
| 98 | + // the years and weeks this outputs depends on where the first day of the first week is for each year |
98 | 99 | DateFormatter dateFormatter = DateFormatters.forPattern("YYYY-ww"); |
99 | 100 |
|
100 | | - // first week of 2016 starts on Monday 2016-01-04 as previous week in 2016 has only 3 days |
101 | 101 | assertThat( |
102 | | - DateFormatters.from(dateFormatter.parse("2016-01")), |
103 | | - equalTo(ZonedDateTime.of(2016, 01, 04, 0, 0, 0, 0, ZoneOffset.UTC)) |
| 102 | + DateFormatters.from(dateFormatter.parse("2016-02")), |
| 103 | + equalTo(ZonedDateTime.of(2016, 01, 03, 0, 0, 0, 0, ZoneOffset.UTC)) |
104 | 104 | ); |
105 | 105 |
|
106 | | - // first week of 2015 starts on Monday 2014-12-29 because 4days belong to 2019 |
107 | 106 | assertThat( |
108 | | - DateFormatters.from(dateFormatter.parse("2015-01")), |
109 | | - equalTo(ZonedDateTime.of(2014, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC)) |
| 107 | + DateFormatters.from(dateFormatter.parse("2015-02")), |
| 108 | + equalTo(ZonedDateTime.of(2015, 01, 04, 0, 0, 0, 0, ZoneOffset.UTC)) |
110 | 109 | ); |
111 | 110 |
|
112 | | - // as per WeekFields.ISO first week starts on Monday and has minimum 4 days |
113 | 111 | dateFormatter = DateFormatters.forPattern("YYYY"); |
114 | 112 |
|
115 | | - // first week of 2016 starts on Monday 2016-01-04 as previous week in 2016 has only 3 days |
116 | | - assertThat(DateFormatters.from(dateFormatter.parse("2016")), equalTo(ZonedDateTime.of(2016, 01, 04, 0, 0, 0, 0, ZoneOffset.UTC))); |
117 | | - |
118 | | - // first week of 2015 starts on Monday 2014-12-29 because 4days belong to 2019 |
119 | | - assertThat(DateFormatters.from(dateFormatter.parse("2015")), equalTo(ZonedDateTime.of(2014, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC))); |
| 113 | + assertThat(DateFormatters.from(dateFormatter.parse("2016")), equalTo(ZonedDateTime.of(2015, 12, 27, 0, 0, 0, 0, ZoneOffset.UTC))); |
| 114 | + assertThat(DateFormatters.from(dateFormatter.parse("2015")), equalTo(ZonedDateTime.of(2014, 12, 28, 0, 0, 0, 0, ZoneOffset.UTC))); |
120 | 115 | } |
121 | 116 |
|
122 | 117 | public void testEpochMillisParser() { |
@@ -600,8 +595,8 @@ public void testYearWithoutMonthRoundUp() { |
600 | 595 | assertDateMathEquals("1500", "1500-01-01T23:59:59.999", "uuuu"); |
601 | 596 | assertDateMathEquals("2022", "2022-01-01T23:59:59.999", "uuuu"); |
602 | 597 | assertDateMathEquals("2022", "2022-01-01T23:59:59.999", "yyyy"); |
603 | | - // cannot reliably default week based years due to locale changing. See JavaDateFormatter javadocs |
604 | | - assertDateMathEquals("2022", "2022-01-03T23:59:59.999", "YYYY", Locale.ROOT); |
| 598 | + // weird locales can change this to epoch-based |
| 599 | + assertDateMathEquals("2022", "2021-12-26T23:59:59.999", "YYYY", Locale.ROOT); |
605 | 600 | } |
606 | 601 |
|
607 | 602 | private void assertRoundupFormatter(String format, String input, long expectedMilliSeconds) { |
@@ -789,30 +784,28 @@ public void testExceptionWhenCompositeParsingFailsDateMath() { |
789 | 784 | String text = "2014-06-06T12:01:02.123"; |
790 | 785 | ElasticsearchParseException e1 = expectThrows( |
791 | 786 | ElasticsearchParseException.class, |
792 | | - () -> dateMathToMillis(text, DateFormatter.forPattern(pattern), randomLocale(random())) |
| 787 | + () -> dateMathToInstant(text, DateFormatter.forPattern(pattern), randomLocale(random())) |
793 | 788 | ); |
794 | 789 | assertThat(e1.getMessage(), containsString(pattern)); |
795 | 790 | assertThat(e1.getMessage(), containsString(text)); |
796 | 791 | } |
797 | 792 |
|
798 | | - private long dateMathToMillis(String text, DateFormatter dateFormatter, Locale locale) { |
| 793 | + private Instant dateMathToInstant(String text, DateFormatter dateFormatter, Locale locale) { |
799 | 794 | DateFormatter javaFormatter = dateFormatter.withLocale(locale); |
800 | 795 | DateMathParser javaDateMath = javaFormatter.toDateMathParser(); |
801 | | - return javaDateMath.parse(text, () -> 0, true, (ZoneId) null).toEpochMilli(); |
| 796 | + return javaDateMath.parse(text, () -> 0, true, null); |
802 | 797 | } |
803 | 798 |
|
804 | 799 | public void testDayOfWeek() { |
805 | | - // 7 (ok joda) vs 1 (java by default) but 7 with customized org.elasticsearch.common.time.IsoLocale.ISO8601 |
806 | 800 | ZonedDateTime now = LocalDateTime.of(2009, 11, 15, 1, 32, 8, 328402).atZone(ZoneOffset.UTC); // Sunday |
807 | 801 | DateFormatter javaFormatter = DateFormatter.forPattern("8e").withZone(ZoneOffset.UTC); |
808 | | - assertThat(javaFormatter.format(now), equalTo("7")); |
| 802 | + assertThat(javaFormatter.format(now), equalTo("1")); |
809 | 803 | } |
810 | 804 |
|
811 | 805 | public void testStartOfWeek() { |
812 | | - // 2019-21 (ok joda) vs 2019-22 (java by default) but 2019-21 with customized org.elasticsearch.common.time.IsoLocale.ISO8601 |
813 | 806 | ZonedDateTime now = LocalDateTime.of(2019, 5, 26, 1, 32, 8, 328402).atZone(ZoneOffset.UTC); |
814 | 807 | DateFormatter javaFormatter = DateFormatter.forPattern("8YYYY-ww").withZone(ZoneOffset.UTC); |
815 | | - assertThat(javaFormatter.format(now), equalTo("2019-21")); |
| 808 | + assertThat(javaFormatter.format(now), equalTo("2019-22")); |
816 | 809 | } |
817 | 810 |
|
818 | 811 | // these parsers should allow both ',' and '.' as a decimal point |
|
0 commit comments