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

Print this page




  62 package java.time.temporal;
  63 
  64 import java.time.DateTimeException;
  65 import java.time.ZoneId;
  66 
  67 /**
  68  * Framework-level interface defining read-only access to a temporal object,
  69  * such as a date, time, offset or some combination of these.
  70  * <p>
  71  * This is the base interface type for date, time and offset objects.
  72  * It is implemented by those classes that can provide information
  73  * as {@linkplain TemporalField fields} or {@linkplain TemporalQuery queries}.
  74  * <p>
  75  * Most date and time information can be represented as a number.
  76  * These are modeled using {@code TemporalField} with the number held using
  77  * a {@code long} to handle large values. Year, month and day-of-month are
  78  * simple examples of fields, but they also include instant and offsets.
  79  * See {@link ChronoField} for the standard set of fields.
  80  * <p>
  81  * Two pieces of date/time information cannot be represented by numbers,
  82  * the {@linkplain Chrono chronology} and the {@linkplain ZoneId time-zone}.
  83  * These can be accessed via {@link #query(TemporalQuery) queries} using
  84  * the static methods defined on {@link Queries}.
  85  * <p>
  86  * A sub-interface, {@link Temporal}, extends this definition to one that also
  87  * supports adjustment and manipulation on more complete temporal objects.
  88  * <p>
  89  * This interface is a framework-level interface that should not be widely
  90  * used in application code. Instead, applications should create and pass
  91  * around instances of concrete types, such as {@code LocalDate}.
  92  * There are many reasons for this, part of which is that implementations
  93  * of this interface may be in calendar systems other than ISO.
  94  * See {@link ChronoLocalDate} for a fuller discussion of the issues.
  95  *
  96  * <h3>Specification for implementors</h3>
  97  * This interface places no restrictions on the mutability of implementations,
  98  * however immutability is strongly recommended.
  99  *
 100  * @since 1.8
 101  */
 102 public interface TemporalAccessor {
 103 
 104     /**
 105      * Checks if the specified field is supported.
 106      * <p>
 107      * This checks if the date-time can be queried for the specified field.
 108      * If false, then calling the {@link #range(TemporalField) range} and {@link #get(TemporalField) get}
 109      * methods will throw an exception.
 110      *
 111      * <h3>Specification for implementors</h3>
 112      * Implementations must check and handle all fields defined in {@link ChronoField}.
 113      * If the field is supported, then true is returned, otherwise false
 114      * <p>
 115      * If the field is not a {@code ChronoField}, then the result of this method
 116      * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
 117      * passing {@code this} as the argument.
 118      * <p>
 119      * Implementations must not alter either this object.
 120      *
 121      * @param field  the field to check, null returns false
 122      * @return true if this date-time can be queried for the field, false if not
 123      */
 124     boolean isSupported(TemporalField field);
 125 
 126     /**
 127      * Gets the range of valid values for the specified field.
 128      * <p>
 129      * All fields can be expressed as a {@code long} integer.
 130      * This method returns an object that describes the valid range for that value.
 131      * The value of this temporal object is used to enhance the accuracy of the returned range.
 132      * If the date-time cannot return the range, because the field is unsupported or for
 133      * some other reason, an exception will be thrown.
 134      * <p>
 135      * Note that the result only describes the minimum and maximum valid values
 136      * and it is important not to read too much into them. For example, there
 137      * could be values within the range that are invalid for the field.
 138      *
 139      * <h3>Specification for implementors</h3>
 140      * Implementations must check and handle all fields defined in {@link ChronoField}.
 141      * If the field is supported, then the range of the field must be returned.
 142      * If unsupported, then a {@code DateTimeException} must be thrown.
 143      * <p>
 144      * If the field is not a {@code ChronoField}, then the result of this method
 145      * is obtained by invoking {@code TemporalField.doRange(TemporalAccessorl)}
 146      * passing {@code this} as the argument.
 147      * <p>
 148      * Implementations must not alter either this object.
 149      * <p>
 150      * The default implementation must behave equivalent to this code:
 151      * <pre>
 152      *  if (field instanceof ChronoField) {
 153      *    if (isSupported(field)) {
 154      *      return field.range();
 155      *    }
 156      *    throw new DateTimeException("Unsupported field: " + field.getName());
 157      *  }
 158      *  return field.doRange(this);
 159      * </pre>
 160      *
 161      * @param field  the field to query the range for, not null
 162      * @return the range of valid values for the field, not null
 163      * @throws DateTimeException if the range for the field cannot be obtained
 164      */
 165     public default ValueRange range(TemporalField field) {
 166         if (field instanceof ChronoField) {
 167             if (isSupported(field)) {
 168                 return field.range();
 169             }
 170             throw new DateTimeException("Unsupported field: " + field.getName());
 171         }
 172         return field.doRange(this);
 173     }
 174 
 175     /**
 176      * Gets the value of the specified field as an {@code int}.
 177      * <p>
 178      * This queries the date-time for the value for the specified field.
 179      * The returned value will always be within the valid range of values for the field.
 180      * If the date-time cannot return the value, because the field is unsupported or for
 181      * some other reason, an exception will be thrown.
 182      *
 183      * <h3>Specification for implementors</h3>
 184      * Implementations must check and handle all fields defined in {@link ChronoField}.
 185      * If the field is supported and has an {@code int} range, then the value of
 186      * the field must be returned.
 187      * If unsupported, then a {@code DateTimeException} must be thrown.
 188      * <p>
 189      * If the field is not a {@code ChronoField}, then the result of this method
 190      * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
 191      * passing {@code this} as the argument.
 192      * <p>
 193      * Implementations must not alter either this object.
 194      * <p>
 195      * The default implementation must behave equivalent to this code:
 196      * <pre>
 197      *  return range(field).checkValidIntValue(getLong(field), field);
 198      * </pre>
 199      *
 200      * @param field  the field to get, not null
 201      * @return the value for the field, within the valid range of values
 202      * @throws DateTimeException if a value for the field cannot be obtained
 203      * @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
 204      * @throws DateTimeException if the value is outside the range of valid values for the field
 205      * @throws ArithmeticException if numeric overflow occurs
 206      */
 207     public default int get(TemporalField field) {
 208         return range(field).checkValidIntValue(getLong(field), field);
 209     }
 210 
 211     /**
 212      * Gets the value of the specified field as a {@code long}.
 213      * <p>
 214      * This queries the date-time for the value for the specified field.
 215      * The returned value may be outside the valid range of values for the field.
 216      * If the date-time cannot return the value, because the field is unsupported or for
 217      * some other reason, an exception will be thrown.
 218      *
 219      * <h3>Specification for implementors</h3>
 220      * Implementations must check and handle all fields defined in {@link ChronoField}.
 221      * If the field is supported, then the value of the field must be returned.
 222      * If unsupported, then a {@code DateTimeException} must be thrown.
 223      * <p>
 224      * If the field is not a {@code ChronoField}, then the result of this method
 225      * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
 226      * passing {@code this} as the argument.
 227      * <p>
 228      * Implementations must not alter either this object.
 229      *
 230      * @param field  the field to get, not null
 231      * @return the value for the field
 232      * @throws DateTimeException if a value for the field cannot be obtained
 233      * @throws ArithmeticException if numeric overflow occurs
 234      */
 235     long getLong(TemporalField field);
 236 
 237     /**
 238      * Queries this date-time.
 239      * <p>
 240      * This queries this date-time using the specified query strategy object.
 241      * <p>
 242      * Queries are a key tool for extracting information from date-times.
 243      * They exists to externalize the process of querying, permitting different
 244      * approaches, as per the strategy design pattern.
 245      * Examples might be a query that checks if the date is the day before February 29th
 246      * in a leap year, or calculates the number of days to your next birthday.
 247      * <p>
 248      * The most common query implementations are method references, such as
 249      * {@code LocalDate::from} and {@code ZoneId::from}.
 250      * Further implementations are on {@link Queries}.
 251      * Queries may also be defined by applications.
 252      *
 253      * <h3>Specification for implementors</h3>
 254      * The default implementation must behave equivalent to this code:
 255      * <pre>
 256      *  if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
 257      *    return null;
 258      *  }
 259      *  return query.queryFrom(this);
 260      * </pre>
 261      * Future versions are permitted to add further queries to the if statement.
 262      * <p>
 263      * All classes implementing this interface and overriding this method must call
 264      * {@code TemporalAccessor.super.query(query)}. JDK classes may avoid calling
 265      * super if they provide behavior equivalent to the default behaviour, however
 266      * non-JDK classes may not utilize this optimization and must call {@code super}.
 267      * <p>
 268      * If the implementation can supply a value for one of the queries listed in the
 269      * if statement of the default implementation, then it must do so.
 270      * For example, an application-defined {@code HourMin} class storing the hour
 271      * and minute must override this method as follows:
 272      * <pre>
 273      *  if (query == Queries.precision()) {
 274      *    return MINUTES;
 275      *  }
 276      *  return TemporalAccessor.super.query(query);
 277      * </pre>
 278      *
 279      * @param <R> the type of the result
 280      * @param query  the query to invoke, not null
 281      * @return the query result, null may be returned (defined by the query)
 282      * @throws DateTimeException if unable to query
 283      * @throws ArithmeticException if numeric overflow occurs
 284      */
 285     public default <R> R query(TemporalQuery<R> query) {
 286         if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
 287             return null;
 288         }
 289         return query.queryFrom(this);
 290     }
 291 
 292 }


  62 package java.time.temporal;
  63 
  64 import java.time.DateTimeException;
  65 import java.time.ZoneId;
  66 
  67 /**
  68  * Framework-level interface defining read-only access to a temporal object,
  69  * such as a date, time, offset or some combination of these.
  70  * <p>
  71  * This is the base interface type for date, time and offset objects.
  72  * It is implemented by those classes that can provide information
  73  * as {@linkplain TemporalField fields} or {@linkplain TemporalQuery queries}.
  74  * <p>
  75  * Most date and time information can be represented as a number.
  76  * These are modeled using {@code TemporalField} with the number held using
  77  * a {@code long} to handle large values. Year, month and day-of-month are
  78  * simple examples of fields, but they also include instant and offsets.
  79  * See {@link ChronoField} for the standard set of fields.
  80  * <p>
  81  * Two pieces of date/time information cannot be represented by numbers,
  82  * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}.
  83  * These can be accessed via {@link #query(TemporalQuery) queries} using
  84  * the static methods defined on {@link Queries}.
  85  * <p>
  86  * A sub-interface, {@link Temporal}, extends this definition to one that also
  87  * supports adjustment and manipulation on more complete temporal objects.
  88  * <p>
  89  * This interface is a framework-level interface that should not be widely
  90  * used in application code. Instead, applications should create and pass
  91  * around instances of concrete types, such as {@code LocalDate}.
  92  * There are many reasons for this, part of which is that implementations
  93  * of this interface may be in calendar systems other than ISO.
  94  * See {@link java.time.chrono.ChronoLocalDate} for a fuller discussion of the issues.
  95  *
  96  * <h3>Specification for implementors</h3>
  97  * This interface places no restrictions on the mutability of implementations,
  98  * however immutability is strongly recommended.
  99  *
 100  * @since 1.8
 101  */
 102 public interface TemporalAccessor {
 103 
 104     /**
 105      * Checks if the specified field is supported.
 106      * <p>
 107      * This checks if the date-time can be queried for the specified field.
 108      * If false, then calling the {@link #range(TemporalField) range} and {@link #get(TemporalField) get}
 109      * methods will throw an exception.
 110      *
 111      * <h3>Specification for implementors</h3>
 112      * Implementations must check and handle all fields defined in {@link ChronoField}.
 113      * If the field is supported, then true is returned, otherwise false
 114      * <p>
 115      * If the field is not a {@code ChronoField}, then the result of this method
 116      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
 117      * passing {@code this} as the argument.
 118      * <p>
 119      * Implementations must not alter either this object.
 120      *
 121      * @param field  the field to check, null returns false
 122      * @return true if this date-time can be queried for the field, false if not
 123      */
 124     boolean isSupported(TemporalField field);
 125 
 126     /**
 127      * Gets the range of valid values for the specified field.
 128      * <p>
 129      * All fields can be expressed as a {@code long} integer.
 130      * This method returns an object that describes the valid range for that value.
 131      * The value of this temporal object is used to enhance the accuracy of the returned range.
 132      * If the date-time cannot return the range, because the field is unsupported or for
 133      * some other reason, an exception will be thrown.
 134      * <p>
 135      * Note that the result only describes the minimum and maximum valid values
 136      * and it is important not to read too much into them. For example, there
 137      * could be values within the range that are invalid for the field.
 138      *
 139      * <h3>Specification for implementors</h3>
 140      * Implementations must check and handle all fields defined in {@link ChronoField}.
 141      * If the field is supported, then the range of the field must be returned.
 142      * If unsupported, then a {@code DateTimeException} must be thrown.
 143      * <p>
 144      * If the field is not a {@code ChronoField}, then the result of this method
 145      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessorl)}
 146      * passing {@code this} as the argument.
 147      * <p>
 148      * Implementations must not alter either this object.
 149      * <p>
 150      * The default implementation must behave equivalent to this code:
 151      * <pre>
 152      *  if (field instanceof ChronoField) {
 153      *    if (isSupported(field)) {
 154      *      return field.range();
 155      *    }
 156      *    throw new DateTimeException("Unsupported field: " + field.getName());
 157      *  }
 158      *  return field.rangeRefinedBy(this);
 159      * </pre>
 160      *
 161      * @param field  the field to query the range for, not null
 162      * @return the range of valid values for the field, not null
 163      * @throws DateTimeException if the range for the field cannot be obtained
 164      */
 165     public default ValueRange range(TemporalField field) {
 166         if (field instanceof ChronoField) {
 167             if (isSupported(field)) {
 168                 return field.range();
 169             }
 170             throw new DateTimeException("Unsupported field: " + field.getName());
 171         }
 172         return field.rangeRefinedBy(this);
 173     }
 174 
 175     /**
 176      * Gets the value of the specified field as an {@code int}.
 177      * <p>
 178      * This queries the date-time for the value for the specified field.
 179      * The returned value will always be within the valid range of values for the field.
 180      * If the date-time cannot return the value, because the field is unsupported or for
 181      * some other reason, an exception will be thrown.
 182      *
 183      * <h3>Specification for implementors</h3>
 184      * Implementations must check and handle all fields defined in {@link ChronoField}.
 185      * If the field is supported and has an {@code int} range, then the value of
 186      * the field must be returned.
 187      * If unsupported, then a {@code DateTimeException} must be thrown.
 188      * <p>
 189      * If the field is not a {@code ChronoField}, then the result of this method
 190      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 191      * passing {@code this} as the argument.
 192      * <p>
 193      * Implementations must not alter either this object.
 194      * <p>
 195      * The default implementation must behave equivalent to this code:
 196      * <pre>
 197      *  return range(field).checkValidIntValue(getLong(field), field);
 198      * </pre>
 199      *
 200      * @param field  the field to get, not null
 201      * @return the value for the field, within the valid range of values
 202      * @throws DateTimeException if a value for the field cannot be obtained
 203      * @throws DateTimeException if the range of valid values for the field exceeds an {@code int}
 204      * @throws DateTimeException if the value is outside the range of valid values for the field
 205      * @throws ArithmeticException if numeric overflow occurs
 206      */
 207     public default int get(TemporalField field) {
 208         return range(field).checkValidIntValue(getLong(field), field);
 209     }
 210 
 211     /**
 212      * Gets the value of the specified field as a {@code long}.
 213      * <p>
 214      * This queries the date-time for the value for the specified field.
 215      * The returned value may be outside the valid range of values for the field.
 216      * If the date-time cannot return the value, because the field is unsupported or for
 217      * some other reason, an exception will be thrown.
 218      *
 219      * <h3>Specification for implementors</h3>
 220      * Implementations must check and handle all fields defined in {@link ChronoField}.
 221      * If the field is supported, then the value of the field must be returned.
 222      * If unsupported, then a {@code DateTimeException} must be thrown.
 223      * <p>
 224      * If the field is not a {@code ChronoField}, then the result of this method
 225      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 226      * passing {@code this} as the argument.
 227      * <p>
 228      * Implementations must not alter either this object.
 229      *
 230      * @param field  the field to get, not null
 231      * @return the value for the field
 232      * @throws DateTimeException if a value for the field cannot be obtained
 233      * @throws ArithmeticException if numeric overflow occurs
 234      */
 235     long getLong(TemporalField field);
 236 
 237     /**
 238      * Queries this date-time.
 239      * <p>
 240      * This queries this date-time using the specified query strategy object.
 241      * <p>
 242      * Queries are a key tool for extracting information from date-times.
 243      * They exists to externalize the process of querying, permitting different
 244      * approaches, as per the strategy design pattern.
 245      * Examples might be a query that checks if the date is the day before February 29th
 246      * in a leap year, or calculates the number of days to your next birthday.
 247      * <p>
 248      * The most common query implementations are method references, such as
 249      * {@code LocalDate::from} and {@code ZoneId::from}.
 250      * Further implementations are on {@link Queries}.
 251      * Queries may also be defined by applications.
 252      *
 253      * <h3>Specification for implementors</h3>
 254      * The default implementation must behave equivalent to this code:
 255      * <pre>
 256      *  if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
 257      *    return null;
 258      *  }
 259      *  return query.queryFrom(this);
 260      * </pre>
 261      * Future versions are permitted to add further queries to the if statement.
 262      * <p>
 263      * All classes implementing this interface and overriding this method must call
 264      * {@code TemporalAccessor.super.query(query)}. JDK classes may avoid calling
 265      * super if they provide behavior equivalent to the default behaviour, however
 266      * non-JDK classes may not utilize this optimization and must call {@code super}.
 267      * <p>
 268      * If the implementation can supply a value for one of the queries listed in the
 269      * if statement of the default implementation, then it must do so.
 270      * For example, an application-defined {@code HourMin} class storing the hour
 271      * and minute must override this method as follows:
 272      * <pre>
 273      *  if (query == Queries.precision()) {
 274      *    return MINUTES;
 275      *  }
 276      *  return TemporalAccessor.super.query(query);
 277      * </pre>
 278      *
 279      * @param <R> the type of the result
 280      * @param query  the query to invoke, not null
 281      * @return the query result, null may be returned (defined by the query)
 282      * @throws DateTimeException if unable to query
 283      * @throws ArithmeticException if numeric overflow occurs
 284      */
 285     public default <R> R query(TemporalQuery<R> query) {
 286         if (query == Queries.zoneId() || query == Queries.chronology() || query == Queries.precision()) {
 287             return null;
 288         }
 289         return query.queryFrom(this);
 290     }
 291 
 292 }