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

Print this page

        

@@ -61,10 +61,11 @@
  */
 package java.time.temporal;
 
 import java.time.DateTimeException;
 import java.time.ZoneId;
+import java.util.Objects;
 
 /**
  * Framework-level interface defining read-only access to a temporal object,
  * such as a date, time, offset or some combination of these.
  * <p>

@@ -78,12 +79,12 @@
  * simple examples of fields, but they also include instant and offsets.
  * See {@link ChronoField} for the standard set of fields.
  * <p>
  * Two pieces of date/time information cannot be represented by numbers,
  * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}.
- * These can be accessed via {@link #query(TemporalQuery) queries} using
- * the static methods defined on {@link Queries}.
+ * These can be accessed via {@linkplain #query(TemporalQuery) queries} using
+ * the static methods defined on {@link TemporalQuery}.
  * <p>
  * A sub-interface, {@link Temporal}, extends this definition to one that also
  * supports adjustment and manipulation on more complete temporal objects.
  * <p>
  * This interface is a framework-level interface that should not be widely

@@ -137,11 +138,11 @@
      * could be values within the range that are invalid for the field.
      *
      * <h3>Specification for implementors</h3>
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then the range of the field must be returned.
-     * If unsupported, then a {@code DateTimeException} must be thrown.
+     * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessorl)}
      * passing {@code this} as the argument.
      * <p>

@@ -151,26 +152,28 @@
      * <pre>
      *  if (field instanceof ChronoField) {
      *    if (isSupported(field)) {
      *      return field.range();
      *    }
-     *    throw new DateTimeException("Unsupported field: " + field.getName());
+     *    throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
      *  }
      *  return field.rangeRefinedBy(this);
      * </pre>
      *
      * @param field  the field to query the range for, not null
      * @return the range of valid values for the field, not null
      * @throws DateTimeException if the range for the field cannot be obtained
+     * @throws UnsupportedTemporalTypeException if the field is not supported
      */
-    public default ValueRange range(TemporalField field) {
+    default ValueRange range(TemporalField field) {
         if (field instanceof ChronoField) {
             if (isSupported(field)) {
                 return field.range();
             }
-            throw new DateTimeException("Unsupported field: " + field.getName());
+            throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
         }
+        Objects.requireNonNull(field, "field");
         return field.rangeRefinedBy(this);
     }
 
     /**
      * Gets the value of the specified field as an {@code int}.

@@ -182,32 +185,44 @@
      *
      * <h3>Specification for implementors</h3>
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported and has an {@code int} range, then the value of
      * the field must be returned.
-     * If unsupported, then a {@code DateTimeException} must be thrown.
+     * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument.
      * <p>
-     * Implementations must not alter either this object.
+     * Implementations must not alter this object.
      * <p>
      * The default implementation must behave equivalent to this code:
      * <pre>
+     *  if (range(field).isIntValue()) {
      *  return range(field).checkValidIntValue(getLong(field), field);
+     *  }
+     *  throw new UnsupportedTemporalTypeException("Invalid field " + field + " + for get() method, use getLong() instead");
      * </pre>
      *
      * @param field  the field to get, not null
      * @return the value for the field, within the valid range of values
-     * @throws DateTimeException if a value for the field cannot be obtained
-     * @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
-     * @throws DateTimeException if the value is outside the range of valid values for the field
+     * @throws DateTimeException if a value for the field cannot be obtained or
+     *         the value is outside the range of valid values for the field
+     * @throws UnsupportedTemporalTypeException if the field is not supported or
+     *         the range of values exceeds an {@code int}
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public default int get(TemporalField field) {
-        return range(field).checkValidIntValue(getLong(field), field);
+    default int get(TemporalField field) {
+        ValueRange range = range(field);
+        if (range.isIntValue() == false) {
+            throw new UnsupportedTemporalTypeException("Invalid field " + field + " + for get() method, use getLong() instead");
+        }
+        long value = getLong(field);
+        if (range.isValidValue(value) == false) {
+            throw new DateTimeException("Invalid value for " + field + " (valid values " + range + "): " + value);
+        }
+        return (int) value;
     }
 
     /**
      * Gets the value of the specified field as a {@code long}.
      * <p>

@@ -217,21 +232,22 @@
      * some other reason, an exception will be thrown.
      *
      * <h3>Specification for implementors</h3>
      * Implementations must check and handle all fields defined in {@link ChronoField}.
      * If the field is supported, then the value of the field must be returned.
-     * If unsupported, then a {@code DateTimeException} must be thrown.
+     * If unsupported, then an {@code UnsupportedTemporalTypeException} must be thrown.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument.
      * <p>
      * Implementations must not alter either this object.
      *
      * @param field  the field to get, not null
      * @return the value for the field
      * @throws DateTimeException if a value for the field cannot be obtained
+     * @throws UnsupportedTemporalTypeException if the field is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     long getLong(TemporalField field);
 
     /**

@@ -245,17 +261,17 @@
      * Examples might be a query that checks if the date is the day before February 29th
      * in a leap year, or calculates the number of days to your next birthday.
      * <p>
      * The most common query implementations are method references, such as
      * {@code LocalDate::from} and {@code ZoneId::from}.
-     * Further implementations are on {@link Queries}.
-     * Queries may also be defined by applications.
+     * Additional implementations are provided as static methods on {@link TemporalQuery}.
      *
      * <h3>Specification for implementors</h3>
      * The default implementation must behave equivalent to this code:
      * <pre>
-     *  if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
+     *  if (query == TemporalQuery.zoneId() ||
+     *        query == TemporalQuery.chronology() || query == TemporalQuery.precision()) {
      *    return null;
      *  }
      *  return query.queryFrom(this);
      * </pre>
      * Future versions are permitted to add further queries to the if statement.

@@ -268,11 +284,11 @@
      * If the implementation can supply a value for one of the queries listed in the
      * if statement of the default implementation, then it must do so.
      * For example, an application-defined {@code HourMin} class storing the hour
      * and minute must override this method as follows:
      * <pre>
-     *  if (query == Queries.precision()) {
+     *  if (query == TemporalQuery.precision()) {
      *    return MINUTES;
      *  }
      *  return TemporalAccessor.super.query(query);
      * </pre>
      *

@@ -280,12 +296,12 @@
      * @param query  the query to invoke, not null
      * @return the query result, null may be returned (defined by the query)
      * @throws DateTimeException if unable to query
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
+    default <R> R query(TemporalQuery<R> query) {
+        if (query == TemporalQuery.zoneId() || query == TemporalQuery.chronology() || query == TemporalQuery.precision()) {
             return null;
         }
         return query.queryFrom(this);
     }