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 static java.time.temporal.ChronoField.EPOCH_DAY; 65 import static java.time.temporal.ChronoField.ERA; 66 import static java.time.temporal.ChronoField.YEAR; 67 import static java.time.temporal.ChronoUnit.DAYS; 68 69 import java.time.DateTimeException; 70 import java.time.LocalDate; 71 import java.time.LocalTime; 72 import java.time.format.DateTimeFormatter; 73 import java.time.temporal.ChronoField; 74 import java.time.temporal.ChronoUnit; 75 import java.time.temporal.Temporal; 76 import java.time.temporal.TemporalAccessor; 77 import java.time.temporal.TemporalAdjuster; 78 import java.time.temporal.TemporalAmount; 79 import java.time.temporal.TemporalField; 80 import java.time.temporal.TemporalQueries; 81 import java.time.temporal.TemporalQuery; 82 import java.time.temporal.TemporalUnit; 83 import java.time.temporal.UnsupportedTemporalTypeException; 84 import java.util.Comparator; 85 import java.util.Objects; 86 87 /** 88 * A date without time-of-day or time-zone in an arbitrary chronology, intended 89 * for advanced globalization use cases. 90 * <p> 91 * <b>Most applications should declare method signatures, fields and variables 92 * as {@link LocalDate}, not this interface.</b> 93 * <p> 94 * A {@code ChronoLocalDate} is the abstract representation of a date where the 95 * {@code Chronology chronology}, or calendar system, is pluggable. 96 * The date is defined in terms of fields expressed by {@link TemporalField}, 97 * where most common implementations are defined in {@link ChronoField}. 98 * The chronology defines how the calendar system operates and the meaning of 99 * the standard fields. 100 * 101 * <h3>When to use this interface</h3> 102 * The design of the API encourages the use of {@code LocalDate} rather than this 103 * interface, even in the case where the application needs to deal with multiple 104 * calendar systems. 105 * <p> 106 * This concept can seem surprising at first, as the natural way to globalize an 107 * application might initially appear to be to abstract the calendar system. 108 * However, as explored below, abstracting the calendar system is usually the wrong 109 * approach, resulting in logic errors and hard to find bugs. 110 * As such, it should be considered an application-wide architectural decision to choose 111 * to use this interface as opposed to {@code LocalDate}. 112 * 113 * <h3>Architectural issues to consider</h3> 114 * These are some of the points that must be considered before using this interface 115 * throughout an application. 116 * <p> 117 * 1) Applications using this interface, as opposed to using just {@code LocalDate}, 118 * face a significantly higher probability of bugs. This is because the calendar system 119 * in use is not known at development time. A key cause of bugs is where the developer 120 * applies assumptions from their day-to-day knowledge of the ISO calendar system 121 * to code that is intended to deal with any arbitrary calendar system. 122 * The section below outlines how those assumptions can cause problems 123 * The primary mechanism for reducing this increased risk of bugs is a strong code review process. 124 * This should also be considered a extra cost in maintenance for the lifetime of the code. 125 * <p> 126 * 2) This interface does not enforce immutability of implementations. 127 * While the implementation notes indicate that all implementations must be immutable 128 * there is nothing in the code or type system to enforce this. Any method declared 129 * to accept a {@code ChronoLocalDate} could therefore be passed a poorly or 130 * maliciously written mutable implementation. 131 * <p> 132 * 3) Applications using this interface must consider the impact of eras. 133 * {@code LocalDate} shields users from the concept of eras, by ensuring that {@code getYear()} 134 * returns the proleptic year. That decision ensures that developers can think of 135 * {@code LocalDate} instances as consisting of three fields - year, month-of-year and day-of-month. 136 * By contrast, users of this interface must think of dates as consisting of four fields - 137 * era, year-of-era, month-of-year and day-of-month. The extra era field is frequently 138 * forgotten, yet it is of vital importance to dates in an arbitrary calendar system. 139 * For example, in the Japanese calendar system, the era represents the reign of an Emperor. 140 * Whenever one reign ends and another starts, the year-of-era is reset to one. 141 * <p> 142 * 4) The only agreed international standard for passing a date between two systems 143 * is the ISO-8601 standard which requires the ISO calendar system. Using this interface 144 * throughout the application will inevitably lead to the requirement to pass the date 145 * across a network or component boundary, requiring an application specific protocol or format. 146 * <p> 147 * 5) Long term persistence, such as a database, will almost always only accept dates in the 148 * ISO-8601 calendar system (or the related Julian-Gregorian). Passing around dates in other 149 * calendar systems increases the complications of interacting with persistence. 150 * <p> 151 * 6) Most of the time, passing a {@code ChronoLocalDate} throughout an application 152 * is unnecessary, as discussed in the last section below. 153 * 154 * <h3>False assumptions causing bugs in multi-calendar system code</h3> 155 * As indicated above, there are many issues to consider when try to use and manipulate a 156 * date in an arbitrary calendar system. These are some of the key issues. 157 * <p> 158 * Code that queries the day-of-month and assumes that the value will never be more than 159 * 31 is invalid. Some calendar systems have more than 31 days in some months. 160 * <p> 161 * Code that adds 12 months to a date and assumes that a year has been added is invalid. 162 * Some calendar systems have a different number of months, such as 13 in the Coptic or Ethiopic. 163 * <p> 164 * Code that adds one month to a date and assumes that the month-of-year value will increase 165 * by one or wrap to the next year is invalid. Some calendar systems have a variable number 166 * of months in a year, such as the Hebrew. 167 * <p> 168 * Code that adds one month, then adds a second one month and assumes that the day-of-month 169 * will remain close to its original value is invalid. Some calendar systems have a large difference 170 * between the length of the longest month and the length of the shortest month. 171 * For example, the Coptic or Ethiopic have 12 months of 30 days and 1 month of 5 days. 172 * <p> 173 * Code that adds seven days and assumes that a week has been added is invalid. 174 * Some calendar systems have weeks of other than seven days, such as the French Revolutionary. 175 * <p> 176 * Code that assumes that because the year of {@code date1} is greater than the year of {@code date2} 177 * then {@code date1} is after {@code date2} is invalid. This is invalid for all calendar systems 178 * when referring to the year-of-era, and especially untrue of the Japanese calendar system 179 * where the year-of-era restarts with the reign of every new Emperor. 180 * <p> 181 * Code that treats month-of-year one and day-of-month one as the start of the year is invalid. 182 * Not all calendar systems start the year when the month value is one. 183 * <p> 184 * In general, manipulating a date, and even querying a date, is wide open to bugs when the 185 * calendar system is unknown at development time. This is why it is essential that code using 186 * this interface is subjected to additional code reviews. It is also why an architectural 187 * decision to avoid this interface type is usually the correct one. 188 * 189 * <h3>Using LocalDate instead</h3> 190 * The primary alternative to using this interface throughout your application is as follows. 191 * <ul> 192 * <li>Declare all method signatures referring to dates in terms of {@code LocalDate}. 193 * <li>Either store the chronology (calendar system) in the user profile or lookup 194 * the chronology from the user locale 195 * <li>Convert the ISO {@code LocalDate} to and from the user's preferred calendar system during 196 * printing and parsing 197 * </ul> 198 * This approach treats the problem of globalized calendar systems as a localization issue 199 * and confines it to the UI layer. This approach is in keeping with other localization 200 * issues in the java platform. 201 * <p> 202 * As discussed above, performing calculations on a date where the rules of the calendar system 203 * are pluggable requires skill and is not recommended. 204 * Fortunately, the need to perform calculations on a date in an arbitrary calendar system 205 * is extremely rare. For example, it is highly unlikely that the business rules of a library 206 * book rental scheme will allow rentals to be for one month, where meaning of the month 207 * is dependent on the user's preferred calendar system. 208 * <p> 209 * A key use case for calculations on a date in an arbitrary calendar system is producing 210 * a month-by-month calendar for display and user interaction. Again, this is a UI issue, 211 * and use of this interface solely within a few methods of the UI layer may be justified. 212 * <p> 213 * In any other part of the system, where a date must be manipulated in a calendar system 214 * other than ISO, the use case will generally specify the calendar system to use. 215 * For example, an application may need to calculate the next Islamic or Hebrew holiday 216 * which may require manipulating the date. 217 * This kind of use case can be handled as follows: 218 * <ul> 219 * <li>start from the ISO {@code LocalDate} being passed to the method 220 * <li>convert the date to the alternate calendar system, which for this use case is known 221 * rather than arbitrary 222 * <li>perform the calculation 223 * <li>convert back to {@code LocalDate} 224 * </ul> 225 * Developers writing low-level frameworks or libraries should also avoid this interface. 226 * Instead, one of the two general purpose access interfaces should be used. 227 * Use {@link TemporalAccessor} if read-only access is required, or use {@link Temporal} 228 * if read-write access is required. 229 * 230 * @implSpec 231 * This interface must be implemented with care to ensure other classes operate correctly. 232 * All implementations that can be instantiated must be final, immutable and thread-safe. 233 * Subclasses should be Serializable wherever possible. 234 * <p> 235 * Additional calendar systems may be added to the system. 236 * See {@link Chronology} for more details. 237 * 238 * @since 1.8 239 */ 240 public interface ChronoLocalDate 241 extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> { 242 243 /** 244 * Gets a comparator that compares {@code ChronoLocalDate} in 245 * time-line order ignoring the chronology. 246 * <p> 247 * This comparator differs from the comparison in {@link #compareTo} in that it 248 * only compares the underlying date and not the chronology. 249 * This allows dates in different calendar systems to be compared based 250 * on the position of the date on the local time-line. 251 * The underlying comparison is equivalent to comparing the epoch-day. 252 * 253 * @return a comparator that compares in time-line order ignoring the chronology 254 * @see #isAfter 255 * @see #isBefore 256 * @see #isEqual 257 */ timeLineOrder()258 static Comparator<ChronoLocalDate> timeLineOrder() { 259 return AbstractChronology.DATE_ORDER; 260 } 261 262 //----------------------------------------------------------------------- 263 /** 264 * Obtains an instance of {@code ChronoLocalDate} from a temporal object. 265 * <p> 266 * This obtains a local date based on the specified temporal. 267 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 268 * which this factory converts to an instance of {@code ChronoLocalDate}. 269 * <p> 270 * The conversion extracts and combines the chronology and the date 271 * from the temporal object. The behavior is equivalent to using 272 * {@link Chronology#date(TemporalAccessor)} with the extracted chronology. 273 * Implementations are permitted to perform optimizations such as accessing 274 * those fields that are equivalent to the relevant objects. 275 * <p> 276 * This method matches the signature of the functional interface {@link TemporalQuery} 277 * allowing it to be used as a query via method reference, {@code ChronoLocalDate::from}. 278 * 279 * @param temporal the temporal object to convert, not null 280 * @return the date, not null 281 * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate} 282 * @see Chronology#date(TemporalAccessor) 283 */ from(TemporalAccessor temporal)284 static ChronoLocalDate from(TemporalAccessor temporal) { 285 if (temporal instanceof ChronoLocalDate) { 286 return (ChronoLocalDate) temporal; 287 } 288 Objects.requireNonNull(temporal, "temporal"); 289 Chronology chrono = temporal.query(TemporalQueries.chronology()); 290 if (chrono == null) { 291 throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass()); 292 } 293 return chrono.date(temporal); 294 } 295 296 //----------------------------------------------------------------------- 297 /** 298 * Gets the chronology of this date. 299 * <p> 300 * The {@code Chronology} represents the calendar system in use. 301 * The era and other fields in {@link ChronoField} are defined by the chronology. 302 * 303 * @return the chronology, not null 304 */ getChronology()305 Chronology getChronology(); 306 307 /** 308 * Gets the era, as defined by the chronology. 309 * <p> 310 * The era is, conceptually, the largest division of the time-line. 311 * Most calendar systems have a single epoch dividing the time-line into two eras. 312 * However, some have multiple eras, such as one for the reign of each leader. 313 * The exact meaning is determined by the {@code Chronology}. 314 * <p> 315 * All correctly implemented {@code Era} classes are singletons, thus it 316 * is valid code to write {@code date.getEra() == SomeChrono.ERA_NAME)}. 317 * <p> 318 * This default implementation uses {@link Chronology#eraOf(int)}. 319 * 320 * @return the chronology specific era constant applicable at this date, not null 321 */ getEra()322 default Era getEra() { 323 return getChronology().eraOf(get(ERA)); 324 } 325 326 /** 327 * Checks if the year is a leap year, as defined by the calendar system. 328 * <p> 329 * A leap-year is a year of a longer length than normal. 330 * The exact meaning is determined by the chronology with the constraint that 331 * a leap-year must imply a year-length longer than a non leap-year. 332 * <p> 333 * This default implementation uses {@link Chronology#isLeapYear(long)}. 334 * 335 * @return true if this date is in a leap year, false otherwise 336 */ isLeapYear()337 default boolean isLeapYear() { 338 return getChronology().isLeapYear(getLong(YEAR)); 339 } 340 341 /** 342 * Returns the length of the month represented by this date, as defined by the calendar system. 343 * <p> 344 * This returns the length of the month in days. 345 * 346 * @return the length of the month in days 347 */ lengthOfMonth()348 int lengthOfMonth(); 349 350 /** 351 * Returns the length of the year represented by this date, as defined by the calendar system. 352 * <p> 353 * This returns the length of the year in days. 354 * <p> 355 * The default implementation uses {@link #isLeapYear()} and returns 365 or 366. 356 * 357 * @return the length of the year in days 358 */ lengthOfYear()359 default int lengthOfYear() { 360 return (isLeapYear() ? 366 : 365); 361 } 362 363 /** 364 * Checks if the specified field is supported. 365 * <p> 366 * This checks if the specified field can be queried on this date. 367 * If false, then calling the {@link #range(TemporalField) range}, 368 * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} 369 * methods will throw an exception. 370 * <p> 371 * The set of supported fields is defined by the chronology and normally includes 372 * all {@code ChronoField} date fields. 373 * <p> 374 * If the field is not a {@code ChronoField}, then the result of this method 375 * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} 376 * passing {@code this} as the argument. 377 * Whether the field is supported is determined by the field. 378 * 379 * @param field the field to check, null returns false 380 * @return true if the field can be queried, false if not 381 */ 382 @Override isSupported(TemporalField field)383 default boolean isSupported(TemporalField field) { 384 if (field instanceof ChronoField) { 385 return field.isDateBased(); 386 } 387 return field != null && field.isSupportedBy(this); 388 } 389 390 /** 391 * Checks if the specified unit is supported. 392 * <p> 393 * This checks if the specified unit can be added to or subtracted from this date. 394 * If false, then calling the {@link #plus(long, TemporalUnit)} and 395 * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. 396 * <p> 397 * The set of supported units is defined by the chronology and normally includes 398 * all {@code ChronoUnit} date units except {@code FOREVER}. 399 * <p> 400 * If the unit is not a {@code ChronoUnit}, then the result of this method 401 * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} 402 * passing {@code this} as the argument. 403 * Whether the unit is supported is determined by the unit. 404 * 405 * @param unit the unit to check, null returns false 406 * @return true if the unit can be added/subtracted, false if not 407 */ 408 @Override isSupported(TemporalUnit unit)409 default boolean isSupported(TemporalUnit unit) { 410 if (unit instanceof ChronoUnit) { 411 return unit.isDateBased(); 412 } 413 return unit != null && unit.isSupportedBy(this); 414 } 415 416 //----------------------------------------------------------------------- 417 // override for covariant return type 418 /** 419 * {@inheritDoc} 420 * @throws DateTimeException {@inheritDoc} 421 * @throws ArithmeticException {@inheritDoc} 422 */ 423 @Override with(TemporalAdjuster adjuster)424 default ChronoLocalDate with(TemporalAdjuster adjuster) { 425 return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); 426 } 427 428 /** 429 * {@inheritDoc} 430 * @throws DateTimeException {@inheritDoc} 431 * @throws UnsupportedTemporalTypeException {@inheritDoc} 432 * @throws ArithmeticException {@inheritDoc} 433 */ 434 @Override with(TemporalField field, long newValue)435 default ChronoLocalDate with(TemporalField field, long newValue) { 436 if (field instanceof ChronoField) { 437 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 438 } 439 return ChronoLocalDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); 440 } 441 442 /** 443 * {@inheritDoc} 444 * @throws DateTimeException {@inheritDoc} 445 * @throws ArithmeticException {@inheritDoc} 446 */ 447 @Override plus(TemporalAmount amount)448 default ChronoLocalDate plus(TemporalAmount amount) { 449 return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); 450 } 451 452 /** 453 * {@inheritDoc} 454 * @throws DateTimeException {@inheritDoc} 455 * @throws ArithmeticException {@inheritDoc} 456 */ 457 @Override plus(long amountToAdd, TemporalUnit unit)458 default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) { 459 if (unit instanceof ChronoUnit) { 460 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); 461 } 462 return ChronoLocalDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); 463 } 464 465 /** 466 * {@inheritDoc} 467 * @throws DateTimeException {@inheritDoc} 468 * @throws ArithmeticException {@inheritDoc} 469 */ 470 @Override minus(TemporalAmount amount)471 default ChronoLocalDate minus(TemporalAmount amount) { 472 return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); 473 } 474 475 /** 476 * {@inheritDoc} 477 * @throws DateTimeException {@inheritDoc} 478 * @throws UnsupportedTemporalTypeException {@inheritDoc} 479 * @throws ArithmeticException {@inheritDoc} 480 */ 481 @Override minus(long amountToSubtract, TemporalUnit unit)482 default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { 483 return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); 484 } 485 486 //----------------------------------------------------------------------- 487 /** 488 * Queries this date using the specified query. 489 * <p> 490 * This queries this date using the specified query strategy object. 491 * The {@code TemporalQuery} object defines the logic to be used to 492 * obtain the result. Read the documentation of the query to understand 493 * what the result of this method will be. 494 * <p> 495 * The result of this method is obtained by invoking the 496 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the 497 * specified query passing {@code this} as the argument. 498 * 499 * @param <R> the type of the result 500 * @param query the query to invoke, not null 501 * @return the query result, null may be returned (defined by the query) 502 * @throws DateTimeException if unable to query (defined by the query) 503 * @throws ArithmeticException if numeric overflow occurs (defined by the query) 504 */ 505 @SuppressWarnings("unchecked") 506 @Override query(TemporalQuery<R> query)507 default <R> R query(TemporalQuery<R> query) { 508 if (query == TemporalQueries.zoneId() || query == TemporalQueries.zone() || query == TemporalQueries.offset()) { 509 return null; 510 } else if (query == TemporalQueries.localTime()) { 511 return null; 512 } else if (query == TemporalQueries.chronology()) { 513 return (R) getChronology(); 514 } else if (query == TemporalQueries.precision()) { 515 return (R) DAYS; 516 } 517 // inline TemporalAccessor.super.query(query) as an optimization 518 // non-JDK classes are not permitted to make this optimization 519 return query.queryFrom(this); 520 } 521 522 /** 523 * Adjusts the specified temporal object to have the same date as this object. 524 * <p> 525 * This returns a temporal object of the same observable type as the input 526 * with the date changed to be the same as this. 527 * <p> 528 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} 529 * passing {@link ChronoField#EPOCH_DAY} as the field. 530 * <p> 531 * In most cases, it is clearer to reverse the calling pattern by using 532 * {@link Temporal#with(TemporalAdjuster)}: 533 * <pre> 534 * // these two lines are equivalent, but the second approach is recommended 535 * temporal = thisLocalDate.adjustInto(temporal); 536 * temporal = temporal.with(thisLocalDate); 537 * </pre> 538 * <p> 539 * This instance is immutable and unaffected by this method call. 540 * 541 * @param temporal the target object to be adjusted, not null 542 * @return the adjusted object, not null 543 * @throws DateTimeException if unable to make the adjustment 544 * @throws ArithmeticException if numeric overflow occurs 545 */ 546 @Override adjustInto(Temporal temporal)547 default Temporal adjustInto(Temporal temporal) { 548 return temporal.with(EPOCH_DAY, toEpochDay()); 549 } 550 551 /** 552 * Calculates the amount of time until another date in terms of the specified unit. 553 * <p> 554 * This calculates the amount of time between two {@code ChronoLocalDate} 555 * objects in terms of a single {@code TemporalUnit}. 556 * The start and end points are {@code this} and the specified date. 557 * The result will be negative if the end is before the start. 558 * The {@code Temporal} passed to this method is converted to a 559 * {@code ChronoLocalDate} using {@link Chronology#date(TemporalAccessor)}. 560 * The calculation returns a whole number, representing the number of 561 * complete units between the two dates. 562 * For example, the amount in days between two dates can be calculated 563 * using {@code startDate.until(endDate, DAYS)}. 564 * <p> 565 * There are two equivalent ways of using this method. 566 * The first is to invoke this method. 567 * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: 568 * <pre> 569 * // these two lines are equivalent 570 * amount = start.until(end, MONTHS); 571 * amount = MONTHS.between(start, end); 572 * </pre> 573 * The choice should be made based on which makes the code more readable. 574 * <p> 575 * The calculation is implemented in this method for {@link ChronoUnit}. 576 * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS}, 577 * {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} 578 * should be supported by all implementations. 579 * Other {@code ChronoUnit} values will throw an exception. 580 * <p> 581 * If the unit is not a {@code ChronoUnit}, then the result of this method 582 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} 583 * passing {@code this} as the first argument and the converted input temporal as 584 * the second argument. 585 * <p> 586 * This instance is immutable and unaffected by this method call. 587 * 588 * @param endExclusive the end date, exclusive, which is converted to a 589 * {@code ChronoLocalDate} in the same chronology, not null 590 * @param unit the unit to measure the amount in, not null 591 * @return the amount of time between this date and the end date 592 * @throws DateTimeException if the amount cannot be calculated, or the end 593 * temporal cannot be converted to a {@code ChronoLocalDate} 594 * @throws UnsupportedTemporalTypeException if the unit is not supported 595 * @throws ArithmeticException if numeric overflow occurs 596 */ 597 @Override // override for Javadoc until(Temporal endExclusive, TemporalUnit unit)598 long until(Temporal endExclusive, TemporalUnit unit); 599 600 /** 601 * Calculates the period between this date and another date as a {@code ChronoPeriod}. 602 * <p> 603 * This calculates the period between two dates. All supplied chronologies 604 * calculate the period using years, months and days, however the 605 * {@code ChronoPeriod} API allows the period to be represented using other units. 606 * <p> 607 * The start and end points are {@code this} and the specified date. 608 * The result will be negative if the end is before the start. 609 * The negative sign will be the same in each of year, month and day. 610 * <p> 611 * The calculation is performed using the chronology of this date. 612 * If necessary, the input date will be converted to match. 613 * <p> 614 * This instance is immutable and unaffected by this method call. 615 * 616 * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null 617 * @return the period between this date and the end date, not null 618 * @throws DateTimeException if the period cannot be calculated 619 * @throws ArithmeticException if numeric overflow occurs 620 */ until(ChronoLocalDate endDateExclusive)621 ChronoPeriod until(ChronoLocalDate endDateExclusive); 622 623 /** 624 * Formats this date using the specified formatter. 625 * <p> 626 * This date will be passed to the formatter to produce a string. 627 * <p> 628 * The default implementation must behave as follows: 629 * <pre> 630 * return formatter.format(this); 631 * </pre> 632 * 633 * @param formatter the formatter to use, not null 634 * @return the formatted date string, not null 635 * @throws DateTimeException if an error occurs during printing 636 */ format(DateTimeFormatter formatter)637 default String format(DateTimeFormatter formatter) { 638 Objects.requireNonNull(formatter, "formatter"); 639 return formatter.format(this); 640 } 641 642 //----------------------------------------------------------------------- 643 /** 644 * Combines this date with a time to create a {@code ChronoLocalDateTime}. 645 * <p> 646 * This returns a {@code ChronoLocalDateTime} formed from this date at the specified time. 647 * All possible combinations of date and time are valid. 648 * 649 * @param localTime the local time to use, not null 650 * @return the local date-time formed from this date and the specified time, not null 651 */ 652 @SuppressWarnings("unchecked") atTime(LocalTime localTime)653 default ChronoLocalDateTime<?> atTime(LocalTime localTime) { 654 return ChronoLocalDateTimeImpl.of(this, localTime); 655 } 656 657 //----------------------------------------------------------------------- 658 /** 659 * Converts this date to the Epoch Day. 660 * <p> 661 * The {@link ChronoField#EPOCH_DAY Epoch Day count} is a simple 662 * incrementing count of days where day 0 is 1970-01-01 (ISO). 663 * This definition is the same for all chronologies, enabling conversion. 664 * <p> 665 * This default implementation queries the {@code EPOCH_DAY} field. 666 * 667 * @return the Epoch Day equivalent to this date 668 */ toEpochDay()669 default long toEpochDay() { 670 return getLong(EPOCH_DAY); 671 } 672 673 //----------------------------------------------------------------------- 674 /** 675 * Compares this date to another date, including the chronology. 676 * <p> 677 * The comparison is based first on the underlying time-line date, then 678 * on the chronology. 679 * It is "consistent with equals", as defined by {@link Comparable}. 680 * <p> 681 * For example, the following is the comparator order: 682 * <ol> 683 * <li>{@code 2012-12-03 (ISO)}</li> 684 * <li>{@code 2012-12-04 (ISO)}</li> 685 * <li>{@code 2555-12-04 (ThaiBuddhist)}</li> 686 * <li>{@code 2012-12-05 (ISO)}</li> 687 * </ol> 688 * Values #2 and #3 represent the same date on the time-line. 689 * When two values represent the same date, the chronology ID is compared to distinguish them. 690 * This step is needed to make the ordering "consistent with equals". 691 * <p> 692 * If all the date objects being compared are in the same chronology, then the 693 * additional chronology stage is not required and only the local date is used. 694 * To compare the dates of two {@code TemporalAccessor} instances, including dates 695 * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator. 696 * <p> 697 * This default implementation performs the comparison defined above. 698 * 699 * @param other the other date to compare to, not null 700 * @return the comparator value, negative if less, positive if greater 701 */ 702 @Override compareTo(ChronoLocalDate other)703 default int compareTo(ChronoLocalDate other) { 704 int cmp = Long.compare(toEpochDay(), other.toEpochDay()); 705 if (cmp == 0) { 706 cmp = getChronology().compareTo(other.getChronology()); 707 } 708 return cmp; 709 } 710 711 /** 712 * Checks if this date is after the specified date ignoring the chronology. 713 * <p> 714 * This method differs from the comparison in {@link #compareTo} in that it 715 * only compares the underlying date and not the chronology. 716 * This allows dates in different calendar systems to be compared based 717 * on the time-line position. 718 * This is equivalent to using {@code date1.toEpochDay() > date2.toEpochDay()}. 719 * <p> 720 * This default implementation performs the comparison based on the epoch-day. 721 * 722 * @param other the other date to compare to, not null 723 * @return true if this is after the specified date 724 */ isAfter(ChronoLocalDate other)725 default boolean isAfter(ChronoLocalDate other) { 726 return this.toEpochDay() > other.toEpochDay(); 727 } 728 729 /** 730 * Checks if this date is before the specified date ignoring the chronology. 731 * <p> 732 * This method differs from the comparison in {@link #compareTo} in that it 733 * only compares the underlying date and not the chronology. 734 * This allows dates in different calendar systems to be compared based 735 * on the time-line position. 736 * This is equivalent to using {@code date1.toEpochDay() < date2.toEpochDay()}. 737 * <p> 738 * This default implementation performs the comparison based on the epoch-day. 739 * 740 * @param other the other date to compare to, not null 741 * @return true if this is before the specified date 742 */ isBefore(ChronoLocalDate other)743 default boolean isBefore(ChronoLocalDate other) { 744 return this.toEpochDay() < other.toEpochDay(); 745 } 746 747 /** 748 * Checks if this date is equal to the specified date ignoring the chronology. 749 * <p> 750 * This method differs from the comparison in {@link #compareTo} in that it 751 * only compares the underlying date and not the chronology. 752 * This allows dates in different calendar systems to be compared based 753 * on the time-line position. 754 * This is equivalent to using {@code date1.toEpochDay() == date2.toEpochDay()}. 755 * <p> 756 * This default implementation performs the comparison based on the epoch-day. 757 * 758 * @param other the other date to compare to, not null 759 * @return true if the underlying date is equal to the specified date 760 */ isEqual(ChronoLocalDate other)761 default boolean isEqual(ChronoLocalDate other) { 762 return this.toEpochDay() == other.toEpochDay(); 763 } 764 765 //----------------------------------------------------------------------- 766 /** 767 * Checks if this date is equal to another date, including the chronology. 768 * <p> 769 * Compares this date with another ensuring that the date and chronology are the same. 770 * <p> 771 * To compare the dates of two {@code TemporalAccessor} instances, including dates 772 * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator. 773 * 774 * @param obj the object to check, null returns false 775 * @return true if this is equal to the other date 776 */ 777 @Override equals(Object obj)778 boolean equals(Object obj); 779 780 /** 781 * A hash code for this date. 782 * 783 * @return a suitable hash code 784 */ 785 @Override hashCode()786 int hashCode(); 787 788 //----------------------------------------------------------------------- 789 /** 790 * Outputs this date as a {@code String}. 791 * <p> 792 * The output will include the full local date. 793 * 794 * @return the formatted date, not null 795 */ 796 @Override toString()797 String toString(); 798 799 } 800