/**
|
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
|
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
|
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
|
*/
|
|
import { UnsupportedTemporalTypeException } from '../errors';
|
import { abstractMethodFail } from '../assert';
|
|
import { ChronoField } from './ChronoField';
|
import { TemporalQueries } from './TemporalQueries';
|
|
export class TemporalAccessor {
|
/**
|
* Queries this date-time.
|
*
|
* This queries this date-time using the specified query strategy object.
|
*
|
* Queries are a key tool for extracting information from date-times.
|
* They exists to externalize the process of querying, permitting different
|
* approaches, as per the strategy design pattern.
|
* 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.
|
*
|
* The most common query implementations are method references, such as
|
* {@link LocalDate::from} and {@link ZoneId::from}.
|
* Further implementations are on {@link TemporalQueries}.
|
* Queries may also be defined by applications.
|
*
|
* @implSpec
|
* Implementations of this method must behave as follows:
|
* <pre>
|
if (query == TemporalQueries.zoneId()
|
|| query == TemporalQueries.chronology()
|
|| query == TemporalQueries.precision()) {
|
return null;
|
}
|
return query.queryFrom(this);
|
* </pre>
|
*
|
* @param {TemporalQuery} 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
|
*/
|
query(query) {
|
if (query === TemporalQueries.zoneId()
|
|| query === TemporalQueries.chronology()
|
|| query === TemporalQueries.precision()) {
|
return null;
|
}
|
return query.queryFrom(this);
|
}
|
|
/**
|
* Gets the value of the specified field as an `int`.
|
*
|
* This queries the date-time for the value for the specified field.
|
* The returned value will always be within the valid range of values for the field.
|
* If the date-time cannot return the value, because the field is unsupported or for
|
* some other reason, an exception will be thrown.
|
*
|
* ### Specification for implementors
|
*
|
* Implementations must check and handle all fields defined in {@link ChronoField}.
|
* If the field is supported and has an `int` range, then the value of
|
* the field must be returned.
|
* If unsupported, then a {@link DateTimeException} must be thrown.
|
*
|
* If the field is not a {@link ChronoField}, then the result of this method
|
* is obtained by invoking {@link TemporalField.getFrom}
|
* passing `this` as the argument.
|
*
|
* Implementations must not alter either this object.
|
*
|
* @param {TemporalField} field - the field to get, not null
|
* @return {number} 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 `int`
|
* @throws DateTimeException if the value is outside the range of valid values for the field
|
* @throws ArithmeticException if numeric overflow occurs
|
*/
|
get(field) {
|
return this.range(field).checkValidIntValue(this.getLong(field), field);
|
}
|
|
// eslint-disable-next-line no-unused-vars
|
getLong(field) {
|
abstractMethodFail('getLong');
|
}
|
|
/**
|
* Gets the range of valid values for the specified field.
|
*
|
* All fields can be expressed as a `long` integer.
|
* This method returns an object that describes the valid range for that value.
|
* The value of this temporal object is used to enhance the accuracy of the returned range.
|
* If the date-time cannot return the range, because the field is unsupported or for
|
* some other reason, an exception will be thrown.
|
*
|
* Note that the result only describes the minimum and maximum valid values
|
* and it is important not to read too much into them. For example, there
|
* could be values within the range that are invalid for the field.
|
*
|
* ### Specification for implementors
|
*
|
* 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 {@link DateTimeException} must be thrown.
|
*
|
* If the field is not a {@link ChronoField}, then the result of this method
|
* is obtained by invoking {@link TemporalField.rangeRefinedBy}
|
* passing `this` as the argument.
|
*
|
* Implementations must not alter either this object.
|
*
|
* @param {TemporalField} field the field to query the range for, not null
|
* @return {ValueRange} the range of valid values for the field, not null
|
* @throws DateTimeException if the range for the field cannot be obtained
|
*/
|
range(field) {
|
if (field instanceof ChronoField) {
|
if (this.isSupported(field)) {
|
return field.range();
|
}
|
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
|
}
|
return field.rangeRefinedBy(this);
|
}
|
|
// eslint-disable-next-line no-unused-vars
|
isSupported(field) {
|
abstractMethodFail('isSupported');
|
}
|
}
|