UNPKG

5.43 kBJavaScriptView Raw
1/**
2 * @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
3 * @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
4 * @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
5 */
6
7import {UnsupportedTemporalTypeException} from '../errors';
8
9import {ChronoField} from './ChronoField';
10import {TemporalQueries} from './TemporalQueries';
11
12export class TemporalAccessor {
13 /**
14 * Queries this date-time.
15 *
16 * This queries this date-time using the specified query strategy object.
17 *
18 * Queries are a key tool for extracting information from date-times.
19 * They exists to externalize the process of querying, permitting different
20 * approaches, as per the strategy design pattern.
21 * Examples might be a query that checks if the date is the day before February 29th
22 * in a leap year, or calculates the number of days to your next birthday.
23 *
24 * The most common query implementations are method references, such as
25 * {@link LocalDate::from} and {@link ZoneId::from}.
26 * Further implementations are on {@link TemporalQueries}.
27 * Queries may also be defined by applications.
28 *
29 * @implSpec
30 * Implementations of this method must behave as follows:
31 * <pre>
32 if (query == TemporalQueries.zoneId()
33 || query == TemporalQueries.chronology()
34 || query == TemporalQueries.precision()) {
35 return null;
36 }
37 return query.queryFrom(this);
38 * </pre>
39 *
40 * @param {TemporalQuery} query the query to invoke, not null
41 * @return the query result, null may be returned (defined by the query)
42 * @throws DateTimeException if unable to query
43 * @throws ArithmeticException if numeric overflow occurs
44 */
45 query(query) {
46 if (query === TemporalQueries.zoneId()
47 || query === TemporalQueries.chronology()
48 || query === TemporalQueries.precision()) {
49 return null;
50 }
51 return query.queryFrom(this);
52 }
53
54 /**
55 * Gets the value of the specified field as an `int`.
56 *
57 * This queries the date-time for the value for the specified field.
58 * The returned value will always be within the valid range of values for the field.
59 * If the date-time cannot return the value, because the field is unsupported or for
60 * some other reason, an exception will be thrown.
61 *
62 * ### Specification for implementors
63 *
64 * Implementations must check and handle all fields defined in {@link ChronoField}.
65 * If the field is supported and has an `int` range, then the value of
66 * the field must be returned.
67 * If unsupported, then a {@link DateTimeException} must be thrown.
68 *
69 * If the field is not a {@link ChronoField}, then the result of this method
70 * is obtained by invoking {@link TemporalField.getFrom}
71 * passing `this` as the argument.
72 *
73 * Implementations must not alter either this object.
74 *
75 * @param {TemporalField} field - the field to get, not null
76 * @return {number} the value for the field, within the valid range of values
77 * @throws DateTimeException if a value for the field cannot be obtained
78 * @throws DateTimeException if the range of valid values for the field exceeds an `int`
79 * @throws DateTimeException if the value is outside the range of valid values for the field
80 * @throws ArithmeticException if numeric overflow occurs
81 */
82 get(field) {
83 return this.range(field).checkValidIntValue(this.getLong(field), field);
84 }
85
86 /**
87 * Gets the range of valid values for the specified field.
88 *
89 * All fields can be expressed as a `long` integer.
90 * This method returns an object that describes the valid range for that value.
91 * The value of this temporal object is used to enhance the accuracy of the returned range.
92 * If the date-time cannot return the range, because the field is unsupported or for
93 * some other reason, an exception will be thrown.
94 *
95 * Note that the result only describes the minimum and maximum valid values
96 * and it is important not to read too much into them. For example, there
97 * could be values within the range that are invalid for the field.
98 *
99 * ### Specification for implementors
100 *
101 * Implementations must check and handle all fields defined in {@link ChronoField}.
102 * If the field is supported, then the range of the field must be returned.
103 * If unsupported, then a {@link DateTimeException} must be thrown.
104 *
105 * If the field is not a {@link ChronoField}, then the result of this method
106 * is obtained by invoking {@link TemporalField.rangeRefinedBy}
107 * passing `this` as the argument.
108 *
109 * Implementations must not alter either this object.
110 *
111 * @param {TemporalField} field the field to query the range for, not null
112 * @return {ValueRange} the range of valid values for the field, not null
113 * @throws DateTimeException if the range for the field cannot be obtained
114 */
115 range(field) {
116 if (field instanceof ChronoField) {
117 if (this.isSupported(field)) {
118 return field.range();
119 }
120 throw new UnsupportedTemporalTypeException('Unsupported field: ' + field);
121 }
122 return field.rangeRefinedBy(this);
123 }
124
125}