author | rriggs |
Thu, 17 Oct 2013 10:37:23 -0400 | |
changeset 20873 | e91d5b1cb8e6 |
parent 20795 | 8ec9e5b79828 |
child 24256 | da9a41004459 |
permissions | -rw-r--r-- |
15658 | 1 |
/* |
2 |
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. |
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
/* |
|
27 |
* This file is available under and governed by the GNU General Public |
|
28 |
* License version 2 only, as published by the Free Software Foundation. |
|
29 |
* However, the following notice accompanied the original version of this |
|
30 |
* file: |
|
31 |
* |
|
32 |
* Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos |
|
33 |
* |
|
34 |
* All rights reserved. |
|
35 |
* |
|
36 |
* Redistribution and use in source and binary forms, with or without |
|
37 |
* modification, are permitted provided that the following conditions are met: |
|
38 |
* |
|
39 |
* * Redistributions of source code must retain the above copyright notice, |
|
40 |
* this list of conditions and the following disclaimer. |
|
41 |
* |
|
42 |
* * Redistributions in binary form must reproduce the above copyright notice, |
|
43 |
* this list of conditions and the following disclaimer in the documentation |
|
44 |
* and/or other materials provided with the distribution. |
|
45 |
* |
|
46 |
* * Neither the name of JSR-310 nor the names of its contributors |
|
47 |
* may be used to endorse or promote products derived from this software |
|
48 |
* without specific prior written permission. |
|
49 |
* |
|
50 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
51 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
52 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
53 |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
54 |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
55 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
56 |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
57 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
58 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
59 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
60 |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
61 |
*/ |
|
62 |
package java.time.chrono; |
|
63 |
||
64 |
import java.time.Clock; |
|
65 |
import java.time.DateTimeException; |
|
66 |
import java.time.Instant; |
|
67 |
import java.time.LocalDate; |
|
68 |
import java.time.LocalTime; |
|
69 |
import java.time.ZoneId; |
|
70 |
import java.time.format.DateTimeFormatterBuilder; |
|
16852 | 71 |
import java.time.format.ResolverStyle; |
15658 | 72 |
import java.time.format.TextStyle; |
73 |
import java.time.temporal.ChronoField; |
|
74 |
import java.time.temporal.TemporalAccessor; |
|
75 |
import java.time.temporal.TemporalField; |
|
20795 | 76 |
import java.time.temporal.TemporalQueries; |
15658 | 77 |
import java.time.temporal.TemporalQuery; |
16852 | 78 |
import java.time.temporal.UnsupportedTemporalTypeException; |
15658 | 79 |
import java.time.temporal.ValueRange; |
80 |
import java.util.List; |
|
81 |
import java.util.Locale; |
|
16852 | 82 |
import java.util.Map; |
15658 | 83 |
import java.util.Objects; |
84 |
import java.util.Set; |
|
16852 | 85 |
|
15658 | 86 |
/** |
87 |
* A calendar system, used to organize and identify dates. |
|
88 |
* <p> |
|
89 |
* The main date and time API is built on the ISO calendar system. |
|
20794 | 90 |
* The chronology operates behind the scenes to represent the general concept of a calendar system. |
15658 | 91 |
* For example, the Japanese, Minguo, Thai Buddhist and others. |
92 |
* <p> |
|
93 |
* Most other calendar systems also operate on the shared concepts of year, month and day, |
|
94 |
* linked to the cycles of the Earth around the Sun, and the Moon around the Earth. |
|
95 |
* These shared concepts are defined by {@link ChronoField} and are available |
|
96 |
* for use by any {@code Chronology} implementation: |
|
97 |
* <pre> |
|
98 |
* LocalDate isoDate = ... |
|
16852 | 99 |
* ThaiBuddhistDate thaiDate = ... |
15658 | 100 |
* int isoYear = isoDate.get(ChronoField.YEAR); |
101 |
* int thaiYear = thaiDate.get(ChronoField.YEAR); |
|
102 |
* </pre> |
|
103 |
* As shown, although the date objects are in different calendar systems, represented by different |
|
104 |
* {@code Chronology} instances, both can be queried using the same constant on {@code ChronoField}. |
|
105 |
* For a full discussion of the implications of this, see {@link ChronoLocalDate}. |
|
106 |
* In general, the advice is to use the known ISO-based {@code LocalDate}, rather than |
|
107 |
* {@code ChronoLocalDate}. |
|
108 |
* <p> |
|
109 |
* While a {@code Chronology} object typically uses {@code ChronoField} and is based on |
|
110 |
* an era, year-of-era, month-of-year, day-of-month model of a date, this is not required. |
|
111 |
* A {@code Chronology} instance may represent a totally different kind of calendar system, |
|
112 |
* such as the Mayan. |
|
113 |
* <p> |
|
114 |
* In practical terms, the {@code Chronology} instance also acts as a factory. |
|
115 |
* The {@link #of(String)} method allows an instance to be looked up by identifier, |
|
116 |
* while the {@link #ofLocale(Locale)} method allows lookup by locale. |
|
117 |
* <p> |
|
118 |
* The {@code Chronology} instance provides a set of methods to create {@code ChronoLocalDate} instances. |
|
119 |
* The date classes are used to manipulate specific dates. |
|
20873 | 120 |
* <ul> |
15658 | 121 |
* <li> {@link #dateNow() dateNow()} |
122 |
* <li> {@link #dateNow(Clock) dateNow(clock)} |
|
123 |
* <li> {@link #dateNow(ZoneId) dateNow(zone)} |
|
124 |
* <li> {@link #date(int, int, int) date(yearProleptic, month, day)} |
|
125 |
* <li> {@link #date(Era, int, int, int) date(era, yearOfEra, month, day)} |
|
126 |
* <li> {@link #dateYearDay(int, int) dateYearDay(yearProleptic, dayOfYear)} |
|
127 |
* <li> {@link #dateYearDay(Era, int, int) dateYearDay(era, yearOfEra, dayOfYear)} |
|
128 |
* <li> {@link #date(TemporalAccessor) date(TemporalAccessor)} |
|
20873 | 129 |
* </ul> |
15658 | 130 |
* |
131 |
* <h3 id="addcalendars">Adding New Calendars</h3> |
|
132 |
* The set of available chronologies can be extended by applications. |
|
133 |
* Adding a new calendar system requires the writing of an implementation of |
|
134 |
* {@code Chronology}, {@code ChronoLocalDate} and {@code Era}. |
|
135 |
* The majority of the logic specific to the calendar system will be in |
|
136 |
* {@code ChronoLocalDate}. The {@code Chronology} subclass acts as a factory. |
|
137 |
* <p> |
|
138 |
* To permit the discovery of additional chronologies, the {@link java.util.ServiceLoader ServiceLoader} |
|
139 |
* is used. A file must be added to the {@code META-INF/services} directory with the |
|
140 |
* name 'java.time.chrono.Chronology' listing the implementation classes. |
|
141 |
* See the ServiceLoader for more details on service loading. |
|
142 |
* For lookup by id or calendarType, the system provided calendars are found |
|
143 |
* first followed by application provided calendars. |
|
144 |
* <p> |
|
145 |
* Each chronology must define a chronology ID that is unique within the system. |
|
146 |
* If the chronology represents a calendar system defined by the |
|
16852 | 147 |
* CLDR specification then the calendar type is the concatenation of the |
148 |
* CLDR type and, if applicable, the CLDR variant, |
|
15658 | 149 |
* |
17474 | 150 |
* @implSpec |
20794 | 151 |
* This interface must be implemented with care to ensure other classes operate correctly. |
15658 | 152 |
* All implementations that can be instantiated must be final, immutable and thread-safe. |
153 |
* Subclasses should be Serializable wherever possible. |
|
154 |
* |
|
155 |
* @since 1.8 |
|
156 |
*/ |
|
20794 | 157 |
public interface Chronology extends Comparable<Chronology> { |
16852 | 158 |
|
159 |
/** |
|
15658 | 160 |
* Obtains an instance of {@code Chronology} from a temporal object. |
161 |
* <p> |
|
162 |
* This obtains a chronology based on the specified temporal. |
|
163 |
* A {@code TemporalAccessor} represents an arbitrary set of date and time information, |
|
164 |
* which this factory converts to an instance of {@code Chronology}. |
|
165 |
* <p> |
|
20873 | 166 |
* The conversion will obtain the chronology using {@link TemporalQueries#chronology()}. |
15658 | 167 |
* If the specified temporal object does not have a chronology, {@link IsoChronology} is returned. |
168 |
* <p> |
|
20873 | 169 |
* This method matches the signature of the functional interface {@link TemporalQuery} |
15658 | 170 |
* allowing it to be used in queries via method reference, {@code Chronology::from}. |
171 |
* |
|
172 |
* @param temporal the temporal to convert, not null |
|
173 |
* @return the chronology, not null |
|
174 |
* @throws DateTimeException if unable to convert to an {@code Chronology} |
|
175 |
*/ |
|
20794 | 176 |
static Chronology from(TemporalAccessor temporal) { |
15658 | 177 |
Objects.requireNonNull(temporal, "temporal"); |
20795 | 178 |
Chronology obj = temporal.query(TemporalQueries.chronology()); |
15658 | 179 |
return (obj != null ? obj : IsoChronology.INSTANCE); |
180 |
} |
|
181 |
||
182 |
//----------------------------------------------------------------------- |
|
183 |
/** |
|
184 |
* Obtains an instance of {@code Chronology} from a locale. |
|
185 |
* <p> |
|
186 |
* This returns a {@code Chronology} based on the specified locale, |
|
187 |
* typically returning {@code IsoChronology}. Other calendar systems |
|
188 |
* are only returned if they are explicitly selected within the locale. |
|
189 |
* <p> |
|
190 |
* The {@link Locale} class provide access to a range of information useful |
|
191 |
* for localizing an application. This includes the language and region, |
|
192 |
* such as "en-GB" for English as used in Great Britain. |
|
193 |
* <p> |
|
194 |
* The {@code Locale} class also supports an extension mechanism that |
|
195 |
* can be used to identify a calendar system. The mechanism is a form |
|
17474 | 196 |
* of key-value pairs, where the calendar system has the key "ca". |
15658 | 197 |
* For example, the locale "en-JP-u-ca-japanese" represents the English |
198 |
* language as used in Japan with the Japanese calendar system. |
|
199 |
* <p> |
|
200 |
* This method finds the desired calendar system by in a manner equivalent |
|
201 |
* to passing "ca" to {@link Locale#getUnicodeLocaleType(String)}. |
|
202 |
* If the "ca" key is not present, then {@code IsoChronology} is returned. |
|
203 |
* <p> |
|
204 |
* Note that the behavior of this method differs from the older |
|
205 |
* {@link java.util.Calendar#getInstance(Locale)} method. |
|
206 |
* If that method receives a locale of "th_TH" it will return {@code BuddhistCalendar}. |
|
207 |
* By contrast, this method will return {@code IsoChronology}. |
|
208 |
* Passing the locale "th-TH-u-ca-buddhist" into either method will |
|
209 |
* result in the Thai Buddhist calendar system and is therefore the |
|
210 |
* recommended approach going forward for Thai calendar system localization. |
|
211 |
* <p> |
|
212 |
* A similar, but simpler, situation occurs for the Japanese calendar system. |
|
213 |
* The locale "jp_JP_JP" has previously been used to access the calendar. |
|
214 |
* However, unlike the Thai locale, "ja_JP_JP" is automatically converted by |
|
215 |
* {@code Locale} to the modern and recommended form of "ja-JP-u-ca-japanese". |
|
216 |
* Thus, there is no difference in behavior between this method and |
|
217 |
* {@code Calendar#getInstance(Locale)}. |
|
218 |
* |
|
219 |
* @param locale the locale to use to obtain the calendar system, not null |
|
220 |
* @return the calendar system associated with the locale, not null |
|
221 |
* @throws DateTimeException if the locale-specified calendar cannot be found |
|
222 |
*/ |
|
20794 | 223 |
static Chronology ofLocale(Locale locale) { |
224 |
return AbstractChronology.ofLocale(locale); |
|
15658 | 225 |
} |
226 |
||
227 |
//----------------------------------------------------------------------- |
|
228 |
/** |
|
229 |
* Obtains an instance of {@code Chronology} from a chronology ID or |
|
230 |
* calendar system type. |
|
231 |
* <p> |
|
232 |
* This returns a chronology based on either the ID or the type. |
|
233 |
* The {@link #getId() chronology ID} uniquely identifies the chronology. |
|
16852 | 234 |
* The {@link #getCalendarType() calendar system type} is defined by the |
235 |
* CLDR specification. |
|
15658 | 236 |
* <p> |
237 |
* The chronology may be a system chronology or a chronology |
|
238 |
* provided by the application via ServiceLoader configuration. |
|
239 |
* <p> |
|
240 |
* Since some calendars can be customized, the ID or type typically refers |
|
241 |
* to the default customization. For example, the Gregorian calendar can have multiple |
|
242 |
* cutover dates from the Julian, but the lookup only provides the default cutover date. |
|
243 |
* |
|
244 |
* @param id the chronology ID or calendar system type, not null |
|
245 |
* @return the chronology with the identifier requested, not null |
|
246 |
* @throws DateTimeException if the chronology cannot be found |
|
247 |
*/ |
|
20794 | 248 |
static Chronology of(String id) { |
249 |
return AbstractChronology.of(id); |
|
15658 | 250 |
} |
251 |
||
252 |
/** |
|
253 |
* Returns the available chronologies. |
|
254 |
* <p> |
|
255 |
* Each returned {@code Chronology} is available for use in the system. |
|
256 |
* The set of chronologies includes the system chronologies and |
|
257 |
* any chronologies provided by the application via ServiceLoader |
|
258 |
* configuration. |
|
259 |
* |
|
260 |
* @return the independent, modifiable set of the available chronology IDs, not null |
|
261 |
*/ |
|
20794 | 262 |
static Set<Chronology> getAvailableChronologies() { |
263 |
return AbstractChronology.getAvailableChronologies(); |
|
15658 | 264 |
} |
265 |
||
266 |
//----------------------------------------------------------------------- |
|
267 |
/** |
|
268 |
* Gets the ID of the chronology. |
|
269 |
* <p> |
|
270 |
* The ID uniquely identifies the {@code Chronology}. |
|
271 |
* It can be used to lookup the {@code Chronology} using {@link #of(String)}. |
|
272 |
* |
|
273 |
* @return the chronology ID, not null |
|
274 |
* @see #getCalendarType() |
|
275 |
*/ |
|
20794 | 276 |
String getId(); |
15658 | 277 |
|
278 |
/** |
|
16852 | 279 |
* Gets the calendar type of the calendar system. |
15658 | 280 |
* <p> |
16852 | 281 |
* The calendar type is an identifier defined by the CLDR and |
282 |
* <em>Unicode Locale Data Markup Language (LDML)</em> specifications |
|
283 |
* to uniquely identification a calendar. |
|
284 |
* The {@code getCalendarType} is the concatenation of the CLDR calendar type |
|
285 |
* and the variant, if applicable, is appended separated by "-". |
|
286 |
* The calendar type is used to lookup the {@code Chronology} using {@link #of(String)}. |
|
15658 | 287 |
* |
17474 | 288 |
* @return the calendar system type, null if the calendar is not defined by CLDR/LDML |
15658 | 289 |
* @see #getId() |
290 |
*/ |
|
20794 | 291 |
String getCalendarType(); |
15658 | 292 |
|
293 |
//----------------------------------------------------------------------- |
|
294 |
/** |
|
295 |
* Obtains a local date in this chronology from the era, year-of-era, |
|
296 |
* month-of-year and day-of-month fields. |
|
297 |
* |
|
20794 | 298 |
* @implSpec |
299 |
* The default implementation combines the era and year-of-era into a proleptic |
|
300 |
* year before calling {@link #date(int, int, int)}. |
|
301 |
* |
|
15658 | 302 |
* @param era the era of the correct type for the chronology, not null |
303 |
* @param yearOfEra the chronology year-of-era |
|
304 |
* @param month the chronology month-of-year |
|
305 |
* @param dayOfMonth the chronology day-of-month |
|
306 |
* @return the local date in this chronology, not null |
|
307 |
* @throws DateTimeException if unable to create the date |
|
16852 | 308 |
* @throws ClassCastException if the {@code era} is not of the correct type for the chronology |
15658 | 309 |
*/ |
20794 | 310 |
default ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { |
15658 | 311 |
return date(prolepticYear(era, yearOfEra), month, dayOfMonth); |
312 |
} |
|
313 |
||
314 |
/** |
|
315 |
* Obtains a local date in this chronology from the proleptic-year, |
|
316 |
* month-of-year and day-of-month fields. |
|
317 |
* |
|
318 |
* @param prolepticYear the chronology proleptic-year |
|
319 |
* @param month the chronology month-of-year |
|
320 |
* @param dayOfMonth the chronology day-of-month |
|
321 |
* @return the local date in this chronology, not null |
|
322 |
* @throws DateTimeException if unable to create the date |
|
323 |
*/ |
|
20794 | 324 |
ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); |
15658 | 325 |
|
326 |
/** |
|
327 |
* Obtains a local date in this chronology from the era, year-of-era and |
|
328 |
* day-of-year fields. |
|
329 |
* |
|
20794 | 330 |
* @implSpec |
331 |
* The default implementation combines the era and year-of-era into a proleptic |
|
332 |
* year before calling {@link #dateYearDay(int, int)}. |
|
333 |
* |
|
15658 | 334 |
* @param era the era of the correct type for the chronology, not null |
335 |
* @param yearOfEra the chronology year-of-era |
|
336 |
* @param dayOfYear the chronology day-of-year |
|
337 |
* @return the local date in this chronology, not null |
|
338 |
* @throws DateTimeException if unable to create the date |
|
16852 | 339 |
* @throws ClassCastException if the {@code era} is not of the correct type for the chronology |
15658 | 340 |
*/ |
20794 | 341 |
default ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { |
15658 | 342 |
return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); |
343 |
} |
|
344 |
||
345 |
/** |
|
346 |
* Obtains a local date in this chronology from the proleptic-year and |
|
347 |
* day-of-year fields. |
|
348 |
* |
|
349 |
* @param prolepticYear the chronology proleptic-year |
|
350 |
* @param dayOfYear the chronology day-of-year |
|
351 |
* @return the local date in this chronology, not null |
|
352 |
* @throws DateTimeException if unable to create the date |
|
353 |
*/ |
|
20794 | 354 |
ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); |
16852 | 355 |
|
356 |
/** |
|
357 |
* Obtains a local date in this chronology from the epoch-day. |
|
358 |
* <p> |
|
359 |
* The definition of {@link ChronoField#EPOCH_DAY EPOCH_DAY} is the same |
|
360 |
* for all calendar systems, thus it can be used for conversion. |
|
361 |
* |
|
362 |
* @param epochDay the epoch day |
|
363 |
* @return the local date in this chronology, not null |
|
364 |
* @throws DateTimeException if unable to create the date |
|
365 |
*/ |
|
20794 | 366 |
ChronoLocalDate dateEpochDay(long epochDay); |
15658 | 367 |
|
368 |
//----------------------------------------------------------------------- |
|
369 |
/** |
|
370 |
* Obtains the current local date in this chronology from the system clock in the default time-zone. |
|
371 |
* <p> |
|
372 |
* This will query the {@link Clock#systemDefaultZone() system clock} in the default |
|
373 |
* time-zone to obtain the current date. |
|
374 |
* <p> |
|
375 |
* Using this method will prevent the ability to use an alternate clock for testing |
|
376 |
* because the clock is hard-coded. |
|
20794 | 377 |
* |
378 |
* @implSpec |
|
379 |
* The default implementation invokes {@link #dateNow(Clock)}. |
|
15658 | 380 |
* |
381 |
* @return the current local date using the system clock and default time-zone, not null |
|
382 |
* @throws DateTimeException if unable to create the date |
|
383 |
*/ |
|
20794 | 384 |
default ChronoLocalDate dateNow() { |
15658 | 385 |
return dateNow(Clock.systemDefaultZone()); |
386 |
} |
|
387 |
||
388 |
/** |
|
389 |
* Obtains the current local date in this chronology from the system clock in the specified time-zone. |
|
390 |
* <p> |
|
391 |
* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date. |
|
392 |
* Specifying the time-zone avoids dependence on the default time-zone. |
|
393 |
* <p> |
|
394 |
* Using this method will prevent the ability to use an alternate clock for testing |
|
395 |
* because the clock is hard-coded. |
|
396 |
* |
|
20794 | 397 |
* @implSpec |
398 |
* The default implementation invokes {@link #dateNow(Clock)}. |
|
399 |
* |
|
15658 | 400 |
* @param zone the zone ID to use, not null |
401 |
* @return the current local date using the system clock, not null |
|
402 |
* @throws DateTimeException if unable to create the date |
|
403 |
*/ |
|
20794 | 404 |
default ChronoLocalDate dateNow(ZoneId zone) { |
15658 | 405 |
return dateNow(Clock.system(zone)); |
406 |
} |
|
407 |
||
408 |
/** |
|
409 |
* Obtains the current local date in this chronology from the specified clock. |
|
410 |
* <p> |
|
411 |
* This will query the specified clock to obtain the current date - today. |
|
412 |
* Using this method allows the use of an alternate clock for testing. |
|
413 |
* The alternate clock may be introduced using {@link Clock dependency injection}. |
|
414 |
* |
|
20794 | 415 |
* @implSpec |
416 |
* The default implementation invokes {@link #date(TemporalAccessor)} )}. |
|
417 |
* |
|
15658 | 418 |
* @param clock the clock to use, not null |
419 |
* @return the current local date, not null |
|
420 |
* @throws DateTimeException if unable to create the date |
|
421 |
*/ |
|
20794 | 422 |
default ChronoLocalDate dateNow(Clock clock) { |
15658 | 423 |
Objects.requireNonNull(clock, "clock"); |
424 |
return date(LocalDate.now(clock)); |
|
425 |
} |
|
426 |
||
427 |
//----------------------------------------------------------------------- |
|
428 |
/** |
|
429 |
* Obtains a local date in this chronology from another temporal object. |
|
430 |
* <p> |
|
16852 | 431 |
* This obtains a date in this chronology based on the specified temporal. |
15658 | 432 |
* A {@code TemporalAccessor} represents an arbitrary set of date and time information, |
433 |
* which this factory converts to an instance of {@code ChronoLocalDate}. |
|
434 |
* <p> |
|
435 |
* The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY} |
|
436 |
* field, which is standardized across calendar systems. |
|
437 |
* <p> |
|
20873 | 438 |
* This method matches the signature of the functional interface {@link TemporalQuery} |
15658 | 439 |
* allowing it to be used as a query via method reference, {@code aChronology::date}. |
440 |
* |
|
441 |
* @param temporal the temporal object to convert, not null |
|
442 |
* @return the local date in this chronology, not null |
|
443 |
* @throws DateTimeException if unable to create the date |
|
16852 | 444 |
* @see ChronoLocalDate#from(TemporalAccessor) |
15658 | 445 |
*/ |
20794 | 446 |
ChronoLocalDate date(TemporalAccessor temporal); |
15658 | 447 |
|
448 |
/** |
|
449 |
* Obtains a local date-time in this chronology from another temporal object. |
|
450 |
* <p> |
|
16852 | 451 |
* This obtains a date-time in this chronology based on the specified temporal. |
15658 | 452 |
* A {@code TemporalAccessor} represents an arbitrary set of date and time information, |
453 |
* which this factory converts to an instance of {@code ChronoLocalDateTime}. |
|
454 |
* <p> |
|
455 |
* The conversion extracts and combines the {@code ChronoLocalDate} and the |
|
456 |
* {@code LocalTime} from the temporal object. |
|
457 |
* Implementations are permitted to perform optimizations such as accessing |
|
458 |
* those fields that are equivalent to the relevant objects. |
|
459 |
* The result uses this chronology. |
|
460 |
* <p> |
|
20873 | 461 |
* This method matches the signature of the functional interface {@link TemporalQuery} |
15658 | 462 |
* allowing it to be used as a query via method reference, {@code aChronology::localDateTime}. |
463 |
* |
|
464 |
* @param temporal the temporal object to convert, not null |
|
465 |
* @return the local date-time in this chronology, not null |
|
466 |
* @throws DateTimeException if unable to create the date-time |
|
16852 | 467 |
* @see ChronoLocalDateTime#from(TemporalAccessor) |
15658 | 468 |
*/ |
20794 | 469 |
default ChronoLocalDateTime<? extends ChronoLocalDate> localDateTime(TemporalAccessor temporal) { |
15658 | 470 |
try { |
471 |
return date(temporal).atTime(LocalTime.from(temporal)); |
|
472 |
} catch (DateTimeException ex) { |
|
473 |
throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass(), ex); |
|
474 |
} |
|
475 |
} |
|
476 |
||
477 |
/** |
|
478 |
* Obtains a {@code ChronoZonedDateTime} in this chronology from another temporal object. |
|
479 |
* <p> |
|
16852 | 480 |
* This obtains a zoned date-time in this chronology based on the specified temporal. |
15658 | 481 |
* A {@code TemporalAccessor} represents an arbitrary set of date and time information, |
482 |
* which this factory converts to an instance of {@code ChronoZonedDateTime}. |
|
483 |
* <p> |
|
484 |
* The conversion will first obtain a {@code ZoneId} from the temporal object, |
|
485 |
* falling back to a {@code ZoneOffset} if necessary. It will then try to obtain |
|
486 |
* an {@code Instant}, falling back to a {@code ChronoLocalDateTime} if necessary. |
|
487 |
* The result will be either the combination of {@code ZoneId} or {@code ZoneOffset} |
|
488 |
* with {@code Instant} or {@code ChronoLocalDateTime}. |
|
489 |
* Implementations are permitted to perform optimizations such as accessing |
|
490 |
* those fields that are equivalent to the relevant objects. |
|
491 |
* The result uses this chronology. |
|
492 |
* <p> |
|
20873 | 493 |
* This method matches the signature of the functional interface {@link TemporalQuery} |
15658 | 494 |
* allowing it to be used as a query via method reference, {@code aChronology::zonedDateTime}. |
495 |
* |
|
496 |
* @param temporal the temporal object to convert, not null |
|
497 |
* @return the zoned date-time in this chronology, not null |
|
498 |
* @throws DateTimeException if unable to create the date-time |
|
16852 | 499 |
* @see ChronoZonedDateTime#from(TemporalAccessor) |
15658 | 500 |
*/ |
20794 | 501 |
default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(TemporalAccessor temporal) { |
15658 | 502 |
try { |
503 |
ZoneId zone = ZoneId.from(temporal); |
|
504 |
try { |
|
505 |
Instant instant = Instant.from(temporal); |
|
506 |
return zonedDateTime(instant, zone); |
|
507 |
||
508 |
} catch (DateTimeException ex1) { |
|
19030 | 509 |
ChronoLocalDateTimeImpl<?> cldt = ChronoLocalDateTimeImpl.ensureValid(this, localDateTime(temporal)); |
15658 | 510 |
return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null); |
511 |
} |
|
512 |
} catch (DateTimeException ex) { |
|
513 |
throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex); |
|
514 |
} |
|
515 |
} |
|
516 |
||
517 |
/** |
|
518 |
* Obtains a {@code ChronoZonedDateTime} in this chronology from an {@code Instant}. |
|
519 |
* <p> |
|
16852 | 520 |
* This obtains a zoned date-time with the same instant as that specified. |
15658 | 521 |
* |
522 |
* @param instant the instant to create the date-time from, not null |
|
523 |
* @param zone the time-zone, not null |
|
524 |
* @return the zoned date-time, not null |
|
525 |
* @throws DateTimeException if the result exceeds the supported range |
|
526 |
*/ |
|
20794 | 527 |
default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(Instant instant, ZoneId zone) { |
15658 | 528 |
return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); |
529 |
} |
|
530 |
||
531 |
//----------------------------------------------------------------------- |
|
532 |
/** |
|
533 |
* Checks if the specified year is a leap year. |
|
534 |
* <p> |
|
535 |
* A leap-year is a year of a longer length than normal. |
|
536 |
* The exact meaning is determined by the chronology according to the following constraints. |
|
20873 | 537 |
* <ul> |
15658 | 538 |
* <li>a leap-year must imply a year-length longer than a non leap-year. |
539 |
* <li>a chronology that does not support the concept of a year must return false. |
|
20873 | 540 |
* </ul> |
15658 | 541 |
* |
542 |
* @param prolepticYear the proleptic-year to check, not validated for range |
|
543 |
* @return true if the year is a leap year |
|
544 |
*/ |
|
20794 | 545 |
boolean isLeapYear(long prolepticYear); |
15658 | 546 |
|
547 |
/** |
|
548 |
* Calculates the proleptic-year given the era and year-of-era. |
|
549 |
* <p> |
|
550 |
* This combines the era and year-of-era into the single proleptic-year field. |
|
16852 | 551 |
* <p> |
552 |
* If the chronology makes active use of eras, such as {@code JapaneseChronology} |
|
553 |
* then the year-of-era will be validated against the era. |
|
554 |
* For other chronologies, validation is optional. |
|
15658 | 555 |
* |
556 |
* @param era the era of the correct type for the chronology, not null |
|
557 |
* @param yearOfEra the chronology year-of-era |
|
558 |
* @return the proleptic-year |
|
16852 | 559 |
* @throws DateTimeException if unable to convert to a proleptic-year, |
560 |
* such as if the year is invalid for the era |
|
561 |
* @throws ClassCastException if the {@code era} is not of the correct type for the chronology |
|
15658 | 562 |
*/ |
20794 | 563 |
int prolepticYear(Era era, int yearOfEra); |
15658 | 564 |
|
565 |
/** |
|
566 |
* Creates the chronology era object from the numeric value. |
|
567 |
* <p> |
|
568 |
* The era is, conceptually, the largest division of the time-line. |
|
569 |
* Most calendar systems have a single epoch dividing the time-line into two eras. |
|
570 |
* However, some have multiple eras, such as one for the reign of each leader. |
|
571 |
* The exact meaning is determined by the chronology according to the following constraints. |
|
572 |
* <p> |
|
573 |
* The era in use at 1970-01-01 must have the value 1. |
|
574 |
* Later eras must have sequentially higher values. |
|
575 |
* Earlier eras must have sequentially lower values. |
|
576 |
* Each chronology must refer to an enum or similar singleton to provide the era values. |
|
577 |
* <p> |
|
578 |
* This method returns the singleton era of the correct type for the specified era value. |
|
579 |
* |
|
580 |
* @param eraValue the era value |
|
581 |
* @return the calendar system era, not null |
|
582 |
* @throws DateTimeException if unable to create the era |
|
583 |
*/ |
|
20794 | 584 |
Era eraOf(int eraValue); |
15658 | 585 |
|
586 |
/** |
|
587 |
* Gets the list of eras for the chronology. |
|
588 |
* <p> |
|
589 |
* Most calendar systems have an era, within which the year has meaning. |
|
590 |
* If the calendar system does not support the concept of eras, an empty |
|
591 |
* list must be returned. |
|
592 |
* |
|
593 |
* @return the list of eras for the chronology, may be immutable, not null |
|
594 |
*/ |
|
20794 | 595 |
List<Era> eras(); |
15658 | 596 |
|
597 |
//----------------------------------------------------------------------- |
|
598 |
/** |
|
599 |
* Gets the range of valid values for the specified field. |
|
600 |
* <p> |
|
601 |
* All fields can be expressed as a {@code long} integer. |
|
602 |
* This method returns an object that describes the valid range for that value. |
|
603 |
* <p> |
|
604 |
* Note that the result only describes the minimum and maximum valid values |
|
605 |
* and it is important not to read too much into them. For example, there |
|
606 |
* could be values within the range that are invalid for the field. |
|
607 |
* <p> |
|
608 |
* This method will return a result whether or not the chronology supports the field. |
|
609 |
* |
|
610 |
* @param field the field to get the range for, not null |
|
611 |
* @return the range of valid values for the field, not null |
|
612 |
* @throws DateTimeException if the range for the field cannot be obtained |
|
613 |
*/ |
|
20794 | 614 |
ValueRange range(ChronoField field); |
15658 | 615 |
|
616 |
//----------------------------------------------------------------------- |
|
617 |
/** |
|
618 |
* Gets the textual representation of this chronology. |
|
619 |
* <p> |
|
620 |
* This returns the textual name used to identify the chronology, |
|
621 |
* suitable for presentation to the user. |
|
622 |
* The parameters control the style of the returned text and the locale. |
|
623 |
* |
|
20794 | 624 |
* @implSpec |
625 |
* The default implementation behaves as the the formatter was used to |
|
626 |
* format the chronology textual name. |
|
627 |
* |
|
15658 | 628 |
* @param style the style of the text required, not null |
629 |
* @param locale the locale to use, not null |
|
630 |
* @return the text value of the chronology, not null |
|
631 |
*/ |
|
20794 | 632 |
default String getDisplayName(TextStyle style, Locale locale) { |
633 |
TemporalAccessor temporal = new TemporalAccessor() { |
|
15658 | 634 |
@Override |
635 |
public boolean isSupported(TemporalField field) { |
|
636 |
return false; |
|
637 |
} |
|
638 |
@Override |
|
639 |
public long getLong(TemporalField field) { |
|
16852 | 640 |
throw new UnsupportedTemporalTypeException("Unsupported field: " + field); |
15658 | 641 |
} |
642 |
@SuppressWarnings("unchecked") |
|
643 |
@Override |
|
644 |
public <R> R query(TemporalQuery<R> query) { |
|
20795 | 645 |
if (query == TemporalQueries.chronology()) { |
15658 | 646 |
return (R) Chronology.this; |
647 |
} |
|
648 |
return TemporalAccessor.super.query(query); |
|
649 |
} |
|
16852 | 650 |
}; |
20794 | 651 |
return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(temporal); |
16852 | 652 |
} |
653 |
||
654 |
//----------------------------------------------------------------------- |
|
655 |
/** |
|
656 |
* Resolves parsed {@code ChronoField} values into a date during parsing. |
|
657 |
* <p> |
|
658 |
* Most {@code TemporalField} implementations are resolved using the |
|
659 |
* resolve method on the field. By contrast, the {@code ChronoField} class |
|
660 |
* defines fields that only have meaning relative to the chronology. |
|
661 |
* As such, {@code ChronoField} date fields are resolved here in the |
|
662 |
* context of a specific chronology. |
|
663 |
* <p> |
|
20794 | 664 |
* The default implementation, which explains typical resolve behaviour, |
665 |
* is provided in {@link AbstractChronology}. |
|
16852 | 666 |
* |
667 |
* @param fieldValues the map of fields to values, which can be updated, not null |
|
668 |
* @param resolverStyle the requested type of resolve, not null |
|
669 |
* @return the resolved date, null if insufficient information to create a date |
|
670 |
* @throws DateTimeException if the date cannot be resolved, typically |
|
671 |
* because of a conflict in the input data |
|
672 |
*/ |
|
20794 | 673 |
ChronoLocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle); |
15658 | 674 |
|
675 |
//----------------------------------------------------------------------- |
|
676 |
/** |
|
20519
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
677 |
* Obtains a period for this chronology based on years, months and days. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
678 |
* <p> |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
679 |
* This returns a period tied to this chronology using the specified |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
680 |
* years, months and days. All supplied chronologies use periods |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
681 |
* based on years, months and days, however the {@code ChronoPeriod} API |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
682 |
* allows the period to be represented using other units. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
683 |
* |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
684 |
* @implSpec |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
685 |
* The default implementation returns an implementation class suitable |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
686 |
* for most calendar systems. It is based solely on the three units. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
687 |
* Normalization, addition and subtraction derive the number of months |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
688 |
* in a year from the {@link #range(ChronoField)}. If the number of |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
689 |
* months within a year is fixed, then the calculation approach for |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
690 |
* addition, subtraction and normalization is slightly different. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
691 |
* <p> |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
692 |
* If implementing an unusual calendar system that is not based on |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
693 |
* years, months and days, or where you want direct control, then |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
694 |
* the {@code ChronoPeriod} interface must be directly implemented. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
695 |
* <p> |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
696 |
* The returned period is immutable and thread-safe. |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
697 |
* |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
698 |
* @param years the number of years, may be negative |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
699 |
* @param months the number of years, may be negative |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
700 |
* @param days the number of years, may be negative |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
701 |
* @return the period in terms of this chronology, not null |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
702 |
*/ |
20794 | 703 |
default ChronoPeriod period(int years, int months, int days) { |
20519
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
704 |
return new ChronoPeriodImpl(this, years, months, days); |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
705 |
} |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
706 |
|
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
707 |
//----------------------------------------------------------------------- |
eee7a92074fd
8023762: Add ChronoPeriod interface and bind period to Chronology
rriggs
parents:
19841
diff
changeset
|
708 |
/** |
15658 | 709 |
* Compares this chronology to another chronology. |
710 |
* <p> |
|
711 |
* The comparison order first by the chronology ID string, then by any |
|
712 |
* additional information specific to the subclass. |
|
713 |
* It is "consistent with equals", as defined by {@link Comparable}. |
|
714 |
* |
|
715 |
* @param other the other chronology to compare to, not null |
|
716 |
* @return the comparator value, negative if less, positive if greater |
|
717 |
*/ |
|
718 |
@Override |
|
20794 | 719 |
int compareTo(Chronology other); |
15658 | 720 |
|
721 |
/** |
|
722 |
* Checks if this chronology is equal to another chronology. |
|
723 |
* <p> |
|
724 |
* The comparison is based on the entire state of the object. |
|
725 |
* |
|
726 |
* @param obj the object to check, null returns false |
|
727 |
* @return true if this is equal to the other chronology |
|
728 |
*/ |
|
729 |
@Override |
|
20794 | 730 |
boolean equals(Object obj); |
15658 | 731 |
|
732 |
/** |
|
733 |
* A hash code for this chronology. |
|
734 |
* <p> |
|
20794 | 735 |
* The hash code should be based on the entire state of the object. |
15658 | 736 |
* |
737 |
* @return a suitable hash code |
|
738 |
*/ |
|
739 |
@Override |
|
20794 | 740 |
int hashCode(); |
15658 | 741 |
|
742 |
//----------------------------------------------------------------------- |
|
743 |
/** |
|
20794 | 744 |
* Outputs this chronology as a {@code String}. |
745 |
* <p> |
|
746 |
* The format should include the entire state of the object. |
|
15658 | 747 |
* |
748 |
* @return a string representation of this chronology, not null |
|
749 |
*/ |
|
750 |
@Override |
|
20794 | 751 |
String toString(); |
15658 | 752 |
|
753 |
} |