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();
     }