mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-17 05:45:05 +00:00
8040058: IsoFields.WEEK_BASED_YEAR adjustInto incorrect and WeekFields.weekOfWeekBasedYear().range incorrect
Reviewed-by: lancea, rriggs
This commit is contained in:
parent
d3bdb3c598
commit
e66fbbceaf
@ -535,11 +535,17 @@ public final class IsoFields {
|
||||
if (isSupportedBy(temporal) == false) {
|
||||
throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear");
|
||||
}
|
||||
int newVal = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check
|
||||
int newWby = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check
|
||||
LocalDate date = LocalDate.from(temporal);
|
||||
int dow = date.get(DAY_OF_WEEK);
|
||||
int week = getWeek(date);
|
||||
date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week);
|
||||
return (R) date.with(date);
|
||||
if (week == 53 && getWeekRange(newWby) == 52) {
|
||||
week = 52;
|
||||
}
|
||||
LocalDate resolved = LocalDate.of(newWby, 1, 4); // 4th is guaranteed to be in week one
|
||||
int days = (dow - resolved.get(DAY_OF_WEEK)) + ((week - 1) * 7);
|
||||
resolved = resolved.plusDays(days);
|
||||
return (R) temporal.with(resolved);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -577,12 +583,16 @@ public final class IsoFields {
|
||||
|
||||
private static ValueRange getWeekRange(LocalDate date) {
|
||||
int wby = getWeekBasedYear(date);
|
||||
date = date.withDayOfYear(1).withYear(wby);
|
||||
return ValueRange.of(1, getWeekRange(wby));
|
||||
}
|
||||
|
||||
private static int getWeekRange(int wby) {
|
||||
LocalDate date = LocalDate.of(wby, 1, 1);
|
||||
// 53 weeks if standard year starts on Thursday, or Wed in a leap year
|
||||
if (date.getDayOfWeek() == THURSDAY || (date.getDayOfWeek() == WEDNESDAY && date.isLeapYear())) {
|
||||
return ValueRange.of(1, 53);
|
||||
return 53;
|
||||
}
|
||||
return ValueRange.of(1, 52);
|
||||
return 52;
|
||||
}
|
||||
|
||||
private static int getWeek(LocalDate date) {
|
||||
|
||||
@ -700,7 +700,7 @@ public final class WeekFields implements Serializable {
|
||||
* @see WeekFields#weekOfWeekBasedYear()
|
||||
*/
|
||||
static ComputedDayOfField ofWeekOfWeekBasedYearField(WeekFields weekDef) {
|
||||
return new ComputedDayOfField("WeekOfWeekBasedYear", weekDef, WEEKS, IsoFields.WEEK_BASED_YEARS, WEEK_OF_YEAR_RANGE);
|
||||
return new ComputedDayOfField("WeekOfWeekBasedYear", weekDef, WEEKS, IsoFields.WEEK_BASED_YEARS, WEEK_OF_WEEK_BASED_YEAR_RANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -753,6 +753,7 @@ public final class WeekFields implements Serializable {
|
||||
private static final ValueRange DAY_OF_WEEK_RANGE = ValueRange.of(1, 7);
|
||||
private static final ValueRange WEEK_OF_MONTH_RANGE = ValueRange.of(0, 1, 4, 6);
|
||||
private static final ValueRange WEEK_OF_YEAR_RANGE = ValueRange.of(0, 1, 52, 54);
|
||||
private static final ValueRange WEEK_OF_WEEK_BASED_YEAR_RANGE = ValueRange.of(1, 52, 53);
|
||||
|
||||
@Override
|
||||
public long getFrom(TemporalAccessor temporal) {
|
||||
|
||||
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package test.java.time.temporal;
|
||||
|
||||
import static java.time.temporal.ChronoField.DAY_OF_WEEK;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.MonthDay;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.Year;
|
||||
import java.time.chrono.ThaiBuddhistDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.IsoFields;
|
||||
import java.time.temporal.TemporalField;
|
||||
import java.time.temporal.ValueRange;
|
||||
import java.time.temporal.WeekFields;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test.
|
||||
*/
|
||||
@Test
|
||||
public class TestIsoWeekFields {
|
||||
|
||||
@DataProvider(name = "fields")
|
||||
Object[][] data_Fields() {
|
||||
return new Object[][] {
|
||||
{IsoFields.WEEK_OF_WEEK_BASED_YEAR, IsoFields.WEEK_BASED_YEAR},
|
||||
{WeekFields.ISO.weekOfWeekBasedYear(), WeekFields.ISO.weekBasedYear()},
|
||||
};
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// WEEK_OF_WEEK_BASED_YEAR
|
||||
//-----------------------------------------------------------------------
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WOWBY_basics(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(weekField.isDateBased(), true);
|
||||
assertEquals(weekField.isTimeBased(), false);
|
||||
assertEquals(weekField.getBaseUnit(), ChronoUnit.WEEKS);
|
||||
assertEquals(weekField.getRangeUnit(), IsoFields.WEEK_BASED_YEARS);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WOWBY_isSupportedBy(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(weekField.isSupportedBy(LocalTime.NOON), false);
|
||||
assertEquals(weekField.isSupportedBy(MonthDay.of(2, 1)), false);
|
||||
assertEquals(weekField.isSupportedBy(LocalDate.MIN), true);
|
||||
assertEquals(weekField.isSupportedBy(OffsetDateTime.MAX), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_WOWBY_isSupportedBy_fieldsDiffer() {
|
||||
assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
|
||||
assertEquals(WeekFields.ISO.weekOfWeekBasedYear().isSupportedBy(ThaiBuddhistDate.now()), true);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WOWBY_range(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(weekField.range(), ValueRange.of(1, 52, 53));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WOWBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(1, 52));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 29)), ValueRange.of(1, 52));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 30)), ValueRange.of(1, 52));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 28)), ValueRange.of(1, 52));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 29)), ValueRange.of(1, 53));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 3)), ValueRange.of(1, 53));
|
||||
assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 4)), ValueRange.of(1, 52));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// WEEK_BASED_YEAR
|
||||
//-----------------------------------------------------------------------
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WBY_basics(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(yearField.isDateBased(), true);
|
||||
assertEquals(yearField.isTimeBased(), false);
|
||||
assertEquals(yearField.getBaseUnit(), IsoFields.WEEK_BASED_YEARS);
|
||||
assertEquals(yearField.getRangeUnit(), ChronoUnit.FOREVER);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WBY_isSupportedBy(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(yearField.isSupportedBy(LocalTime.NOON), false);
|
||||
assertEquals(yearField.isSupportedBy(MonthDay.of(2, 1)), false);
|
||||
assertEquals(yearField.isSupportedBy(LocalDate.MIN), true);
|
||||
assertEquals(yearField.isSupportedBy(OffsetDateTime.MAX), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_WBY_isSupportedBy_ISO() {
|
||||
assertEquals(IsoFields.WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WBY_range(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(yearField.range(), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_WBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) {
|
||||
assertEquals(yearField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_getFrom(TemporalField weekField, TemporalField yearField) {
|
||||
// tests every day from 2011 to 2016 inclusive
|
||||
LocalDate date = LocalDate.of(2011, 1, 3);
|
||||
int wby = 2011;
|
||||
int week = 1;
|
||||
int dow = 1;
|
||||
for (int i = 1; i <= ((52 + 52 + 52 + 52 + 53 + 52) * 7); i++) {
|
||||
assertEquals(yearField.getFrom(date), wby);
|
||||
assertEquals(weekField.getFrom(date), week);
|
||||
assertEquals(DAY_OF_WEEK.getFrom(date), dow);
|
||||
if (dow == 7) {
|
||||
dow = 1;
|
||||
week++;
|
||||
} else {
|
||||
dow++;
|
||||
}
|
||||
if (week > wbyLen(wby)) {
|
||||
week = 1;
|
||||
wby++;
|
||||
}
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
assertEquals(yearField.getFrom(date), 2017);
|
||||
assertEquals(weekField.getFrom(date), 1);
|
||||
assertEquals(DAY_OF_WEEK.getFrom(date), 1);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_adjustInto_dow(TemporalField weekField, TemporalField yearField) {
|
||||
// tests every day from 2012 to 2016 inclusive
|
||||
LocalDate date = LocalDate.of(2012, 1, 2);
|
||||
int wby = 2012;
|
||||
int week = 1;
|
||||
int dow = 1;
|
||||
for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
|
||||
for (int j = 1; j <= 7; j++) {
|
||||
LocalDate adjusted = DAY_OF_WEEK.adjustInto(date, j);
|
||||
assertEquals(adjusted.get(DAY_OF_WEEK), j);
|
||||
assertEquals(adjusted.get(weekField), week);
|
||||
assertEquals(adjusted.get(yearField), wby);
|
||||
}
|
||||
if (dow == 7) {
|
||||
dow = 1;
|
||||
week++;
|
||||
} else {
|
||||
dow++;
|
||||
}
|
||||
if (week > wbyLen(wby)) {
|
||||
week = 1;
|
||||
wby++;
|
||||
}
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_adjustInto_week(TemporalField weekField, TemporalField yearField) {
|
||||
// tests every day from 2012 to 2016 inclusive
|
||||
LocalDate date = LocalDate.of(2012, 1, 2);
|
||||
int wby = 2012;
|
||||
int week = 1;
|
||||
int dow = 1;
|
||||
for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
|
||||
int weeksInYear = (wby == 2015 ? 53 : 52);
|
||||
for (int j = 1; j <= weeksInYear; j++) {
|
||||
LocalDate adjusted = weekField.adjustInto(date, j);
|
||||
assertEquals(adjusted.get(weekField), j);
|
||||
assertEquals(adjusted.get(DAY_OF_WEEK), dow);
|
||||
assertEquals(adjusted.get(yearField), wby);
|
||||
}
|
||||
if (dow == 7) {
|
||||
dow = 1;
|
||||
week++;
|
||||
} else {
|
||||
dow++;
|
||||
}
|
||||
if (week > wbyLen(wby)) {
|
||||
week = 1;
|
||||
wby++;
|
||||
}
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_adjustInto_wby(TemporalField weekField, TemporalField yearField) {
|
||||
// tests every day from 2012 to 2016 inclusive
|
||||
LocalDate date = LocalDate.of(2012, 1, 2);
|
||||
int wby = 2012;
|
||||
int week = 1;
|
||||
int dow = 1;
|
||||
for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
|
||||
for (int j = 2004; j <= 2015; j++) {
|
||||
LocalDate adjusted = yearField.adjustInto(date, j);
|
||||
assertEquals(adjusted.get(yearField), j);
|
||||
assertEquals(adjusted.get(DAY_OF_WEEK), dow);
|
||||
assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(j) == 52 ? 52 : week), "" + date + " " + adjusted);
|
||||
}
|
||||
if (dow == 7) {
|
||||
dow = 1;
|
||||
week++;
|
||||
} else {
|
||||
dow++;
|
||||
}
|
||||
if (week > wbyLen(wby)) {
|
||||
week = 1;
|
||||
wby++;
|
||||
}
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fields")
|
||||
public void test_addTo_weekBasedYears(TemporalField weekField, TemporalField yearField) {
|
||||
// tests every day from 2012 to 2016 inclusive
|
||||
LocalDate date = LocalDate.of(2012, 1, 2);
|
||||
int wby = 2012;
|
||||
int week = 1;
|
||||
int dow = 1;
|
||||
for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) {
|
||||
for (int j = -5; j <= 5; j++) {
|
||||
LocalDate adjusted = IsoFields.WEEK_BASED_YEARS.addTo(date, j);
|
||||
assertEquals(adjusted.get(yearField), wby + j);
|
||||
assertEquals(adjusted.get(DAY_OF_WEEK), dow);
|
||||
assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(wby + j) == 52 ? 52 : week), "" + date + " " + adjusted);
|
||||
}
|
||||
if (dow == 7) {
|
||||
dow = 1;
|
||||
week++;
|
||||
} else {
|
||||
dow++;
|
||||
}
|
||||
if (week > wbyLen(wby)) {
|
||||
week = 1;
|
||||
wby++;
|
||||
}
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
private int wbyLen(int wby) {
|
||||
return (wby == 2004 || wby == 2009 || wby == 2015 || wby == 2020 ? 53 : 52);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user