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

Print this page

        

@@ -60,12 +60,14 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 package java.time.temporal;
 
 import java.time.DateTimeException;
-import java.util.Comparator;
+import java.time.format.ResolverStyle;
+import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * A field of date-time, such as month-of-year or hour-of-minute.
  * <p>
  * Date and time is expressed using fields which partition the time-line into something

@@ -86,11 +88,11 @@
  * Implementations should be {@code Serializable} where possible.
  * An enum is as effective implementation choice.
  *
  * @since 1.8
  */
-public interface TemporalField extends Comparator<TemporalAccessor> {
+public interface TemporalField {
 
     /**
      * Gets a descriptive name for the field.
      * <p>
      * The should be of the format 'BaseOfRange', such as 'MonthOfYear',

@@ -100,10 +102,25 @@
      * @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.
+     *
+     * @param locale  the locale to use, not null
+     * @return the display name for the locale or the value of {@code getName},
+     *     not null
+     */
+    default String getDisplayName(Locale locale) {
+        Objects.requireNonNull(locale, "local");
+        return getName();
+    }
+
+    /**
      * Gets the unit that the field is measured in.
      * <p>
      * The unit of the field is the period that varies within the range.
      * For example, in the field 'MonthOfYear', the unit is 'Months'.
      * See also {@link #getRangeUnit()}.

@@ -124,32 +141,10 @@
      *
      * @return the period unit defining the range of the field, not null
      */
     TemporalUnit getRangeUnit();
 
-    //-----------------------------------------------------------------------
-    /**
-     * Compares the value of this field in two temporal objects.
-     * <p>
-     * All fields implement {@link Comparator} on {@link TemporalAccessor}.
-     * This allows a list of date-times to be compared using the value of a field.
-     * For example, you could sort a list of arbitrary temporal objects by the value of
-     * the month-of-year field - {@code Collections.sort(list, MONTH_OF_YEAR)}
-     * <p>
-     * The default implementation must behave equivalent to this code:
-     * <pre>
-     *  return Long.compare(temporal1.getLong(this), temporal2.getLong(this));
-     * </pre>
-     *
-     * @param temporal1  the first temporal object to compare, not null
-     * @param temporal2  the second temporal object to compare, not null
-     * @throws DateTimeException if unable to obtain the value for this field
-     */
-    public default int compare(TemporalAccessor temporal1, TemporalAccessor temporal2) {
-         return Long.compare(temporal1.getLong(this), temporal2.getLong(this));
-    }
-
     /**
      * Gets the range of valid values for the field.
      * <p>
      * All fields can be expressed as a {@code long} integer.
      * This method returns an object that describes the valid range for that value.

@@ -163,10 +158,39 @@
      */
     ValueRange range();
 
     //-----------------------------------------------------------------------
     /**
+     * Checks if this field represents a component of a date.
+     * <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.
+     *
+     * @return true if this field is a component of a date
+     */
+    default boolean isDateBased() {
+        return false;
+    }
+
+    /**
+     * 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.
+     *
+     * @return true if this field is a component of a time
+     */
+    default boolean isTimeBased() {
+        return false;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Checks if this field is supported by the temporal object.
      * <p>
      * This determines whether the temporal accessor supports this field.
      * If this returns false, the the temporal cannot be queried for this field.
      * <p>

@@ -211,15 +235,16 @@
      * It is recommended to use the second approach, {@code range(TemporalField)},
      * as it is a lot clearer to read in code.
      * <p>
      * Implementations should perform any queries or calculations using the fields
      * available in {@link ChronoField}.
-     * If the field is not supported a {@code DateTimeException} must be thrown.
+     * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown.
      *
      * @param temporal  the temporal object used to refine the result, not null
      * @return the range of valid values for this field, not null
      * @throws DateTimeException if the range for the field cannot be obtained
+     * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal
      */
     ValueRange rangeRefinedBy(TemporalAccessor temporal);
 
     /**
      * Gets the value of this field from the specified temporal object.

@@ -238,15 +263,16 @@
      * It is recommended to use the second approach, {@code getLong(TemporalField)},
      * as it is a lot clearer to read in code.
      * <p>
      * Implementations should perform any queries or calculations using the fields
      * available in {@link ChronoField}.
-     * If the field is not supported a {@code DateTimeException} must be thrown.
+     * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown.
      *
      * @param temporal  the temporal object to query, not null
      * @return the value of this field, not null
      * @throws DateTimeException if a value for the field cannot be obtained
+     * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal
      * @throws ArithmeticException if numeric overflow occurs
      */
     long getFrom(TemporalAccessor temporal);
 
     /**

@@ -274,21 +300,22 @@
      * It is recommended to use the second approach, {@code with(TemporalField)},
      * as it is a lot clearer to read in code.
      * <p>
      * Implementations should perform any queries or calculations using the fields
      * available in {@link ChronoField}.
-     * If the field is not supported a {@code DateTimeException} must be thrown.
+     * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown.
      * <p>
      * Implementations must not alter the specified temporal object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      *
      * @param <R>  the type of the Temporal object
      * @param temporal the temporal object to adjust, not null
      * @param newValue the new value of the field
      * @return the adjusted temporal object, not null
      * @throws DateTimeException if the field cannot be set
+     * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal
      * @throws ArithmeticException if numeric overflow occurs
      */
     <R extends Temporal> R adjustInto(R temporal, long newValue);
 
     /**

@@ -312,20 +339,25 @@
      * removed from the temporal. A null key must not be added to the result map.
      * <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.
      * <p>
+     * The {@link ResolverStyle} should be used by implementations to determine
+     * how to perform the resolve.
+     * <p>
      * The default implementation must return null.
      *
      * @param temporal  the temporal to resolve, not null
      * @param value  the value of this field
+     * @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
      * @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
      */
-    public default Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value) {
+    default Map<TemporalField, Long> resolve(
+            TemporalAccessor temporal, long value, ResolverStyle resolverStyle) {
         return null;
     }
 
 }