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

View file

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

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,9 @@
package test.java.time.format; package test.java.time.format;
import static java.time.temporal.ChronoField.DAY_OF_MONTH; 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.assertSame;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail; import static org.testng.Assert.fail;
@ -85,7 +87,7 @@ import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle; import java.time.format.DecimalStyle;
import java.time.format.SignStyle; import java.time.format.SignStyle;
import java.time.format.TextStyle; import java.time.format.ResolverStyle;
import java.time.temporal.Temporal; import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Locale; import java.util.Locale;
@ -96,7 +98,7 @@ import org.testng.annotations.Test;
/** /**
* Test DateTimeFormatter. * Test DateTimeFormatter.
* @bug 8085887 * @bug 8085887 8293146
*/ */
@Test @Test
public class TestDateTimeFormatter { 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);
});
}
}
} }