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