src/share/classes/java/time/temporal/IsoFields.java
Print this page
*** 69,78 ****
--- 69,80 ----
import static java.time.temporal.ChronoUnit.WEEKS;
import static java.time.temporal.ChronoUnit.YEARS;
import java.time.Duration;
import java.time.LocalDate;
+ import java.time.ZoneId;
+ import java.time.chrono.ChronoLocalDate;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.format.ResolverStyle;
import java.util.HashMap;
import java.util.Locale;
*** 287,300 ****
* Implementation of the field.
*/
private static enum Field implements TemporalField {
DAY_OF_QUARTER {
@Override
- public String getName() {
- return "DayOfQuarter";
- }
- @Override
public TemporalUnit getBaseUnit() {
return DAYS;
}
@Override
public TemporalUnit getRangeUnit() {
--- 289,298 ----
*** 342,384 ****
long curValue = getFrom(temporal);
range().checkValidValue(newValue, this); // leniently check from 1 to 92 TODO: check
return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue));
}
@Override
! public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long doq, ResolverStyle resolverStyle) {
! if ((temporal.isSupported(YEAR) && temporal.isSupported(QUARTER_OF_YEAR)) == false) {
return null;
}
! int y = temporal.get(YEAR); // validated
LocalDate date;
if (resolverStyle == ResolverStyle.LENIENT) {
! long qoy = temporal.getLong(QUARTER_OF_YEAR); // unvalidated
! date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3));
} else {
! int qoy = temporal.get(QUARTER_OF_YEAR); // validated
date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1);
if (doq < 1 || doq > 90) {
if (resolverStyle == ResolverStyle.STRICT) {
rangeRefinedBy(date).checkValidValue(doq, this); // only allow exact range
} else { // SMART
range().checkValidValue(doq, this); // allow 1-92 rolling into next quarter
}
}
}
! long epochDay = Math.addExact(date.toEpochDay(), Math.subtractExact(doq, 1));
! Map<TemporalField, Long> result = new HashMap<>(4, 1.0f);
! result.put(EPOCH_DAY, epochDay);
! result.put(YEAR, null);
! result.put(QUARTER_OF_YEAR, null);
! return result;
}
- },
- QUARTER_OF_YEAR {
@Override
! public String getName() {
! return "QuarterOfYear";
}
@Override
public TemporalUnit getBaseUnit() {
return QUARTER_YEARS;
}
@Override
--- 340,385 ----
long curValue = getFrom(temporal);
range().checkValidValue(newValue, this); // leniently check from 1 to 92 TODO: check
return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue));
}
@Override
! public ChronoLocalDate resolve(
! Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) {
! Long yearLong = fieldValues.get(YEAR);
! Long qoyLong = fieldValues.get(QUARTER_OF_YEAR);
! if (yearLong == null || qoyLong == null) {
return null;
}
! int y = YEAR.checkValidIntValue(yearLong); // always validate
! long doq = fieldValues.get(DAY_OF_QUARTER);
LocalDate date;
if (resolverStyle == ResolverStyle.LENIENT) {
! date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3));
! doq = Math.subtractExact(doq, 1);
} else {
! int qoy = QUARTER_OF_YEAR.range().checkValidIntValue(qoyLong, QUARTER_OF_YEAR); // validated
date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1);
if (doq < 1 || doq > 90) {
if (resolverStyle == ResolverStyle.STRICT) {
rangeRefinedBy(date).checkValidValue(doq, this); // only allow exact range
} else { // SMART
range().checkValidValue(doq, this); // allow 1-92 rolling into next quarter
}
}
+ doq--;
}
! fieldValues.remove(this);
! fieldValues.remove(YEAR);
! fieldValues.remove(QUARTER_OF_YEAR);
! return date.plusDays(doq);
}
@Override
! public String toString() {
! return "DayOfQuarter";
}
+ },
+ QUARTER_OF_YEAR {
@Override
public TemporalUnit getBaseUnit() {
return QUARTER_YEARS;
}
@Override
*** 407,430 ****
// calls getFrom() to check if supported
long curValue = getFrom(temporal);
range().checkValidValue(newValue, this); // strictly check from 1 to 4
return (R) temporal.with(MONTH_OF_YEAR, temporal.getLong(MONTH_OF_YEAR) + (newValue - curValue) * 3);
}
- },
- WEEK_OF_WEEK_BASED_YEAR {
@Override
! public String getName() {
! return "WeekOfWeekBasedYear";
}
!
@Override
public String getDisplayName(Locale locale) {
Objects.requireNonNull(locale, "locale");
LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
.getLocaleResources(locale);
ResourceBundle rb = lr.getJavaTimeFormatData();
! return rb.containsKey("field.week") ? rb.getString("field.week") : getName();
}
@Override
public TemporalUnit getBaseUnit() {
return WEEKS;
--- 408,430 ----
// calls getFrom() to check if supported
long curValue = getFrom(temporal);
range().checkValidValue(newValue, this); // strictly check from 1 to 4
return (R) temporal.with(MONTH_OF_YEAR, temporal.getLong(MONTH_OF_YEAR) + (newValue - curValue) * 3);
}
@Override
! public String toString() {
! return "QuarterOfYear";
}
! },
! WEEK_OF_WEEK_BASED_YEAR {
@Override
public String getDisplayName(Locale locale) {
Objects.requireNonNull(locale, "locale");
LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
.getLocaleResources(locale);
ResourceBundle rb = lr.getJavaTimeFormatData();
! return rb.containsKey("field.week") ? rb.getString("field.week") : toString();
}
@Override
public TemporalUnit getBaseUnit() {
return WEEKS;
*** 461,509 ****
// calls getFrom() to check if supported
range().checkValidValue(newValue, this); // lenient range
return (R) temporal.plus(Math.subtractExact(newValue, getFrom(temporal)), WEEKS);
}
@Override
! public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long wowby, ResolverStyle resolverStyle) {
! if ((temporal.isSupported(WEEK_BASED_YEAR) && temporal.isSupported(DAY_OF_WEEK)) == false) {
return null;
}
! int wby = temporal.get(WEEK_BASED_YEAR); // validated
LocalDate date = LocalDate.of(wby, 1, 4);
if (resolverStyle == ResolverStyle.LENIENT) {
! long dow = temporal.getLong(DAY_OF_WEEK); // unvalidated
if (dow > 7) {
date = date.plusWeeks((dow - 1) / 7);
dow = ((dow - 1) % 7) + 1;
} else if (dow < 1) {
date = date.plusWeeks(Math.subtractExact(dow, 7) / 7);
dow = ((dow + 6) % 7) + 1;
}
date = date.plusWeeks(Math.subtractExact(wowby, 1)).with(DAY_OF_WEEK, dow);
} else {
! int dow = temporal.get(DAY_OF_WEEK); // validated
if (wowby < 1 || wowby > 52) {
if (resolverStyle == ResolverStyle.STRICT) {
getWeekRange(date).checkValidValue(wowby, this); // only allow exact range
} else { // SMART
range().checkValidValue(wowby, this); // allow 1-53 rolling into next year
}
}
date = date.plusWeeks(wowby - 1).with(DAY_OF_WEEK, dow);
}
! Map<TemporalField, Long> result = new HashMap<>(2, 1.0f);
! result.put(EPOCH_DAY, date.toEpochDay());
! result.put(WEEK_BASED_YEAR, null);
! result.put(DAY_OF_WEEK, null);
! return result;
}
- },
- WEEK_BASED_YEAR {
@Override
! public String getName() {
! return "WeekBasedYear";
}
@Override
public TemporalUnit getBaseUnit() {
return WEEK_BASED_YEARS;
}
@Override
--- 461,512 ----
// calls getFrom() to check if supported
range().checkValidValue(newValue, this); // lenient range
return (R) temporal.plus(Math.subtractExact(newValue, getFrom(temporal)), WEEKS);
}
@Override
! public ChronoLocalDate resolve(
! Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) {
! Long wbyLong = fieldValues.get(WEEK_BASED_YEAR);
! Long dowLong = fieldValues.get(DAY_OF_WEEK);
! if (wbyLong == null || dowLong == null) {
return null;
}
! int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate
! long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR);
LocalDate date = LocalDate.of(wby, 1, 4);
if (resolverStyle == ResolverStyle.LENIENT) {
! long dow = dowLong; // unvalidated
if (dow > 7) {
date = date.plusWeeks((dow - 1) / 7);
dow = ((dow - 1) % 7) + 1;
} else if (dow < 1) {
date = date.plusWeeks(Math.subtractExact(dow, 7) / 7);
dow = ((dow + 6) % 7) + 1;
}
date = date.plusWeeks(Math.subtractExact(wowby, 1)).with(DAY_OF_WEEK, dow);
} else {
! int dow = DAY_OF_WEEK.checkValidIntValue(dowLong); // validated
if (wowby < 1 || wowby > 52) {
if (resolverStyle == ResolverStyle.STRICT) {
getWeekRange(date).checkValidValue(wowby, this); // only allow exact range
} else { // SMART
range().checkValidValue(wowby, this); // allow 1-53 rolling into next year
}
}
date = date.plusWeeks(wowby - 1).with(DAY_OF_WEEK, dow);
}
! fieldValues.remove(this);
! fieldValues.remove(WEEK_BASED_YEAR);
! fieldValues.remove(DAY_OF_WEEK);
! return date;
}
@Override
! public String toString() {
! return "WeekOfWeekBasedYear";
}
+ },
+ WEEK_BASED_YEAR {
@Override
public TemporalUnit getBaseUnit() {
return WEEK_BASED_YEARS;
}
@Override
*** 535,559 ****
LocalDate date = LocalDate.from(temporal);
int week = getWeek(date);
date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week);
return (R) date.with(date);
}
};
@Override
public boolean isDateBased() {
return true;
}
@Override
! public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
! return range();
}
@Override
! public String toString() {
! return getName();
}
//-------------------------------------------------------------------------
private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
--- 538,566 ----
LocalDate date = LocalDate.from(temporal);
int week = getWeek(date);
date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week);
return (R) date.with(date);
}
+ @Override
+ public String toString() {
+ return "WeekBasedYear";
+ }
};
@Override
public boolean isDateBased() {
return true;
}
@Override
! public boolean isTimeBased() {
! return false;
}
@Override
! public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
! return range();
}
//-------------------------------------------------------------------------
private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
*** 634,666 ****
this.name = name;
this.duration = estimatedDuration;
}
@Override
- public String getName() {
- return name;
- }
-
- @Override
public Duration getDuration() {
return duration;
}
@Override
public boolean isDurationEstimated() {
return true;
}
@Override
public boolean isSupportedBy(Temporal temporal) {
return temporal.isSupported(EPOCH_DAY);
}
@SuppressWarnings("unchecked")
@Override
public <R extends Temporal> R addTo(R temporal, long amount) {
! switch(this) {
case WEEK_BASED_YEARS:
return (R) temporal.with(WEEK_BASED_YEAR,
Math.addExact(temporal.get(WEEK_BASED_YEAR), amount));
case QUARTER_YEARS:
// no overflow (256 is multiple of 4)
--- 641,678 ----
this.name = name;
this.duration = estimatedDuration;
}
@Override
public Duration getDuration() {
return duration;
}
@Override
public boolean isDurationEstimated() {
return true;
}
@Override
+ public boolean isDateBased() {
+ return true;
+ }
+
+ @Override
+ public boolean isTimeBased() {
+ return false;
+ }
+
+ @Override
public boolean isSupportedBy(Temporal temporal) {
return temporal.isSupported(EPOCH_DAY);
}
@SuppressWarnings("unchecked")
@Override
public <R extends Temporal> R addTo(R temporal, long amount) {
! switch (this) {
case WEEK_BASED_YEARS:
return (R) temporal.with(WEEK_BASED_YEAR,
Math.addExact(temporal.get(WEEK_BASED_YEAR), amount));
case QUARTER_YEARS:
// no overflow (256 is multiple of 4)
*** 676,693 ****
switch(this) {
case WEEK_BASED_YEARS:
return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR),
temporal1.getLong(WEEK_BASED_YEAR));
case QUARTER_YEARS:
! return temporal1.periodUntil(temporal2, MONTHS) / 3;
default:
throw new IllegalStateException("Unreachable");
}
}
@Override
public String toString() {
! return getName();
!
}
}
}
--- 688,704 ----
switch(this) {
case WEEK_BASED_YEARS:
return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR),
temporal1.getLong(WEEK_BASED_YEAR));
case QUARTER_YEARS:
! return temporal1.until(temporal2, MONTHS) / 3;
default:
throw new IllegalStateException("Unreachable");
}
}
@Override
public String toString() {
! return name;
}
}
}