jdk/src/share/classes/java/time/temporal/TemporalField.java
changeset 19030 32f129cb6351
parent 17474 8c100beabcc0
child 20523 aee7c8a56c75
--- a/jdk/src/share/classes/java/time/temporal/TemporalField.java	Thu Jul 18 10:49:08 2013 -0700
+++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java	Thu Jul 18 11:02:02 2013 -0700
@@ -62,6 +62,9 @@
 package java.time.temporal;
 
 import java.time.DateTimeException;
+import java.time.ZoneId;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
 import java.time.format.ResolverStyle;
 import java.util.Locale;
 import java.util.Map;
@@ -93,29 +96,19 @@
 public interface TemporalField {
 
     /**
-     * Gets a descriptive name for the field.
-     * <p>
-     * The should be of the format 'BaseOfRange', such as 'MonthOfYear',
-     * unless the field has a range of {@code FOREVER}, when only
-     * the base unit is mentioned, such as 'Year' or 'Era'.
-     *
-     * @return the name, not null
-     */
-    String getName();
-
-    /**
      * Gets the display name for the field in the requested locale.
      * <p>
-     * If there is no display name for the locale the value of {@code getName}
-     * is returned.
+     * If there is no display name for the locale then a suitable default must be returned.
+     * <p>
+     * The default implementation must check the locale is not null
+     * and return {@code toString()}.
      *
      * @param locale  the locale to use, not null
-     * @return the display name for the locale or the value of {@code getName},
-     *     not null
+     * @return the display name for the locale or a suitable default, not null
      */
     default String getDisplayName(Locale locale) {
-        Objects.requireNonNull(locale, "local");
-        return getName();
+        Objects.requireNonNull(locale, "locale");
+        return toString();
     }
 
     /**
@@ -164,28 +157,24 @@
      * <p>
      * A field is date-based if it can be derived from
      * {@link ChronoField#EPOCH_DAY EPOCH_DAY}.
-     * <p>
-     * The default implementation must return false.
+     * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()}
+     * to return false, such as when representing a field like minute-of-week.
      *
      * @return true if this field is a component of a date
      */
-    default boolean isDateBased() {
-        return false;
-    }
+    boolean isDateBased();
 
     /**
      * Checks if this field represents a component of a time.
      * <p>
      * A field is time-based if it can be derived from
      * {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}.
-     * <p>
-     * The default implementation must return false.
+     * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()}
+     * to return false, such as when representing a field like minute-of-week.
      *
      * @return true if this field is a component of a time
      */
-    default boolean isTimeBased() {
-        return false;
-    }
+    boolean isTimeBased();
 
     //-----------------------------------------------------------------------
     /**
@@ -319,45 +308,79 @@
     <R extends Temporal> R adjustInto(R temporal, long newValue);
 
     /**
-     * Resolves this field to provide a simpler alternative.
+     * Resolves this field to provide a simpler alternative or a date.
      * <p>
      * This method is invoked during the resolve phase of parsing.
      * It is designed to allow application defined fields to be simplified into
-     * more standard fields, such as those on {@code ChronoField}.
-     * <p>
-     * The method will only be invoked if the specified temporal supports this field.
-     * The value of this field is provided.
+     * more standard fields, such as those on {@code ChronoField}, or into a date.
      * <p>
-     * The temporal must be queried using the methods of {@code TemporalAccessor},
-     * not using {@code getFrom}, {@code isSupportedBy} or {@code rangeRefinedBy}.
-     * Before querying any field, implementations must ensure it is supported, as
-     * exceptions of this type would negatively affect the calculation of a parsed result.
+     * Applications should not normally invoke this method directly.
+     *
+     * @implSpec
+     * If an implementation represents a field that can be simplified, or
+     * combined with others, then this method must be implemented.
+     * <p>
+     * The specified map contains the current state of the parse.
+     * The map is mutable and must be mutated to resolve the field and
+     * any related fields. This method will only be invoked during parsing
+     * if the map contains this field, and implementations should therefore
+     * assume this field is present.
      * <p>
-     * If this field can resolve, it must return a map, if not it must return null.
-     * The returned map contains the changes to be made to the temporal, expressed
-     * as field-value pairs. If the value for a field is null, the field is to be
-     * removed from the temporal. A null key must not be added to the result map.
+     * Resolving a field will consist of looking at the value of this field,
+     * and potentially other fields, and either updating the map with a
+     * simpler value, such as a {@code ChronoField}, or returning a
+     * complete {@code ChronoLocalDate}. If a resolve is successful,
+     * the code must remove all the fields that were resolved from the map,
+     * including this field.
+     * <p>
+     * For example, the {@code IsoFields} class contains the quarter-of-year
+     * and day-of-quarter fields. The implementation of this method in that class
+     * resolves the two fields plus the {@link ChronoField#YEAR YEAR} into a
+     * complete {@code LocalDate}. The resolve method will remove all three
+     * fields from the map before returning the {@code LocalDate}.
      * <p>
-     * If the result is non-null, this field will be removed from the temporal.
-     * This field should not be added to the result map.
+     * If resolution should be possible, but the data is invalid, the resolver
+     * style should be used to determine an appropriate level of leniency, which
+     * may require throwing a {@code DateTimeException} or {@code ArithmeticException}.
+     * If no resolution is possible, the resolve method must return null.
      * <p>
-     * The {@link ResolverStyle} should be used by implementations to determine
-     * how to perform the resolve.
+     * When resolving time fields, the map will be altered and null returned.
+     * When resolving date fields, the date is normally returned from the method,
+     * with the map altered to remove the resolved fields. However, it would also
+     * be acceptable for the date fields to be resolved into other {@code ChronoField}
+     * instances that can produce a date, such as {@code EPOCH_DAY}.
+     * <p>
+     * The zone is not normally required for resolution, but is provided for completeness.
      * <p>
      * The default implementation must return null.
      *
-     * @param temporal  the temporal to resolve, not null
-     * @param value  the value of this field
+     * @param fieldValues  the map of fields to values, which can be updated, not null
+     * @param chronology  the effective chronology, not null
+     * @param zone  the effective zone, not null
      * @param resolverStyle  the requested type of resolve, not null
-     * @return a map of fields to update in the temporal, with a mapping to null
-     *  indicating a deletion. The whole map must be null if no resolving occurred
+     * @return the resolved date; null if resolving only changed the map,
+     *  or no resolve occurred
+     * @throws ArithmeticException if numeric overflow occurs
      * @throws DateTimeException if resolving results in an error. This must not be thrown
      *  by querying a field on the temporal without first checking if it is supported
-     * @throws ArithmeticException if numeric overflow occurs
      */
-    default Map<TemporalField, Long> resolve(
-            TemporalAccessor temporal, long value, ResolverStyle resolverStyle) {
+    default ChronoLocalDate resolve(
+            Map<TemporalField, Long> fieldValues, Chronology chronology,
+            ZoneId zone, ResolverStyle resolverStyle) {
         return null;
     }
 
+    /**
+     * Gets a descriptive name for the field.
+     * <p>
+     * The should be of the format 'BaseOfRange', such as 'MonthOfYear',
+     * unless the field has a range of {@code FOREVER}, when only
+     * the base unit is mentioned, such as 'Year' or 'Era'.
+     *
+     * @return the name of the field, not null
+     */
+    @Override
+    String toString();
+
+
 }