src/share/classes/java/time/temporal/IsoFields.java

Print this page

        

@@ -69,10 +69,12 @@
 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,14 +289,10 @@
      * 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() {

@@ -342,43 +340,46 @@
                 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) {
+            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 = temporal.get(YEAR);  // validated
+                int y = YEAR.checkValidIntValue(yearLong);  // always validate
+                long doq = fieldValues.get(DAY_OF_QUARTER);
                 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));
+                    date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3));
+                    doq = Math.subtractExact(doq, 1);
                 } else {
-                    int qoy = temporal.get(QUARTER_OF_YEAR);  // validated
+                    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--;
                 }
-                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;
+                fieldValues.remove(this);
+                fieldValues.remove(YEAR);
+                fieldValues.remove(QUARTER_OF_YEAR);
+                return date.plusDays(doq);
             }
-        },
-        QUARTER_OF_YEAR {
             @Override
-            public String getName() {
-                return "QuarterOfYear";
+            public String toString() {
+                return "DayOfQuarter";
             }
+        },
+        QUARTER_OF_YEAR {
             @Override
             public TemporalUnit getBaseUnit() {
                 return QUARTER_YEARS;
             }
             @Override

@@ -407,24 +408,23 @@
                 // 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";
+            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") : getName();
+                return rb.containsKey("field.week") ? rb.getString("field.week") : toString();
             }
 
             @Override
             public TemporalUnit getBaseUnit() {
                 return WEEKS;

@@ -461,49 +461,52 @@
                 // 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) {
+            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 = temporal.get(WEEK_BASED_YEAR);  // validated
+                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 = temporal.getLong(DAY_OF_WEEK);  // unvalidated
+                    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 = temporal.get(DAY_OF_WEEK);  // validated
+                    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);
                 }
-                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;
+                fieldValues.remove(this);
+                fieldValues.remove(WEEK_BASED_YEAR);
+                fieldValues.remove(DAY_OF_WEEK);
+                return date;
             }
-        },
-        WEEK_BASED_YEAR {
             @Override
-            public String getName() {
-                return "WeekBasedYear";
+            public String toString() {
+                return "WeekOfWeekBasedYear";
             }
+        },
+        WEEK_BASED_YEAR {
             @Override
             public TemporalUnit getBaseUnit() {
                 return WEEK_BASED_YEARS;
             }
             @Override

@@ -535,25 +538,29 @@
                 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 ValueRange rangeRefinedBy(TemporalAccessor temporal) {
-            return range();
+        public boolean isTimeBased() {
+            return false;
         }
 
         @Override
-        public String toString() {
-            return getName();
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+            return range();
         }
 
         //-------------------------------------------------------------------------
         private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
 

@@ -634,33 +641,38 @@
             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 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) {
+            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,18 +688,17 @@
             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;
+                    return temporal1.until(temporal2, MONTHS) / 3;
                 default:
                     throw new IllegalStateException("Unreachable");
             }
         }
 
         @Override
         public String toString() {
-            return getName();
-
+            return name;
         }
     }
 }