8293146: Strict DateTimeFormatter fails to report an invalid week 53

Reviewed-by: rriggs
This commit is contained in:
Naoto Sato 2022-09-07 18:33:37 +00:00
parent 02dce24b59
commit 32c7b6283d
2 changed files with 65 additions and 4 deletions
src/java.base/share/classes/java/time/temporal
test/jdk/java/time/test/java/time/format

@ -78,6 +78,7 @@ import java.io.ObjectInputStream;
import java.io.Serializable;
import java.time.DateTimeException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.Chronology;
import java.time.format.ResolverStyle;
@ -1031,7 +1032,7 @@ public final class WeekFields implements Serializable {
long weeks = Math.subtractExact(wowby, 1);
date = date.plus(weeks, WEEKS);
} else {
int wowby = weekDef.weekOfWeekBasedYear.range().checkValidIntValue(
int wowby = weekDef.weekOfWeekBasedYear.rangeRefinedBy(LocalDate.of(yowby, 7, 2)).checkValidIntValue(
fieldValues.get(weekDef.weekOfWeekBasedYear), weekDef.weekOfWeekBasedYear); // validate
date = ofWeekBasedYear(chrono, yowby, wowby, localDow);
if (resolverStyle == ResolverStyle.STRICT && localizedWeekBasedYear(date) != yowby) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,9 @@
package test.java.time.format;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@ -85,7 +87,7 @@ import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.time.format.SignStyle;
import java.time.format.TextStyle;
import java.time.format.ResolverStyle;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
@ -96,7 +98,7 @@ import org.testng.annotations.Test;
/**
* Test DateTimeFormatter.
* @bug 8085887
* @bug 8085887 8293146
*/
@Test
public class TestDateTimeFormatter {
@ -272,4 +274,62 @@ public class TestDateTimeFormatter {
}
private static final DateTimeFormatter STRICT_WEEK = DateTimeFormatter.ofPattern("YYYY-'W'ww-e")
.withResolverStyle(ResolverStyle.STRICT);
private static final Locale EGYPT = Locale.forLanguageTag("en-EG");
@DataProvider(name = "week53Dates")
Object[][] data_week53Dates() {
return new Object[][] {
// WeekFields[SUNDAY,1]
{"2012-W53-1", Locale.US, null},
{"2013-W53-1", Locale.US, null},
{"2014-W53-1", Locale.US, null},
{"2015-W53-1", Locale.US, null},
{"2016-W53-1", Locale.US, LocalDate.of(2016, 12, 25)},
{"2017-W53-1", Locale.US, null},
{"2018-W53-1", Locale.US, null},
{"2019-W53-1", Locale.US, null},
{"2020-W53-1", Locale.US, null},
{"2021-W53-1", Locale.US, null},
{"2022-W53-1", Locale.US, LocalDate.of(2022, 12, 25)},
// WeekFields[MONDAY,4]
{"2012-W53-1", Locale.UK, null},
{"2013-W53-1", Locale.UK, null},
{"2014-W53-1", Locale.UK, null},
{"2015-W53-1", Locale.UK, LocalDate.of(2015, 12, 28)},
{"2016-W53-1", Locale.UK, null},
{"2017-W53-1", Locale.UK, null},
{"2018-W53-1", Locale.UK, null},
{"2019-W53-1", Locale.UK, null},
{"2020-W53-1", Locale.UK, LocalDate.of(2020, 12, 28)},
{"2021-W53-1", Locale.UK, null},
{"2022-W53-1", Locale.UK, null},
// WeekFields[SATURDAY,1]
{"2012-W53-1", EGYPT, null},
{"2013-W53-1", EGYPT, null},
{"2014-W53-1", EGYPT, null},
{"2015-W53-1", EGYPT, null},
{"2016-W53-1", EGYPT, LocalDate.of(2016, 12, 24)},
{"2017-W53-1", EGYPT, null},
{"2018-W53-1", EGYPT, null},
{"2019-W53-1", EGYPT, null},
{"2020-W53-1", EGYPT, null},
{"2021-W53-1", EGYPT, LocalDate.of(2021, 12, 25)},
{"2022-W53-1", EGYPT, null}
};
}
@Test (dataProvider = "week53Dates")
public void test_week_53(String weekDate, Locale locale, LocalDate expected) {
var f = STRICT_WEEK.withLocale(locale);
if (expected != null) {
assertEquals(LocalDate.parse(weekDate, f), expected);
} else {
assertThrows(DateTimeException.class, () -> {
LocalDate.parse(weekDate, f);
});
}
}
}