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 |
|
7 | /**
|
8 | * Common implementations of {@link TemporalQuery}.
|
9 | *
|
10 | * This class provides common implementations of {@link TemporalQuery}.
|
11 | * These queries are primarily used as optimizations, allowing the internals
|
12 | * of other objects to be extracted effectively. Note that application code
|
13 | * can also use the {@link from} method on most temporal
|
14 | * objects as a method reference matching the query interface, such as
|
15 | * {@link LocalDate::from} and {@link ZoneId::from}.
|
16 | *
|
17 | * There are two equivalent ways of using a {@link TemporalQuery}.
|
18 | * The first is to invoke the method on the interface directly.
|
19 | * The second is to use {@link TemporalAccessor#query}:
|
20 | * <pre>
|
21 | * // these two lines are equivalent, but the second approach is recommended
|
22 | * dateTime = query.queryFrom(dateTime);
|
23 | * dateTime = dateTime.query(query);
|
24 | * </pre>
|
25 | * It is recommended to use the second approach, {@link query},
|
26 | * as it is a lot clearer to read in code.
|
27 | *
|
28 | */
|
29 | export class TemporalQueries {
|
30 |
|
31 | /**
|
32 | * A strict query for the {@link ZoneId}.
|
33 | *
|
34 | * This queries a {@link TemporalAccessor} for the zone.
|
35 | * The zone is only returned if the date-time conceptually contains a {@link ZoneId}.
|
36 | * It will not be returned if the date-time only conceptually has an {@link ZoneOffset}.
|
37 | * Thus a {@link ZonedDateTime} will return the result of
|
38 | * {@link getZone}, but an {@link OffsetDateTime} will
|
39 | * return null.
|
40 | *
|
41 | * In most cases, applications should use {@link ZONE} as this query is too strict.
|
42 | *
|
43 | * The result from JDK classes implementing {@link TemporalAccessor} is as follows:
|
44 | * * * {@link LocalDate} returns null
|
45 | * * {@link LocalTime} returns null
|
46 | * * {@link LocalDateTime} returns null
|
47 | * * {@link ZonedDateTime} returns the associated zone
|
48 | * * {@link OffsetTime} returns null
|
49 | * * {@link OffsetDateTime} returns null
|
50 | * * {@link ChronoLocalDate} returns null
|
51 | * * {@link ChronoLocalDateTime} returns null
|
52 | * * {@link ChronoZonedDateTime} returns the associated zone
|
53 | * * {@link Era} returns null
|
54 | * * {@link DayOfWeek} returns null
|
55 | * * {@link Month} returns null
|
56 | * * {@link Year} returns null
|
57 | * * {@link YearMonth} returns null
|
58 | * * {@link MonthDay} returns null
|
59 | * * {@link ZoneOffset} returns null
|
60 | * * {@link Instant} returns null
|
61 | *
|
62 | * @return a query that can obtain the zone ID of a temporal, not null
|
63 | */
|
64 | static zoneId() {
|
65 | return TemporalQueries.ZONE_ID;
|
66 | }
|
67 |
|
68 | /**
|
69 | * A query for the {@link Chronology}.
|
70 | *
|
71 | * This queries a {@link TemporalAccessor} for the chronology.
|
72 | * If the target {@link TemporalAccessor} represents a date, or part of a date,
|
73 | * then it should return the chronology that the date is expressed in.
|
74 | * As a result of this definition, objects only representing time, such as
|
75 | * {@link LocalTime}, will return null.
|
76 | *
|
77 | * The result from js-joda classes implementing {@link TemporalAccessor} is as follows:
|
78 | *
|
79 | * * {@link LocalDate} returns * {@link IsoChronology.INSTANCE}
|
80 | * * {@link LocalTime} returns null (does not represent a date)
|
81 | * * {@link LocalDateTime} returns * {@link IsoChronology.INSTANCE}
|
82 | * * {@link ZonedDateTime} returns * {@link IsoChronology.INSTANCE}
|
83 | * * {@link OffsetTime} returns null (does not represent a date)
|
84 | * * {@link OffsetDateTime} returns * {@link IsoChronology.INSTANCE}
|
85 | * * {@link ChronoLocalDate} returns the associated chronology
|
86 | * * {@link ChronoLocalDateTime} returns the associated chronology
|
87 | * * {@link ChronoZonedDateTime} returns the associated chronology
|
88 | * * {@link Era} returns the associated chronology
|
89 | * * {@link DayOfWeek} returns null (shared across chronologies)
|
90 | * * {@link Month} returns * {@link IsoChronology.INSTANCE}
|
91 | * * {@link Year} returns * {@link IsoChronology.INSTANCE}
|
92 | * * {@link YearMonth} returns * {@link IsoChronology.INSTANCE}
|
93 | * * {@link MonthDay} returns null * {@link IsoChronology.INSTANCE}
|
94 | * * {@link ZoneOffset} returns null (does not represent a date)
|
95 | * * {@link Instant} returns null (does not represent a date)
|
96 | *
|
97 | * The method {@link Chronology#from} can be used as a
|
98 | * {@link TemporalQuery}
|
99 | * That method is equivalent to this query, except that it throws an
|
100 | * exception if a chronology cannot be obtained.
|
101 | *
|
102 | * @return {TemporalQuery} a query that can obtain the chronology of a temporal, not null
|
103 | */
|
104 | static chronology() {
|
105 | return TemporalQueries.CHRONO;
|
106 | }
|
107 |
|
108 | /**
|
109 | * A query for the smallest supported unit.
|
110 | *
|
111 | * This queries a {@link TemporalAccessor} for the time precision.
|
112 | * If the target {@link TemporalAccessor} represents a consistent or complete date-time,
|
113 | * date or time then this must return the smallest precision actually supported.
|
114 | * Note that fields such as {@link NANO_OF_DAY} and {@link NANO_OF_SECOND}
|
115 | * are defined to always return ignoring the precision, thus this is the only
|
116 | * way to find the actual smallest supported unit.
|
117 | * For example, were {@link GregorianCalendar} to implement {@link TemporalAccessor}
|
118 | * it would return a precision of {@link MILLIS}.
|
119 | *
|
120 | * The result from js-joda classes implementing {@link TemporalAccessor} is as follows:
|
121 | *
|
122 | * {@link LocalDate} returns {@link DAYS}
|
123 | * {@link LocalTime} returns {@link NANOS}
|
124 | * {@link LocalDateTime} returns {@link NANOS}
|
125 | * {@link ZonedDateTime} returns {@link NANOS}
|
126 | * {@link OffsetTime} returns {@link NANOS}
|
127 | * {@link OffsetDateTime} returns {@link NANOS}
|
128 | * {@link ChronoLocalDate} returns {@link DAYS}
|
129 | * {@link ChronoLocalDateTime} returns {@link NANOS}
|
130 | * {@link ChronoZonedDateTime} returns {@link NANOS}
|
131 | * {@link Era} returns {@link ERAS}
|
132 | * {@link DayOfWeek} returns {@link DAYS}
|
133 | * {@link Month} returns {@link MONTHS}
|
134 | * {@link Year} returns {@link YEARS}
|
135 | * {@link YearMonth} returns {@link MONTHS}
|
136 | * {@link MonthDay} returns null (does not represent a complete date or time)
|
137 | * {@link ZoneOffset} returns null (does not represent a date or time)
|
138 | * {@link Instant} returns {@link NANOS}
|
139 | *
|
140 | * @return a query that can obtain the precision of a temporal, not null
|
141 | */
|
142 | static precision() {
|
143 | return TemporalQueries.PRECISION;
|
144 | }
|
145 |
|
146 | /**
|
147 | * A lenient query for the {@link ZoneId}, falling back to the {@link ZoneOffset}.
|
148 | *
|
149 | * This queries a {@link TemporalAccessor} for the zone.
|
150 | * It first tries to obtain the zone, using {@link zoneId}.
|
151 | * If that is not found it tries to obtain the {@link offset}.
|
152 | *
|
153 | * In most cases, applications should use this query rather than {@link zoneId}.
|
154 | *
|
155 | * This query examines the {@link ChronoField#OFFSET_SECONDS}
|
156 | * field and uses it to create a {@link ZoneOffset}.
|
157 | *
|
158 | * The method {@link ZoneId#from} can be used as a
|
159 | * {@link TemporalQuery} via a method reference, {@link ZoneId::from}.
|
160 | * That method is equivalent to this query, except that it throws an
|
161 | * exception if a zone cannot be obtained.
|
162 | *
|
163 | * @return a query that can obtain the zone ID or offset of a temporal, not null
|
164 | */
|
165 | static zone() {
|
166 | return TemporalQueries.ZONE;
|
167 | }
|
168 |
|
169 | /**
|
170 | * A query for {@link ZoneOffset} returning null if not found.
|
171 | *
|
172 | * This returns a {@link TemporalQuery} that can be used to query a temporal
|
173 | * object for the offset. The query will return null if the temporal
|
174 | * object cannot supply an offset.
|
175 | *
|
176 | * The query implementation examines the {@link ChronoField#OFFSET_SECONDS}
|
177 | * field and uses it to create a {@link ZoneOffset}.
|
178 | *
|
179 | * The method {@link java.time.ZoneOffset#from} can be used as a
|
180 | * {@link TemporalQuery} via a method reference, {@link ZoneOffset::from}.
|
181 | * This query and {@link ZoneOffset::from} will return the same result if the
|
182 | * temporal object contains an offset. If the temporal object does not contain
|
183 | * an offset, then the method reference will throw an exception, whereas this
|
184 | * query will return null.
|
185 | *
|
186 | * @return a query that can obtain the offset of a temporal, not null
|
187 | */
|
188 | static offset() {
|
189 | return TemporalQueries.OFFSET;
|
190 | }
|
191 |
|
192 | /**
|
193 | * A query for {@link LocalDate} returning null if not found.
|
194 | *
|
195 | * This returns a {@link TemporalQuery} that can be used to query a temporal
|
196 | * object for the local date. The query will return null if the temporal
|
197 | * object cannot supply a local date.
|
198 | *
|
199 | * The query implementation examines the {@link ChronoField#EPOCH_DAY}
|
200 | * field and uses it to create a {@link LocalDate}.
|
201 | *
|
202 | * @return a query that can obtain the date of a temporal, not null
|
203 | */
|
204 | static localDate() {
|
205 | return TemporalQueries.LOCAL_DATE;
|
206 | }
|
207 |
|
208 | /**
|
209 | * A query for {@link LocalTime} returning null if not found.
|
210 | *
|
211 | * This returns a {@link TemporalQuery} that can be used to query a temporal
|
212 | * object for the local time. The query will return null if the temporal
|
213 | * object cannot supply a local time.
|
214 | *
|
215 | * The query implementation examines the {@link ChronoField#NANO_OF_DAY}
|
216 | * field and uses it to create a {@link LocalTime}.
|
217 | *
|
218 | * @return a query that can obtain the time of a temporal, not null
|
219 | */
|
220 | static localTime() {
|
221 | return TemporalQueries.LOCAL_TIME;
|
222 | }
|
223 | }
|