1 /* 2 * Copyright (c) 2012, 2015, 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; 71 import java.time.format.ResolverStyle; 72 import java.time.format.TextStyle; 73 import java.time.temporal.ChronoField; 74 import java.time.temporal.TemporalAccessor; 75 import java.time.temporal.TemporalField; 76 import java.time.temporal.TemporalQueries; 77 import java.time.temporal.TemporalQuery; 78 import java.time.temporal.UnsupportedTemporalTypeException; 79 import java.time.temporal.ValueRange; 80 import java.util.List; 81 import java.util.Locale; 82 import java.util.Map; 83 import java.util.Objects; 84 import java.util.Set; 85 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. 90 * The chronology operates behind the scenes to represent the general concept of a calendar system. 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 = ... 99 * ThaiBuddhistDate thaiDate = ... 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. 120 * <ul> 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)} 129 * </ul> 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 the 136 * {@code ChronoLocalDate} implementation. 137 * The {@code Chronology} implementation acts as a factory. 138 * <p> 139 * To permit the discovery of additional chronologies, the {@link java.util.ServiceLoader ServiceLoader} 140 * is used. A file must be added to the {@code META-INF/services} directory with the 141 * name 'java.time.chrono.Chronology' listing the implementation classes. 142 * See the ServiceLoader for more details on service loading. 143 * For lookup by id or calendarType, the system provided calendars are found 144 * first followed by application provided calendars. 145 * <p> 146 * Each chronology must define a chronology ID that is unique within the system. 147 * If the chronology represents a calendar system defined by the 148 * CLDR specification then the calendar type is the concatenation of the 149 * CLDR type and, if applicable, the CLDR variant, 150 * 151 * @implSpec 152 * This interface must be implemented with care to ensure other classes operate correctly. 153 * All implementations that can be instantiated must be final, immutable and thread-safe. 154 * Subclasses should be Serializable wherever possible. 155 * 156 * @since 1.8 157 */ 158 public interface Chronology extends Comparable<Chronology> { 159 160 /** 161 * Obtains an instance of {@code Chronology} from a temporal object. 162 * <p> 163 * This obtains a chronology based on the specified temporal. 164 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 165 * which this factory converts to an instance of {@code Chronology}. 166 * <p> 167 * The conversion will obtain the chronology using {@link TemporalQueries#chronology()}. 168 * If the specified temporal object does not have a chronology, {@link IsoChronology} is returned. 169 * <p> 170 * This method matches the signature of the functional interface {@link TemporalQuery} 171 * allowing it to be used as a query via method reference, {@code Chronology::from}. 172 * 173 * @param temporal the temporal to convert, not null 174 * @return the chronology, not null 175 * @throws DateTimeException if unable to convert to an {@code Chronology} 176 */ from(TemporalAccessor temporal)177 static Chronology from(TemporalAccessor temporal) { 178 Objects.requireNonNull(temporal, "temporal"); 179 Chronology obj = temporal.query(TemporalQueries.chronology()); 180 return (obj != null ? obj : IsoChronology.INSTANCE); 181 } 182 183 //----------------------------------------------------------------------- 184 /** 185 * Obtains an instance of {@code Chronology} from a locale. 186 * <p> 187 * This returns a {@code Chronology} based on the specified locale, 188 * typically returning {@code IsoChronology}. Other calendar systems 189 * are only returned if they are explicitly selected within the locale. 190 * <p> 191 * The {@link Locale} class provide access to a range of information useful 192 * for localizing an application. This includes the language and region, 193 * such as "en-GB" for English as used in Great Britain. 194 * <p> 195 * The {@code Locale} class also supports an extension mechanism that 196 * can be used to identify a calendar system. The mechanism is a form 197 * of key-value pairs, where the calendar system has the key "ca". 198 * For example, the locale "en-JP-u-ca-japanese" represents the English 199 * language as used in Japan with the Japanese calendar system. 200 * <p> 201 * This method finds the desired calendar system by in a manner equivalent 202 * to passing "ca" to {@link Locale#getUnicodeLocaleType(String)}. 203 * If the "ca" key is not present, then {@code IsoChronology} is returned. 204 * <p> 205 * Note that the behavior of this method differs from the older 206 * {@link java.util.Calendar#getInstance(Locale)} method. 207 * If that method receives a locale of "th_TH" it will return {@code BuddhistCalendar}. 208 * By contrast, this method will return {@code IsoChronology}. 209 * Passing the locale "th-TH-u-ca-buddhist" into either method will 210 * result in the Thai Buddhist calendar system and is therefore the 211 * recommended approach going forward for Thai calendar system localization. 212 * <p> 213 * A similar, but simpler, situation occurs for the Japanese calendar system. 214 * The locale "jp_JP_JP" has previously been used to access the calendar. 215 * However, unlike the Thai locale, "ja_JP_JP" is automatically converted by 216 * {@code Locale} to the modern and recommended form of "ja-JP-u-ca-japanese". 217 * Thus, there is no difference in behavior between this method and 218 * {@code Calendar#getInstance(Locale)}. 219 * 220 * @param locale the locale to use to obtain the calendar system, not null 221 * @return the calendar system associated with the locale, not null 222 * @throws DateTimeException if the locale-specified calendar cannot be found 223 */ ofLocale(Locale locale)224 static Chronology ofLocale(Locale locale) { 225 return AbstractChronology.ofLocale(locale); 226 } 227 228 //----------------------------------------------------------------------- 229 /** 230 * Obtains an instance of {@code Chronology} from a chronology ID or 231 * calendar system type. 232 * <p> 233 * This returns a chronology based on either the ID or the type. 234 * The {@link #getId() chronology ID} uniquely identifies the chronology. 235 * The {@link #getCalendarType() calendar system type} is defined by the 236 * CLDR specification. 237 * <p> 238 * The chronology may be a system chronology or a chronology 239 * provided by the application via ServiceLoader configuration. 240 * <p> 241 * Since some calendars can be customized, the ID or type typically refers 242 * to the default customization. For example, the Gregorian calendar can have multiple 243 * cutover dates from the Julian, but the lookup only provides the default cutover date. 244 * 245 * @param id the chronology ID or calendar system type, not null 246 * @return the chronology with the identifier requested, not null 247 * @throws DateTimeException if the chronology cannot be found 248 */ of(String id)249 static Chronology of(String id) { 250 return AbstractChronology.of(id); 251 } 252 253 /** 254 * Returns the available chronologies. 255 * <p> 256 * Each returned {@code Chronology} is available for use in the system. 257 * The set of chronologies includes the system chronologies and 258 * any chronologies provided by the application via ServiceLoader 259 * configuration. 260 * 261 * @return the independent, modifiable set of the available chronology IDs, not null 262 */ getAvailableChronologies()263 static Set<Chronology> getAvailableChronologies() { 264 return AbstractChronology.getAvailableChronologies(); 265 } 266 267 //----------------------------------------------------------------------- 268 /** 269 * Gets the ID of the chronology. 270 * <p> 271 * The ID uniquely identifies the {@code Chronology}. 272 * It can be used to lookup the {@code Chronology} using {@link #of(String)}. 273 * 274 * @return the chronology ID, not null 275 * @see #getCalendarType() 276 */ getId()277 String getId(); 278 279 /** 280 * Gets the calendar type of the calendar system. 281 * <p> 282 * The calendar type is an identifier defined by the CLDR and 283 * <em>Unicode Locale Data Markup Language (LDML)</em> specifications 284 * to uniquely identification a calendar. 285 * The {@code getCalendarType} is the concatenation of the CLDR calendar type 286 * and the variant, if applicable, is appended separated by "-". 287 * The calendar type is used to lookup the {@code Chronology} using {@link #of(String)}. 288 * 289 * @return the calendar system type, null if the calendar is not defined by CLDR/LDML 290 * @see #getId() 291 */ getCalendarType()292 String getCalendarType(); 293 294 //----------------------------------------------------------------------- 295 /** 296 * Obtains a local date in this chronology from the era, year-of-era, 297 * month-of-year and day-of-month fields. 298 * 299 * @implSpec 300 * The default implementation combines the era and year-of-era into a proleptic 301 * year before calling {@link #date(int, int, int)}. 302 * 303 * @param era the era of the correct type for the chronology, not null 304 * @param yearOfEra the chronology year-of-era 305 * @param month the chronology month-of-year 306 * @param dayOfMonth the chronology day-of-month 307 * @return the local date in this chronology, not null 308 * @throws DateTimeException if unable to create the date 309 * @throws ClassCastException if the {@code era} is not of the correct type for the chronology 310 */ date(Era era, int yearOfEra, int month, int dayOfMonth)311 default ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { 312 return date(prolepticYear(era, yearOfEra), month, dayOfMonth); 313 } 314 315 /** 316 * Obtains a local date in this chronology from the proleptic-year, 317 * month-of-year and day-of-month fields. 318 * 319 * @param prolepticYear the chronology proleptic-year 320 * @param month the chronology month-of-year 321 * @param dayOfMonth the chronology day-of-month 322 * @return the local date in this chronology, not null 323 * @throws DateTimeException if unable to create the date 324 */ date(int prolepticYear, int month, int dayOfMonth)325 ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); 326 327 /** 328 * Obtains a local date in this chronology from the era, year-of-era and 329 * day-of-year fields. 330 * 331 * @implSpec 332 * The default implementation combines the era and year-of-era into a proleptic 333 * year before calling {@link #dateYearDay(int, int)}. 334 * 335 * @param era the era of the correct type for the chronology, not null 336 * @param yearOfEra the chronology year-of-era 337 * @param dayOfYear the chronology day-of-year 338 * @return the local date in this chronology, not null 339 * @throws DateTimeException if unable to create the date 340 * @throws ClassCastException if the {@code era} is not of the correct type for the chronology 341 */ dateYearDay(Era era, int yearOfEra, int dayOfYear)342 default ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { 343 return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); 344 } 345 346 /** 347 * Obtains a local date in this chronology from the proleptic-year and 348 * day-of-year fields. 349 * 350 * @param prolepticYear the chronology proleptic-year 351 * @param dayOfYear the chronology day-of-year 352 * @return the local date in this chronology, not null 353 * @throws DateTimeException if unable to create the date 354 */ dateYearDay(int prolepticYear, int dayOfYear)355 ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); 356 357 /** 358 * Obtains a local date in this chronology from the epoch-day. 359 * <p> 360 * The definition of {@link ChronoField#EPOCH_DAY EPOCH_DAY} is the same 361 * for all calendar systems, thus it can be used for conversion. 362 * 363 * @param epochDay the epoch day 364 * @return the local date in this chronology, not null 365 * @throws DateTimeException if unable to create the date 366 */ dateEpochDay(long epochDay)367 ChronoLocalDate dateEpochDay(long epochDay); 368 369 //----------------------------------------------------------------------- 370 /** 371 * Obtains the current local date in this chronology from the system clock in the default time-zone. 372 * <p> 373 * This will query the {@link Clock#systemDefaultZone() system clock} in the default 374 * time-zone to obtain the current date. 375 * <p> 376 * Using this method will prevent the ability to use an alternate clock for testing 377 * because the clock is hard-coded. 378 * 379 * @implSpec 380 * The default implementation invokes {@link #dateNow(Clock)}. 381 * 382 * @return the current local date using the system clock and default time-zone, not null 383 * @throws DateTimeException if unable to create the date 384 */ dateNow()385 default ChronoLocalDate dateNow() { 386 return dateNow(Clock.systemDefaultZone()); 387 } 388 389 /** 390 * Obtains the current local date in this chronology from the system clock in the specified time-zone. 391 * <p> 392 * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date. 393 * Specifying the time-zone avoids dependence on the default time-zone. 394 * <p> 395 * Using this method will prevent the ability to use an alternate clock for testing 396 * because the clock is hard-coded. 397 * 398 * @implSpec 399 * The default implementation invokes {@link #dateNow(Clock)}. 400 * 401 * @param zone the zone ID to use, not null 402 * @return the current local date using the system clock, not null 403 * @throws DateTimeException if unable to create the date 404 */ dateNow(ZoneId zone)405 default ChronoLocalDate dateNow(ZoneId zone) { 406 return dateNow(Clock.system(zone)); 407 } 408 409 /** 410 * Obtains the current local date in this chronology from the specified clock. 411 * <p> 412 * This will query the specified clock to obtain the current date - today. 413 * Using this method allows the use of an alternate clock for testing. 414 * The alternate clock may be introduced using {@link Clock dependency injection}. 415 * 416 * @implSpec 417 * The default implementation invokes {@link #date(TemporalAccessor)}. 418 * 419 * @param clock the clock to use, not null 420 * @return the current local date, not null 421 * @throws DateTimeException if unable to create the date 422 */ dateNow(Clock clock)423 default ChronoLocalDate dateNow(Clock clock) { 424 Objects.requireNonNull(clock, "clock"); 425 return date(LocalDate.now(clock)); 426 } 427 428 //----------------------------------------------------------------------- 429 /** 430 * Obtains a local date in this chronology from another temporal object. 431 * <p> 432 * This obtains a date in this chronology based on the specified temporal. 433 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 434 * which this factory converts to an instance of {@code ChronoLocalDate}. 435 * <p> 436 * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY} 437 * field, which is standardized across calendar systems. 438 * <p> 439 * This method matches the signature of the functional interface {@link TemporalQuery} 440 * allowing it to be used as a query via method reference, {@code aChronology::date}. 441 * 442 * @param temporal the temporal object to convert, not null 443 * @return the local date in this chronology, not null 444 * @throws DateTimeException if unable to create the date 445 * @see ChronoLocalDate#from(TemporalAccessor) 446 */ date(TemporalAccessor temporal)447 ChronoLocalDate date(TemporalAccessor temporal); 448 449 /** 450 * Obtains a local date-time in this chronology from another temporal object. 451 * <p> 452 * This obtains a date-time in this chronology based on the specified temporal. 453 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 454 * which this factory converts to an instance of {@code ChronoLocalDateTime}. 455 * <p> 456 * The conversion extracts and combines the {@code ChronoLocalDate} and the 457 * {@code LocalTime} from the temporal object. 458 * Implementations are permitted to perform optimizations such as accessing 459 * those fields that are equivalent to the relevant objects. 460 * The result uses this chronology. 461 * <p> 462 * This method matches the signature of the functional interface {@link TemporalQuery} 463 * allowing it to be used as a query via method reference, {@code aChronology::localDateTime}. 464 * 465 * @param temporal the temporal object to convert, not null 466 * @return the local date-time in this chronology, not null 467 * @throws DateTimeException if unable to create the date-time 468 * @see ChronoLocalDateTime#from(TemporalAccessor) 469 */ localDateTime(TemporalAccessor temporal)470 default ChronoLocalDateTime<? extends ChronoLocalDate> localDateTime(TemporalAccessor temporal) { 471 try { 472 return date(temporal).atTime(LocalTime.from(temporal)); 473 } catch (DateTimeException ex) { 474 throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass(), ex); 475 } 476 } 477 478 /** 479 * Obtains a {@code ChronoZonedDateTime} in this chronology from another temporal object. 480 * <p> 481 * This obtains a zoned date-time in this chronology based on the specified temporal. 482 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 483 * which this factory converts to an instance of {@code ChronoZonedDateTime}. 484 * <p> 485 * The conversion will first obtain a {@code ZoneId} from the temporal object, 486 * falling back to a {@code ZoneOffset} if necessary. It will then try to obtain 487 * an {@code Instant}, falling back to a {@code ChronoLocalDateTime} if necessary. 488 * The result will be either the combination of {@code ZoneId} or {@code ZoneOffset} 489 * with {@code Instant} or {@code ChronoLocalDateTime}. 490 * Implementations are permitted to perform optimizations such as accessing 491 * those fields that are equivalent to the relevant objects. 492 * The result uses this chronology. 493 * <p> 494 * This method matches the signature of the functional interface {@link TemporalQuery} 495 * allowing it to be used as a query via method reference, {@code aChronology::zonedDateTime}. 496 * 497 * @param temporal the temporal object to convert, not null 498 * @return the zoned date-time in this chronology, not null 499 * @throws DateTimeException if unable to create the date-time 500 * @see ChronoZonedDateTime#from(TemporalAccessor) 501 */ zonedDateTime(TemporalAccessor temporal)502 default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(TemporalAccessor temporal) { 503 try { 504 ZoneId zone = ZoneId.from(temporal); 505 try { 506 Instant instant = Instant.from(temporal); 507 return zonedDateTime(instant, zone); 508 509 } catch (DateTimeException ex1) { 510 ChronoLocalDateTimeImpl<?> cldt = ChronoLocalDateTimeImpl.ensureValid(this, localDateTime(temporal)); 511 return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null); 512 } 513 } catch (DateTimeException ex) { 514 throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex); 515 } 516 } 517 518 /** 519 * Obtains a {@code ChronoZonedDateTime} in this chronology from an {@code Instant}. 520 * <p> 521 * This obtains a zoned date-time with the same instant as that specified. 522 * 523 * @param instant the instant to create the date-time from, not null 524 * @param zone the time-zone, not null 525 * @return the zoned date-time, not null 526 * @throws DateTimeException if the result exceeds the supported range 527 */ zonedDateTime(Instant instant, ZoneId zone)528 default ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(Instant instant, ZoneId zone) { 529 return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); 530 } 531 532 //----------------------------------------------------------------------- 533 /** 534 * Checks if the specified year is a leap year. 535 * <p> 536 * A leap-year is a year of a longer length than normal. 537 * The exact meaning is determined by the chronology according to the following constraints. 538 * <ul> 539 * <li>a leap-year must imply a year-length longer than a non leap-year. 540 * <li>a chronology that does not support the concept of a year must return false. 541 * </ul> 542 * 543 * @param prolepticYear the proleptic-year to check, not validated for range 544 * @return true if the year is a leap year 545 */ isLeapYear(long prolepticYear)546 boolean isLeapYear(long prolepticYear); 547 548 /** 549 * Calculates the proleptic-year given the era and year-of-era. 550 * <p> 551 * This combines the era and year-of-era into the single proleptic-year field. 552 * <p> 553 * If the chronology makes active use of eras, such as {@code JapaneseChronology} 554 * then the year-of-era will be validated against the era. 555 * For other chronologies, validation is optional. 556 * 557 * @param era the era of the correct type for the chronology, not null 558 * @param yearOfEra the chronology year-of-era 559 * @return the proleptic-year 560 * @throws DateTimeException if unable to convert to a proleptic-year, 561 * such as if the year is invalid for the era 562 * @throws ClassCastException if the {@code era} is not of the correct type for the chronology 563 */ prolepticYear(Era era, int yearOfEra)564 int prolepticYear(Era era, int yearOfEra); 565 566 /** 567 * Creates the chronology era object from the numeric value. 568 * <p> 569 * The era is, conceptually, the largest division of the time-line. 570 * Most calendar systems have a single epoch dividing the time-line into two eras. 571 * However, some have multiple eras, such as one for the reign of each leader. 572 * The exact meaning is determined by the chronology according to the following constraints. 573 * <p> 574 * The era in use at 1970-01-01 must have the value 1. 575 * Later eras must have sequentially higher values. 576 * Earlier eras must have sequentially lower values. 577 * Each chronology must refer to an enum or similar singleton to provide the era values. 578 * <p> 579 * This method returns the singleton era of the correct type for the specified era value. 580 * 581 * @param eraValue the era value 582 * @return the calendar system era, not null 583 * @throws DateTimeException if unable to create the era 584 */ eraOf(int eraValue)585 Era eraOf(int eraValue); 586 587 /** 588 * Gets the list of eras for the chronology. 589 * <p> 590 * Most calendar systems have an era, within which the year has meaning. 591 * If the calendar system does not support the concept of eras, an empty 592 * list must be returned. 593 * 594 * @return the list of eras for the chronology, may be immutable, not null 595 */ eras()596 List<Era> eras(); 597 598 //----------------------------------------------------------------------- 599 /** 600 * Gets the range of valid values for the specified field. 601 * <p> 602 * All fields can be expressed as a {@code long} integer. 603 * This method returns an object that describes the valid range for that value. 604 * <p> 605 * Note that the result only describes the minimum and maximum valid values 606 * and it is important not to read too much into them. For example, there 607 * could be values within the range that are invalid for the field. 608 * <p> 609 * This method will return a result whether or not the chronology supports the field. 610 * 611 * @param field the field to get the range for, not null 612 * @return the range of valid values for the field, not null 613 * @throws DateTimeException if the range for the field cannot be obtained 614 */ range(ChronoField field)615 ValueRange range(ChronoField field); 616 617 //----------------------------------------------------------------------- 618 /** 619 * Gets the textual representation of this chronology. 620 * <p> 621 * This returns the textual name used to identify the chronology, 622 * suitable for presentation to the user. 623 * The parameters control the style of the returned text and the locale. 624 * 625 * @implSpec 626 * The default implementation behaves as though the formatter was used to 627 * format the chronology textual name. 628 * 629 * @param style the style of the text required, not null 630 * @param locale the locale to use, not null 631 * @return the text value of the chronology, not null 632 */ getDisplayName(TextStyle style, Locale locale)633 default String getDisplayName(TextStyle style, Locale locale) { 634 TemporalAccessor temporal = new TemporalAccessor() { 635 @Override 636 public boolean isSupported(TemporalField field) { 637 return false; 638 } 639 @Override 640 public long getLong(TemporalField field) { 641 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 642 } 643 @SuppressWarnings("unchecked") 644 @Override 645 public <R> R query(TemporalQuery<R> query) { 646 if (query == TemporalQueries.chronology()) { 647 return (R) Chronology.this; 648 } 649 return TemporalAccessor.super.query(query); 650 } 651 }; 652 return new DateTimeFormatterBuilder().appendChronologyText(style).toFormatter(locale).format(temporal); 653 } 654 655 //----------------------------------------------------------------------- 656 /** 657 * Resolves parsed {@code ChronoField} values into a date during parsing. 658 * <p> 659 * Most {@code TemporalField} implementations are resolved using the 660 * resolve method on the field. By contrast, the {@code ChronoField} class 661 * defines fields that only have meaning relative to the chronology. 662 * As such, {@code ChronoField} date fields are resolved here in the 663 * context of a specific chronology. 664 * <p> 665 * The default implementation, which explains typical resolve behaviour, 666 * is provided in {@link AbstractChronology}. 667 * 668 * @param fieldValues the map of fields to values, which can be updated, not null 669 * @param resolverStyle the requested type of resolve, not null 670 * @return the resolved date, null if insufficient information to create a date 671 * @throws DateTimeException if the date cannot be resolved, typically 672 * because of a conflict in the input data 673 */ resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle)674 ChronoLocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle); 675 676 //----------------------------------------------------------------------- 677 /** 678 * Obtains a period for this chronology based on years, months and days. 679 * <p> 680 * This returns a period tied to this chronology using the specified 681 * years, months and days. All supplied chronologies use periods 682 * based on years, months and days, however the {@code ChronoPeriod} API 683 * allows the period to be represented using other units. 684 * 685 * @implSpec 686 * The default implementation returns an implementation class suitable 687 * for most calendar systems. It is based solely on the three units. 688 * Normalization, addition and subtraction derive the number of months 689 * in a year from the {@link #range(ChronoField)}. If the number of 690 * months within a year is fixed, then the calculation approach for 691 * addition, subtraction and normalization is slightly different. 692 * <p> 693 * If implementing an unusual calendar system that is not based on 694 * years, months and days, or where you want direct control, then 695 * the {@code ChronoPeriod} interface must be directly implemented. 696 * <p> 697 * The returned period is immutable and thread-safe. 698 * 699 * @param years the number of years, may be negative 700 * @param months the number of years, may be negative 701 * @param days the number of years, may be negative 702 * @return the period in terms of this chronology, not null 703 */ period(int years, int months, int days)704 default ChronoPeriod period(int years, int months, int days) { 705 return new ChronoPeriodImpl(this, years, months, days); 706 } 707 708 //----------------------------------------------------------------------- 709 /** 710 * Compares this chronology to another chronology. 711 * <p> 712 * The comparison order first by the chronology ID string, then by any 713 * additional information specific to the subclass. 714 * It is "consistent with equals", as defined by {@link Comparable}. 715 * 716 * @param other the other chronology to compare to, not null 717 * @return the comparator value, negative if less, positive if greater 718 */ 719 @Override compareTo(Chronology other)720 int compareTo(Chronology other); 721 722 /** 723 * Checks if this chronology is equal to another chronology. 724 * <p> 725 * The comparison is based on the entire state of the object. 726 * 727 * @param obj the object to check, null returns false 728 * @return true if this is equal to the other chronology 729 */ 730 @Override equals(Object obj)731 boolean equals(Object obj); 732 733 /** 734 * A hash code for this chronology. 735 * <p> 736 * The hash code should be based on the entire state of the object. 737 * 738 * @return a suitable hash code 739 */ 740 @Override hashCode()741 int hashCode(); 742 743 //----------------------------------------------------------------------- 744 /** 745 * Outputs this chronology as a {@code String}. 746 * <p> 747 * The format should include the entire state of the object. 748 * 749 * @return a string representation of this chronology, not null 750 */ 751 @Override toString()752 String toString(); 753 754 } 755