Path: blob/master/src/java.base/share/classes/java/time/chrono/Chronology.java
41159 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file:30*31* Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos32*33* All rights reserved.34*35* Redistribution and use in source and binary forms, with or without36* modification, are permitted provided that the following conditions are met:37*38* * Redistributions of source code must retain the above copyright notice,39* this list of conditions and the following disclaimer.40*41* * Redistributions in binary form must reproduce the above copyright notice,42* this list of conditions and the following disclaimer in the documentation43* and/or other materials provided with the distribution.44*45* * Neither the name of JSR-310 nor the names of its contributors46* may be used to endorse or promote products derived from this software47* without specific prior written permission.48*49* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS50* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT51* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR52* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR53* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,54* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,55* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR56* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF57* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING58* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS59* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.60*/61package java.time.chrono;6263import static java.time.temporal.ChronoField.HOUR_OF_DAY;64import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;65import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;6667import java.time.Clock;68import java.time.DateTimeException;69import java.time.Instant;70import java.time.LocalDate;71import java.time.LocalTime;72import java.time.ZoneId;73import java.time.ZoneOffset;74import java.time.format.DateTimeFormatterBuilder;75import java.time.format.ResolverStyle;76import java.time.format.TextStyle;77import java.time.temporal.ChronoField;78import java.time.temporal.TemporalAccessor;79import java.time.temporal.TemporalField;80import java.time.temporal.TemporalQueries;81import java.time.temporal.TemporalQuery;82import java.time.temporal.UnsupportedTemporalTypeException;83import java.time.temporal.ValueRange;84import java.util.List;85import java.util.Locale;86import java.util.Map;87import java.util.Objects;88import java.util.Set;8990/**91* A calendar system, used to organize and identify dates.92* <p>93* The main date and time API is built on the ISO calendar system.94* The chronology operates behind the scenes to represent the general concept of a calendar system.95* For example, the Japanese, Minguo, Thai Buddhist and others.96* <p>97* Most other calendar systems also operate on the shared concepts of year, month and day,98* linked to the cycles of the Earth around the Sun, and the Moon around the Earth.99* These shared concepts are defined by {@link ChronoField} and are available100* for use by any {@code Chronology} implementation:101* <pre>102* LocalDate isoDate = ...103* ThaiBuddhistDate thaiDate = ...104* int isoYear = isoDate.get(ChronoField.YEAR);105* int thaiYear = thaiDate.get(ChronoField.YEAR);106* </pre>107* As shown, although the date objects are in different calendar systems, represented by different108* {@code Chronology} instances, both can be queried using the same constant on {@code ChronoField}.109* For a full discussion of the implications of this, see {@link ChronoLocalDate}.110* In general, the advice is to use the known ISO-based {@code LocalDate}, rather than111* {@code ChronoLocalDate}.112* <p>113* While a {@code Chronology} object typically uses {@code ChronoField} and is based on114* an era, year-of-era, month-of-year, day-of-month model of a date, this is not required.115* A {@code Chronology} instance may represent a totally different kind of calendar system,116* such as the Mayan.117* <p>118* In practical terms, the {@code Chronology} instance also acts as a factory.119* The {@link #of(String)} method allows an instance to be looked up by identifier,120* while the {@link #ofLocale(Locale)} method allows lookup by locale.121* <p>122* The {@code Chronology} instance provides a set of methods to create {@code ChronoLocalDate} instances.123* The date classes are used to manipulate specific dates.124* <ul>125* <li> {@link #dateNow() dateNow()}126* <li> {@link #dateNow(Clock) dateNow(clock)}127* <li> {@link #dateNow(ZoneId) dateNow(zone)}128* <li> {@link #date(int, int, int) date(yearProleptic, month, day)}129* <li> {@link #date(Era, int, int, int) date(era, yearOfEra, month, day)}130* <li> {@link #dateYearDay(int, int) dateYearDay(yearProleptic, dayOfYear)}131* <li> {@link #dateYearDay(Era, int, int) dateYearDay(era, yearOfEra, dayOfYear)}132* <li> {@link #date(TemporalAccessor) date(TemporalAccessor)}133* </ul>134*135* <h2 id="addcalendars">Adding New Calendars</h2>136* The set of available chronologies can be extended by applications.137* Adding a new calendar system requires the writing of an implementation of138* {@code Chronology}, {@code ChronoLocalDate} and {@code Era}.139* The majority of the logic specific to the calendar system will be in the140* {@code ChronoLocalDate} implementation.141* The {@code Chronology} implementation acts as a factory.142* <p>143* To permit the discovery of additional chronologies, the {@link java.util.ServiceLoader ServiceLoader}144* is used. A file must be added to the {@code META-INF/services} directory with the145* name 'java.time.chrono.Chronology' listing the implementation classes.146* See the ServiceLoader for more details on service loading.147* For lookup by id or calendarType, the system provided calendars are found148* first followed by application provided calendars.149* <p>150* Each chronology must define a chronology ID that is unique within the system.151* If the chronology represents a calendar system defined by the152* CLDR specification then the calendar type is the concatenation of the153* CLDR type and, if applicable, the CLDR variant.154*155* @implSpec156* This interface must be implemented with care to ensure other classes operate correctly.157* All implementations that can be instantiated must be final, immutable and thread-safe.158* Subclasses should be Serializable wherever possible.159*160* @since 1.8161*/162public interface Chronology extends Comparable<Chronology> {163164/**165* Obtains an instance of {@code Chronology} from a temporal object.166* <p>167* This obtains a chronology based on the specified temporal.168* A {@code TemporalAccessor} represents an arbitrary set of date and time information,169* which this factory converts to an instance of {@code Chronology}.170* <p>171* The conversion will obtain the chronology using {@link TemporalQueries#chronology()}.172* If the specified temporal object does not have a chronology, {@link IsoChronology} is returned.173* <p>174* This method matches the signature of the functional interface {@link TemporalQuery}175* allowing it to be used as a query via method reference, {@code Chronology::from}.176*177* @param temporal the temporal to convert, not null178* @return the chronology, not null179* @throws DateTimeException if unable to convert to a {@code Chronology}180*/181static Chronology from(TemporalAccessor temporal) {182Objects.requireNonNull(temporal, "temporal");183Chronology obj = temporal.query(TemporalQueries.chronology());184return Objects.requireNonNullElse(obj, IsoChronology.INSTANCE);185}186187//-----------------------------------------------------------------------188/**189* Obtains an instance of {@code Chronology} from a locale.190* <p>191* This returns a {@code Chronology} based on the specified locale,192* typically returning {@code IsoChronology}. Other calendar systems193* are only returned if they are explicitly selected within the locale.194* <p>195* The {@link Locale} class provide access to a range of information useful196* for localizing an application. This includes the language and region,197* such as "en-GB" for English as used in Great Britain.198* <p>199* The {@code Locale} class also supports an extension mechanism that200* can be used to identify a calendar system. The mechanism is a form201* of key-value pairs, where the calendar system has the key "ca".202* For example, the locale "en-JP-u-ca-japanese" represents the English203* language as used in Japan with the Japanese calendar system.204* <p>205* This method finds the desired calendar system in a manner equivalent206* to passing "ca" to {@link Locale#getUnicodeLocaleType(String)}.207* If the "ca" key is not present, then {@code IsoChronology} is returned.208* <p>209* Note that the behavior of this method differs from the older210* {@link java.util.Calendar#getInstance(Locale)} method.211* If that method receives a locale of "th_TH" it will return {@code BuddhistCalendar}.212* By contrast, this method will return {@code IsoChronology}.213* Passing the locale "th-TH-u-ca-buddhist" into either method will214* result in the Thai Buddhist calendar system and is therefore the215* recommended approach going forward for Thai calendar system localization.216* <p>217* A similar, but simpler, situation occurs for the Japanese calendar system.218* The locale "jp_JP_JP" has previously been used to access the calendar.219* However, unlike the Thai locale, "ja_JP_JP" is automatically converted by220* {@code Locale} to the modern and recommended form of "ja-JP-u-ca-japanese".221* Thus, there is no difference in behavior between this method and222* {@code Calendar#getInstance(Locale)}.223*224* @param locale the locale to use to obtain the calendar system, not null225* @return the calendar system associated with the locale, not null226* @throws DateTimeException if the locale-specified calendar cannot be found227*/228static Chronology ofLocale(Locale locale) {229return AbstractChronology.ofLocale(locale);230}231232//-----------------------------------------------------------------------233/**234* Obtains an instance of {@code Chronology} from a chronology ID or235* calendar system type.236* <p>237* This returns a chronology based on either the ID or the type.238* The {@link #getId() chronology ID} uniquely identifies the chronology.239* The {@link #getCalendarType() calendar system type} is defined by the240* CLDR specification.241* <p>242* The chronology may be a system chronology or a chronology243* provided by the application via ServiceLoader configuration.244* <p>245* Since some calendars can be customized, the ID or type typically refers246* to the default customization. For example, the Gregorian calendar can have multiple247* cutover dates from the Julian, but the lookup only provides the default cutover date.248*249* @param id the chronology ID or calendar system type, not null250* @return the chronology with the identifier requested, not null251* @throws DateTimeException if the chronology cannot be found252*/253static Chronology of(String id) {254return AbstractChronology.of(id);255}256257/**258* Returns the available chronologies.259* <p>260* Each returned {@code Chronology} is available for use in the system.261* The set of chronologies includes the system chronologies and262* any chronologies provided by the application via ServiceLoader263* configuration.264*265* @return the independent, modifiable set of the available chronology IDs, not null266*/267static Set<Chronology> getAvailableChronologies() {268return AbstractChronology.getAvailableChronologies();269}270271//-----------------------------------------------------------------------272/**273* Gets the ID of the chronology.274* <p>275* The ID uniquely identifies the {@code Chronology}.276* It can be used to lookup the {@code Chronology} using {@link #of(String)}.277*278* @return the chronology ID, not null279* @see #getCalendarType()280*/281String getId();282283/**284* Gets the calendar type of the calendar system.285* <p>286* The calendar type is an identifier defined by the CLDR and287* <em>Unicode Locale Data Markup Language (LDML)</em> specifications288* to uniquely identify a calendar.289* The {@code getCalendarType} is the concatenation of the CLDR calendar type290* and the variant, if applicable, is appended separated by "-".291* The calendar type is used to lookup the {@code Chronology} using {@link #of(String)}.292*293* @return the calendar system type, null if the calendar is not defined by CLDR/LDML294* @see #getId()295*/296String getCalendarType();297298//-----------------------------------------------------------------------299/**300* Obtains a local date in this chronology from the era, year-of-era,301* month-of-year and day-of-month fields.302*303* @implSpec304* The default implementation combines the era and year-of-era into a proleptic305* year before calling {@link #date(int, int, int)}.306*307* @param era the era of the correct type for the chronology, not null308* @param yearOfEra the chronology year-of-era309* @param month the chronology month-of-year310* @param dayOfMonth the chronology day-of-month311* @return the local date in this chronology, not null312* @throws DateTimeException if unable to create the date313* @throws ClassCastException if the {@code era} is not of the correct type for the chronology314*/315default ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) {316return date(prolepticYear(era, yearOfEra), month, dayOfMonth);317}318319/**320* Obtains a local date in this chronology from the proleptic-year,321* month-of-year and day-of-month fields.322*323* @param prolepticYear the chronology proleptic-year324* @param month the chronology month-of-year325* @param dayOfMonth the chronology day-of-month326* @return the local date in this chronology, not null327* @throws DateTimeException if unable to create the date328*/329ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth);330331/**332* Obtains a local date in this chronology from the era, year-of-era and333* day-of-year fields.334*335* @implSpec336* The default implementation combines the era and year-of-era into a proleptic337* year before calling {@link #dateYearDay(int, int)}.338*339* @param era the era of the correct type for the chronology, not null340* @param yearOfEra the chronology year-of-era341* @param dayOfYear the chronology day-of-year342* @return the local date in this chronology, not null343* @throws DateTimeException if unable to create the date344* @throws ClassCastException if the {@code era} is not of the correct type for the chronology345*/346default ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {347return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);348}349350/**351* Obtains a local date in this chronology from the proleptic-year and352* day-of-year fields.353*354* @param prolepticYear the chronology proleptic-year355* @param dayOfYear the chronology day-of-year356* @return the local date in this chronology, not null357* @throws DateTimeException if unable to create the date358*/359ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear);360361/**362* Obtains a local date in this chronology from the epoch-day.363* <p>364* The definition of {@link ChronoField#EPOCH_DAY EPOCH_DAY} is the same365* for all calendar systems, thus it can be used for conversion.366*367* @param epochDay the epoch day368* @return the local date in this chronology, not null369* @throws DateTimeException if unable to create the date370*/371ChronoLocalDate dateEpochDay(long epochDay);372373//-----------------------------------------------------------------------374/**375* Obtains the current local date in this chronology from the system clock in the default time-zone.376* <p>377* This will query the {@link Clock#systemDefaultZone() system clock} in the default378* time-zone to obtain the current date.379* <p>380* Using this method will prevent the ability to use an alternate clock for testing381* because the clock is hard-coded.382*383* @implSpec384* The default implementation invokes {@link #dateNow(Clock)}.385*386* @return the current local date using the system clock and default time-zone, not null387* @throws DateTimeException if unable to create the date388*/389default ChronoLocalDate dateNow() {390return dateNow(Clock.systemDefaultZone());391}392393/**394* Obtains the current local date in this chronology from the system clock in the specified time-zone.395* <p>396* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.397* Specifying the time-zone avoids dependence on the default time-zone.398* <p>399* Using this method will prevent the ability to use an alternate clock for testing400* because the clock is hard-coded.401*402* @implSpec403* The default implementation invokes {@link #dateNow(Clock)}.404*405* @param zone the zone ID to use, not null406* @return the current local date using the system clock, not null407* @throws DateTimeException if unable to create the date408*/409default ChronoLocalDate dateNow(ZoneId zone) {410return dateNow(Clock.system(zone));411}412413/**414* Obtains the current local date in this chronology from the specified clock.415* <p>416* This will query the specified clock to obtain the current date - today.417* Using this method allows the use of an alternate clock for testing.418* The alternate clock may be introduced using {@link Clock dependency injection}.419*420* @implSpec421* The default implementation invokes {@link #date(TemporalAccessor)}.422*423* @param clock the clock to use, not null424* @return the current local date, not null425* @throws DateTimeException if unable to create the date426*/427default ChronoLocalDate dateNow(Clock clock) {428Objects.requireNonNull(clock, "clock");429return date(LocalDate.now(clock));430}431432//-----------------------------------------------------------------------433/**434* Obtains a local date in this chronology from another temporal object.435* <p>436* This obtains a date in this chronology based on the specified temporal.437* A {@code TemporalAccessor} represents an arbitrary set of date and time information,438* which this factory converts to an instance of {@code ChronoLocalDate}.439* <p>440* The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}441* field, which is standardized across calendar systems.442* <p>443* This method matches the signature of the functional interface {@link TemporalQuery}444* allowing it to be used as a query via method reference, {@code aChronology::date}.445*446* @param temporal the temporal object to convert, not null447* @return the local date in this chronology, not null448* @throws DateTimeException if unable to create the date449* @see ChronoLocalDate#from(TemporalAccessor)450*/451ChronoLocalDate date(TemporalAccessor temporal);452453/**454* Obtains a local date-time in this chronology from another temporal object.455* <p>456* This obtains a date-time in this chronology based on the specified temporal.457* A {@code TemporalAccessor} represents an arbitrary set of date and time information,458* which this factory converts to an instance of {@code ChronoLocalDateTime}.459* <p>460* The conversion extracts and combines the {@code ChronoLocalDate} and the461* {@code LocalTime} from the temporal object.462* Implementations are permitted to perform optimizations such as accessing463* those fields that are equivalent to the relevant objects.464* The result uses this chronology.465* <p>466* This method matches the signature of the functional interface {@link TemporalQuery}467* allowing it to be used as a query via method reference, {@code aChronology::localDateTime}.468*469* @param temporal the temporal object to convert, not null470* @return the local date-time in this chronology, not null471* @throws DateTimeException if unable to create the date-time472* @see ChronoLocalDateTime#from(TemporalAccessor)473*/474default ChronoLocalDateTime<? extends ChronoLocalDate> localDateTime(TemporalAccessor temporal) {475try {476return date(temporal).atTime(LocalTime.from(temporal));477} catch (DateTimeException ex) {478throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass(), ex);479}480}481482/**483* Obtains a {@code ChronoZonedDateTime} in this chronology from another temporal object.484* <p>485* This obtains a zoned date-time in this chronology based on the specified temporal.486* A {@code TemporalAccessor} represents an arbitrary set of date and time information,487* which this factory converts to an instance of {@code ChronoZonedDateTime}.488* <p>489* The conversion will first obtain a {@code ZoneId} from the temporal object,490* falling back to a {@code ZoneOffset} if necessary. It will then try to obtain491* an {@code Instant}, falling back to a {@code ChronoLocalDateTime} if necessary.492* The result will be either the combination of {@code ZoneId} or {@code ZoneOffset}493* with {@code Instant} or {@code ChronoLocalDateTime}.494* Implementations are permitted to perform optimizations such as accessing495* those fields that are equivalent to the relevant objects.496* The result uses this chronology.497* <p>498* This method matches the signature of the functional interface {@link TemporalQuery}499* allowing it to be used as a query via method reference, {@code aChronology::zonedDateTime}.500*501* @param temporal the temporal object to convert, not null502* @return the zoned date-time in this chronology, not null503* @throws DateTimeException if unable to create the date-time504* @see ChronoZonedDateTime#from(TemporalAccessor)505*/506default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(TemporalAccessor temporal) {507try {508ZoneId zone = ZoneId.from(temporal);509try {510Instant instant = Instant.from(temporal);511return zonedDateTime(instant, zone);512513} catch (DateTimeException ex1) {514ChronoLocalDateTimeImpl<?> cldt = ChronoLocalDateTimeImpl.ensureValid(this, localDateTime(temporal));515return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null);516}517} catch (DateTimeException ex) {518throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex);519}520}521522/**523* Obtains a {@code ChronoZonedDateTime} in this chronology from an {@code Instant}.524* <p>525* This obtains a zoned date-time with the same instant as that specified.526*527* @param instant the instant to create the date-time from, not null528* @param zone the time-zone, not null529* @return the zoned date-time, not null530* @throws DateTimeException if the result exceeds the supported range531*/532default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(Instant instant, ZoneId zone) {533return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone);534}535536//-----------------------------------------------------------------------537/**538* Checks if the specified year is a leap year.539* <p>540* A leap-year is a year of a longer length than normal.541* The exact meaning is determined by the chronology according to the following constraints.542* <ul>543* <li>a leap-year must imply a year-length longer than a non leap-year.544* <li>a chronology that does not support the concept of a year must return false.545* <li>the correct result must be returned for all years within the546* valid range of years for the chronology.547* </ul>548* <p>549* Outside the range of valid years an implementation is free to return550* either a best guess or false.551* An implementation must not throw an exception, even if the year is552* outside the range of valid years.553*554* @param prolepticYear the proleptic-year to check, not validated for range555* @return true if the year is a leap year556*/557boolean isLeapYear(long prolepticYear);558559/**560* Calculates the proleptic-year given the era and year-of-era.561* <p>562* This combines the era and year-of-era into the single proleptic-year field.563* <p>564* If the chronology makes active use of eras, such as {@code JapaneseChronology}565* then the year-of-era will be validated against the era.566* For other chronologies, validation is optional.567*568* @param era the era of the correct type for the chronology, not null569* @param yearOfEra the chronology year-of-era570* @return the proleptic-year571* @throws DateTimeException if unable to convert to a proleptic-year,572* such as if the year is invalid for the era573* @throws ClassCastException if the {@code era} is not of the correct type for the chronology574*/575int prolepticYear(Era era, int yearOfEra);576577/**578* Creates the chronology era object from the numeric value.579* <p>580* The era is, conceptually, the largest division of the time-line.581* Most calendar systems have a single epoch dividing the time-line into two eras.582* However, some have multiple eras, such as one for the reign of each leader.583* The exact meaning is determined by the chronology according to the following constraints.584* <p>585* The era in use at 1970-01-01 must have the value 1.586* Later eras must have sequentially higher values.587* Earlier eras must have sequentially lower values.588* Each chronology must refer to an enum or similar singleton to provide the era values.589* <p>590* This method returns the singleton era of the correct type for the specified era value.591*592* @param eraValue the era value593* @return the calendar system era, not null594* @throws DateTimeException if unable to create the era595*/596Era eraOf(int eraValue);597598/**599* Gets the list of eras for the chronology.600* <p>601* Most calendar systems have an era, within which the year has meaning.602* If the calendar system does not support the concept of eras, an empty603* list must be returned.604*605* @return the list of eras for the chronology, may be immutable, not null606*/607List<Era> eras();608609//-----------------------------------------------------------------------610/**611* Gets the range of valid values for the specified field.612* <p>613* All fields can be expressed as a {@code long} integer.614* This method returns an object that describes the valid range for that value.615* <p>616* Note that the result only describes the minimum and maximum valid values617* and it is important not to read too much into them. For example, there618* could be values within the range that are invalid for the field.619* <p>620* This method will return a result whether or not the chronology supports the field.621*622* @param field the field to get the range for, not null623* @return the range of valid values for the field, not null624* @throws DateTimeException if the range for the field cannot be obtained625*/626ValueRange range(ChronoField field);627628//-----------------------------------------------------------------------629/**630* Gets the textual representation of this chronology.631* <p>632* This returns the textual name used to identify the chronology,633* suitable for presentation to the user.634* The parameters control the style of the returned text and the locale.635*636* @implSpec637* The default implementation behaves as though the formatter was used to638* format the chronology textual name.639*640* @param style the style of the text required, not null641* @param locale the locale to use, not null642* @return the text value of the chronology, not null643*/644default String getDisplayName(TextStyle style, Locale locale) {645TemporalAccessor temporal = new TemporalAccessor() {646@Override647public boolean isSupported(TemporalField field) {648return false;649}650@Override651public long getLong(TemporalField field) {652throw new UnsupportedTemporalTypeException("Unsupported field: " + field);653}654@SuppressWarnings("unchecked")655@Override656public <R> R query(TemporalQuery<R> query) {657if (query == TemporalQueries.chronology()) {658return (R) Chronology.this;659}660return TemporalAccessor.super.query(query);661}662};663return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(temporal);664}665666//-----------------------------------------------------------------------667/**668* Resolves parsed {@code ChronoField} values into a date during parsing.669* <p>670* Most {@code TemporalField} implementations are resolved using the671* resolve method on the field. By contrast, the {@code ChronoField} class672* defines fields that only have meaning relative to the chronology.673* As such, {@code ChronoField} date fields are resolved here in the674* context of a specific chronology.675* <p>676* The default implementation, which explains typical resolve behaviour,677* is provided in {@link AbstractChronology}.678*679* @param fieldValues the map of fields to values, which can be updated, not null680* @param resolverStyle the requested type of resolve, not null681* @return the resolved date, null if insufficient information to create a date682* @throws DateTimeException if the date cannot be resolved, typically683* because of a conflict in the input data684*/685ChronoLocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle);686687//-----------------------------------------------------------------------688/**689* Obtains a period for this chronology based on years, months and days.690* <p>691* This returns a period tied to this chronology using the specified692* years, months and days. All supplied chronologies use periods693* based on years, months and days, however the {@code ChronoPeriod} API694* allows the period to be represented using other units.695*696* @implSpec697* The default implementation returns an implementation class suitable698* for most calendar systems. It is based solely on the three units.699* Normalization, addition and subtraction derive the number of months700* in a year from the {@link #range(ChronoField)}. If the number of701* months within a year is fixed, then the calculation approach for702* addition, subtraction and normalization is slightly different.703* <p>704* If implementing an unusual calendar system that is not based on705* years, months and days, or where you want direct control, then706* the {@code ChronoPeriod} interface must be directly implemented.707* <p>708* The returned period is immutable and thread-safe.709*710* @param years the number of years, may be negative711* @param months the number of years, may be negative712* @param days the number of years, may be negative713* @return the period in terms of this chronology, not null714*/715default ChronoPeriod period(int years, int months, int days) {716return new ChronoPeriodImpl(this, years, months, days);717}718719//---------------------------------------------------------------------720721/**722* Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.723* <p>724* The number of seconds is calculated using the proleptic-year,725* month, day-of-month, hour, minute, second, and zoneOffset.726*727* @param prolepticYear the chronology proleptic-year728* @param month the chronology month-of-year729* @param dayOfMonth the chronology day-of-month730* @param hour the hour-of-day, from 0 to 23731* @param minute the minute-of-hour, from 0 to 59732* @param second the second-of-minute, from 0 to 59733* @param zoneOffset the zone offset, not null734* @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative735* @throws DateTimeException if any of the values are out of range736* @since 9737*/738public default long epochSecond(int prolepticYear, int month, int dayOfMonth,739int hour, int minute, int second, ZoneOffset zoneOffset) {740Objects.requireNonNull(zoneOffset, "zoneOffset");741HOUR_OF_DAY.checkValidValue(hour);742MINUTE_OF_HOUR.checkValidValue(minute);743SECOND_OF_MINUTE.checkValidValue(second);744long daysInSec = Math.multiplyExact(date(prolepticYear, month, dayOfMonth).toEpochDay(), 86400);745long timeinSec = (hour * 60 + minute) * 60 + second;746return Math.addExact(daysInSec, timeinSec - zoneOffset.getTotalSeconds());747}748749/**750* Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.751* <p>752* The number of seconds is calculated using the era, year-of-era,753* month, day-of-month, hour, minute, second, and zoneOffset.754*755* @param era the era of the correct type for the chronology, not null756* @param yearOfEra the chronology year-of-era757* @param month the chronology month-of-year758* @param dayOfMonth the chronology day-of-month759* @param hour the hour-of-day, from 0 to 23760* @param minute the minute-of-hour, from 0 to 59761* @param second the second-of-minute, from 0 to 59762* @param zoneOffset the zone offset, not null763* @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative764* @throws DateTimeException if any of the values are out of range765* @since 9766*/767public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,768int hour, int minute, int second, ZoneOffset zoneOffset) {769Objects.requireNonNull(era, "era");770return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);771}772//-----------------------------------------------------------------------773/**774* Compares this chronology to another chronology.775* <p>776* The comparison order first by the chronology ID string, then by any777* additional information specific to the subclass.778* It is "consistent with equals", as defined by {@link Comparable}.779*780* @param other the other chronology to compare to, not null781* @return the comparator value, negative if less, positive if greater782*/783@Override784int compareTo(Chronology other);785786/**787* Checks if this chronology is equal to another chronology.788* <p>789* The comparison is based on the entire state of the object.790*791* @param obj the object to check, null returns false792* @return true if this is equal to the other chronology793*/794@Override795boolean equals(Object obj);796797/**798* A hash code for this chronology.799* <p>800* The hash code should be based on the entire state of the object.801*802* @return a suitable hash code803*/804@Override805int hashCode();806807//-----------------------------------------------------------------------808/**809* Outputs this chronology as a {@code String}.810* <p>811* The format should include the entire state of the object.812*813* @return a string representation of this chronology, not null814*/815@Override816String toString();817818}819820821