Skip to content

Commit 31d50ee

Browse files
authored
Update 9.0 with various locale changes from 8.x (#113787) (#113870)
Forward-port changes from #113787, and update the docs with similar information to #113587
1 parent 81bd866 commit 31d50ee

File tree

5 files changed

+51
-16
lines changed

5 files changed

+51
-16
lines changed

docs/reference/mapping/params/format.asciidoc

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@ down to the nearest day.
3131
[[custom-date-formats]]
3232
==== Custom date formats
3333

34-
Completely customizable date formats are supported. The syntax for these is explained
35-
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html[DateTimeFormatter docs].
34+
Completely customizable date formats are supported. The syntax for these is explained in
35+
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/time/format/DateTimeFormatter.html[DateTimeFormatter docs].
36+
37+
Note that whilst the built-in formats for week dates use the ISO definition of weekyears,
38+
custom formatters using the `Y`, `W`, or `w` field specifiers use the JDK locale definition
39+
of weekyears. This can result in different values between the built-in formats and custom formats
40+
for week dates.
3641

3742
[[built-in-date-formats]]
3843
==== Built In Formats
@@ -256,31 +261,37 @@ The following tables lists all the defaults ISO formats supported:
256261
`week_date` or `strict_week_date`::
257262

258263
A formatter for a full date as four digit weekyear, two digit week of
259-
weekyear, and one digit day of week: `xxxx-'W'ww-e`.
264+
weekyear, and one digit day of week: `YYYY-'W'ww-e`.
265+
This uses the ISO week-date definition.
260266

261267
`week_date_time` or `strict_week_date_time`::
262268

263269
A formatter that combines a full weekyear date and time, separated by a
264-
'T': `xxxx-'W'ww-e'T'HH:mm:ss.SSSZ`.
270+
'T': `YYYY-'W'ww-e'T'HH:mm:ss.SSSZ`.
271+
This uses the ISO week-date definition.
265272

266273
`week_date_time_no_millis` or `strict_week_date_time_no_millis`::
267274

268275
A formatter that combines a full weekyear date and time without millis,
269-
separated by a 'T': `xxxx-'W'ww-e'T'HH:mm:ssZ`.
276+
separated by a 'T': `YYYY-'W'ww-e'T'HH:mm:ssZ`.
277+
This uses the ISO week-date definition.
270278

271279
`weekyear` or `strict_weekyear`::
272280

273-
A formatter for a four digit weekyear: `xxxx`.
281+
A formatter for a four digit weekyear: `YYYY`.
282+
This uses the ISO week-date definition.
274283

275284
`weekyear_week` or `strict_weekyear_week`::
276285

277286
A formatter for a four digit weekyear and two digit week of weekyear:
278-
`xxxx-'W'ww`.
287+
`YYYY-'W'ww`.
288+
This uses the ISO week-date definition.
279289

280290
`weekyear_week_day` or `strict_weekyear_week_day`::
281291

282292
A formatter for a four digit weekyear, two digit week of weekyear, and one
283-
digit day of week: `xxxx-'W'ww-e`.
293+
digit day of week: `YYYY-'W'ww-e`.
294+
This uses the ISO week-date definition.
284295

285296
`year` or `strict_year`::
286297

docs/reference/mapping/types/date.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ The following parameters are accepted by `date` fields:
126126

127127
The locale to use when parsing dates since months do not have the same names
128128
and/or abbreviations in all languages. The default is the
129-
https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#ROOT[`ROOT` locale],
129+
https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#ROOT[`ROOT` locale].
130130

131131
<<ignore-malformed,`ignore_malformed`>>::
132132

modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DateFormat.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Function<String, ZonedDateTime> getFunction(String format, ZoneId zoneId, Locale
9797
// fill the rest of the date up with the parsed date
9898
if (accessor.isSupported(ChronoField.YEAR) == false
9999
&& accessor.isSupported(ChronoField.YEAR_OF_ERA) == false
100+
&& accessor.isSupported(WeekFields.ISO.weekBasedYear()) == false
100101
&& accessor.isSupported(WeekFields.of(locale).weekBasedYear()) == false
101102
&& accessor.isSupported(ChronoField.INSTANT_SECONDS) == false) {
102103
int year = LocalDate.now(ZoneOffset.UTC).getYear();

server/src/main/java/org/elasticsearch/common/time/DateFormatters.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private static DateFormatter newDateFormatter(String format, DateTimeFormatter p
8282
);
8383
}
8484

85-
public static final WeekFields WEEK_FIELDS_ROOT = WeekFields.of(Locale.ROOT);
85+
public static final WeekFields WEEK_FIELDS_ROOT = WeekFields.ISO;
8686

8787
private static final DateTimeFormatter TIME_ZONE_FORMATTER_NO_COLON = new DateTimeFormatterBuilder().appendOffset("+HHmm", "Z")
8888
.toFormatter(Locale.ROOT)
@@ -2389,6 +2389,7 @@ public static ZonedDateTime from(TemporalAccessor accessor, Locale locale, ZoneI
23892389
boolean isLocalTimeSet = localTime != null;
23902390

23912391
// the first two cases are the most common, so this allows us to exit early when parsing dates
2392+
WeekFields localeWeekFields;
23922393
if (isLocalDateSet && isLocalTimeSet) {
23932394
return of(localDate, localTime, zoneId);
23942395
} else if (accessor.isSupported(ChronoField.INSTANT_SECONDS) && accessor.isSupported(NANO_OF_SECOND)) {
@@ -2407,17 +2408,18 @@ public static ZonedDateTime from(TemporalAccessor accessor, Locale locale, ZoneI
24072408
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
24082409
// missing year, falling back to the epoch and then filling
24092410
return getLocalDate(accessor, locale).atStartOfDay(zoneId);
2410-
} else if (accessor.isSupported(WeekFields.of(locale).weekBasedYear())) {
2411-
return localDateFromWeekBasedDate(accessor, locale).atStartOfDay(zoneId);
2411+
} else if (accessor.isSupported(WeekFields.ISO.weekBasedYear())) {
2412+
return localDateFromWeekBasedDate(accessor, locale, WeekFields.ISO).atStartOfDay(zoneId);
2413+
} else if (accessor.isSupported((localeWeekFields = WeekFields.of(locale)).weekBasedYear())) {
2414+
return localDateFromWeekBasedDate(accessor, locale, localeWeekFields).atStartOfDay(zoneId);
24122415
}
24132416

24142417
// we should not reach this piece of code, everything being parsed we should be able to
24152418
// convert to a zoned date time! If not, we have to extend the above methods
24162419
throw new IllegalArgumentException("temporal accessor [" + accessor + "] cannot be converted to zoned date time");
24172420
}
24182421

2419-
private static LocalDate localDateFromWeekBasedDate(TemporalAccessor accessor, Locale locale) {
2420-
WeekFields weekFields = WeekFields.of(locale);
2422+
private static LocalDate localDateFromWeekBasedDate(TemporalAccessor accessor, Locale locale, WeekFields weekFields) {
24212423
if (accessor.isSupported(weekFields.weekOfWeekBasedYear())) {
24222424
return LocalDate.ofEpochDay(0)
24232425
.with(weekFields.weekBasedYear(), accessor.get(weekFields.weekBasedYear()))
@@ -2459,8 +2461,11 @@ public String toString() {
24592461
};
24602462

24612463
private static LocalDate getLocalDate(TemporalAccessor accessor, Locale locale) {
2462-
if (accessor.isSupported(WeekFields.of(locale).weekBasedYear())) {
2463-
return localDateFromWeekBasedDate(accessor, locale);
2464+
WeekFields localeWeekFields;
2465+
if (accessor.isSupported(WeekFields.ISO.weekBasedYear())) {
2466+
return localDateFromWeekBasedDate(accessor, locale, WeekFields.ISO);
2467+
} else if (accessor.isSupported((localeWeekFields = WeekFields.of(locale)).weekBasedYear())) {
2468+
return localDateFromWeekBasedDate(accessor, locale, localeWeekFields);
24642469
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
24652470
int year = getYear(accessor);
24662471
if (accessor.isSupported(DAY_OF_MONTH)) {

server/src/test/java/org/elasticsearch/common/time/DateFormattersTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,24 @@ public void testWeekBasedDates() {
112112

113113
assertThat(DateFormatters.from(dateFormatter.parse("2016")), equalTo(ZonedDateTime.of(2015, 12, 27, 0, 0, 0, 0, ZoneOffset.UTC)));
114114
assertThat(DateFormatters.from(dateFormatter.parse("2015")), equalTo(ZonedDateTime.of(2014, 12, 28, 0, 0, 0, 0, ZoneOffset.UTC)));
115+
116+
// the built-in formats use different week definitions (ISO instead of locale)
117+
dateFormatter = DateFormatters.forPattern("weekyear_week");
118+
119+
assertThat(
120+
DateFormatters.from(dateFormatter.parse("2016-W01")),
121+
equalTo(ZonedDateTime.of(2016, 01, 04, 0, 0, 0, 0, ZoneOffset.UTC))
122+
);
123+
124+
assertThat(
125+
DateFormatters.from(dateFormatter.parse("2015-W01")),
126+
equalTo(ZonedDateTime.of(2014, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC))
127+
);
128+
129+
dateFormatter = DateFormatters.forPattern("weekyear");
130+
131+
assertThat(DateFormatters.from(dateFormatter.parse("2016")), equalTo(ZonedDateTime.of(2016, 01, 04, 0, 0, 0, 0, ZoneOffset.UTC)));
132+
assertThat(DateFormatters.from(dateFormatter.parse("2015")), equalTo(ZonedDateTime.of(2014, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC)));
115133
}
116134

117135
public void testEpochMillisParser() {

0 commit comments

Comments
 (0)