src/share/classes/java/time/chrono/IsoChronology.java
Print this page
@@ -59,29 +59,20 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package java.time.chrono;
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
-import static java.time.temporal.ChronoField.DAY_OF_YEAR;
-import static java.time.temporal.ChronoField.EPOCH_DAY;
import static java.time.temporal.ChronoField.ERA;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
import static java.time.temporal.ChronoField.YEAR;
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
-import static java.time.temporal.TemporalAdjuster.nextOrSame;
import java.io.Serializable;
import java.time.Clock;
import java.time.DateTimeException;
-import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Year;
@@ -396,11 +387,11 @@
}
return (era == IsoEra.CE ? yearOfEra : 1 - yearOfEra);
}
@Override
- public Era eraOf(int eraValue) {
+ public IsoEra eraOf(int eraValue) {
return IsoEra.of(eraValue);
}
@Override
public List<Era> eras() {
@@ -419,20 +410,20 @@
* <p>
* {@code ChronoField} instances on the ISO calendar system are resolved
* as follows.
* <ul>
* <li>{@code EPOCH_DAY} - If present, this is converted to a {@code LocalDate}
- * all other date fields are then cross-checked against the date
+ * and all other date fields are then cross-checked against the date.
* <li>{@code PROLEPTIC_MONTH} - If present, then it is split into the
* {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart
* then the field is validated.
* <li>{@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they
* are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA}
* range is not validated, in smart and strict mode it is. The {@code ERA} is
* validated for range in all three modes. If only the {@code YEAR_OF_ERA} is
* present, and the mode is smart or lenient, then the current era (CE/AD)
- * is assumed. In strict mode, no ers is assumed and the {@code YEAR_OF_ERA} is
+ * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is
* left untouched. If only the {@code ERA} is present, then it is left untouched.
* <li>{@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} -
* If all three are present, then they are combined to form a {@code LocalDate}.
* In all three modes, the {@code YEAR} is validated. If the mode is smart or strict,
* then the month and day are validated, with the day validated from 1 to 31.
@@ -493,63 +484,27 @@
* @throws DateTimeException if the date cannot be resolved, typically
* because of a conflict in the input data
*/
@Override // override for performance
public LocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- // check epoch-day before inventing era
- if (fieldValues.containsKey(EPOCH_DAY)) {
- return LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY));
+ return (LocalDate) super.resolveDate(fieldValues, resolverStyle);
}
- // fix proleptic month before inventing era
- resolveProlepticMonth(fieldValues, resolverStyle);
-
- // invent era if necessary to resolve year-of-era
- resolveYearOfEra(fieldValues, resolverStyle);
-
- // build date
- if (fieldValues.containsKey(YEAR)) {
- if (fieldValues.containsKey(MONTH_OF_YEAR)) {
- if (fieldValues.containsKey(DAY_OF_MONTH)) {
- return resolveYMD(fieldValues, resolverStyle);
- }
- if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) {
- if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) {
- return resolveYMAA(fieldValues, resolverStyle);
- }
- if (fieldValues.containsKey(DAY_OF_WEEK)) {
- return resolveYMAD(fieldValues, resolverStyle);
- }
- }
- }
- if (fieldValues.containsKey(DAY_OF_YEAR)) {
- return resolveYD(fieldValues, resolverStyle);
- }
- if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) {
- if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) {
- return resolveYAA(fieldValues, resolverStyle);
- }
- if (fieldValues.containsKey(DAY_OF_WEEK)) {
- return resolveYAD(fieldValues, resolverStyle);
- }
- }
- }
- return null;
- }
-
- private void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
+ @Override // override for better proleptic algorithm
+ void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
Long pMonth = fieldValues.remove(PROLEPTIC_MONTH);
if (pMonth != null) {
if (resolverStyle != ResolverStyle.LENIENT) {
PROLEPTIC_MONTH.checkValidValue(pMonth);
}
addFieldValue(fieldValues, MONTH_OF_YEAR, Math.floorMod(pMonth, 12) + 1);
addFieldValue(fieldValues, YEAR, Math.floorDiv(pMonth, 12));
}
}
- private void resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
+ @Override // override for enhanced behaviour
+ LocalDate resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
Long yoeLong = fieldValues.remove(YEAR_OF_ERA);
if (yoeLong != null) {
if (resolverStyle != ResolverStyle.LENIENT) {
YEAR_OF_ERA.checkValidValue(yoeLong);
}
@@ -573,14 +528,18 @@
} else if (era.longValue() == 0L) {
addFieldValue(fieldValues, YEAR, Math.subtractExact(1, yoeLong));
} else {
throw new DateTimeException("Invalid value for era: " + era);
}
+ } else if (fieldValues.containsKey(ERA)) {
+ ERA.checkValidValue(fieldValues.get(ERA)); // always validated
}
+ return null;
}
- private LocalDate resolveYMD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
+ @Override // override for performance
+ LocalDate resolveYMD(Map <TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
if (resolverStyle == ResolverStyle.LENIENT) {
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
return LocalDate.of(y, 1, 1).plusMonths(months).plusDays(days);
@@ -596,100 +555,10 @@
}
}
return LocalDate.of(y, moy, dom);
}
- private LocalDate resolveYD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
- if (resolverStyle == ResolverStyle.LENIENT) {
- long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1);
- return LocalDate.of(y, 1, 1).plusDays(days);
- }
- int doy = DAY_OF_YEAR.checkValidIntValue(fieldValues.remove(DAY_OF_YEAR));
- return LocalDate.ofYearDay(y, doy); // smart is same as strict
- }
-
- private LocalDate resolveYMAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
- if (resolverStyle == ResolverStyle.LENIENT) {
- long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
- long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1);
- long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1);
- return LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks).plusDays(days);
- }
- int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
- int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
- int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
- LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1));
- if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) {
- throw new DateTimeException("Strict mode rejected resolved date as it is in a different month");
- }
- return date;
- }
-
- private LocalDate resolveYMAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
- if (resolverStyle == ResolverStyle.LENIENT) {
- long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
- long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1);
- long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1);
- return resolveAligned(y, months, weeks, dow);
- }
- int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
- int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
- int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK));
- LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow)));
- if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) {
- throw new DateTimeException("Strict mode rejected resolved date as it is in a different month");
- }
- return date;
- }
-
- private LocalDate resolveYAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
- if (resolverStyle == ResolverStyle.LENIENT) {
- long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1);
- long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1);
- return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days);
- }
- int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
- int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR));
- LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
- if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) {
- throw new DateTimeException("Strict mode rejected resolved date as it is in a different year");
- }
- return date;
- }
-
- private LocalDate resolveYAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
- int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
- if (resolverStyle == ResolverStyle.LENIENT) {
- long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1);
- long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1);
- return resolveAligned(y, 0, weeks, dow);
- }
- int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR));
- int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK));
- LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow)));
- if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) {
- throw new DateTimeException("Strict mode rejected resolved date as it is in a different year");
- }
- return date;
- }
-
- private LocalDate resolveAligned(int y, long months, long weeks, long dow) {
- LocalDate date = LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks);
- 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;
- }
- return date.with(nextOrSame(DayOfWeek.of((int) dow)));
- }
-
//-----------------------------------------------------------------------
@Override
public ValueRange range(ChronoField field) {
return field.range();
}