changeset 19030 | 32f129cb6351 |
parent 17474 | 8c100beabcc0 |
child 20518 | dde564773845 |
19029:30c64a024c86 | 19030:32f129cb6351 |
---|---|
240 * Subclasses should be Serializable wherever possible. |
240 * Subclasses should be Serializable wherever possible. |
241 * <p> |
241 * <p> |
242 * Additional calendar systems may be added to the system. |
242 * Additional calendar systems may be added to the system. |
243 * See {@link Chronology} for more details. |
243 * See {@link Chronology} for more details. |
244 * |
244 * |
245 * @param <D> the concrete type for the date |
|
246 * @since 1.8 |
245 * @since 1.8 |
247 */ |
246 */ |
248 public interface ChronoLocalDate<D extends ChronoLocalDate<D>> |
247 public interface ChronoLocalDate |
249 extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> { |
248 extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> { |
250 |
249 |
251 /** |
250 /** |
252 * Gets a comparator that compares {@code ChronoLocalDate} in |
251 * Gets a comparator that compares {@code ChronoLocalDate} in |
253 * time-line order ignoring the chronology. |
252 * time-line order ignoring the chronology. |
254 * <p> |
253 * <p> |
261 * |
260 * |
262 * @see #isAfter |
261 * @see #isAfter |
263 * @see #isBefore |
262 * @see #isBefore |
264 * @see #isEqual |
263 * @see #isEqual |
265 */ |
264 */ |
266 static Comparator<ChronoLocalDate<?>> timeLineOrder() { |
265 static Comparator<ChronoLocalDate> timeLineOrder() { |
267 return Chronology.DATE_ORDER; |
266 return Chronology.DATE_ORDER; |
268 } |
267 } |
269 |
268 |
270 //----------------------------------------------------------------------- |
269 //----------------------------------------------------------------------- |
271 /** |
270 /** |
287 * @param temporal the temporal object to convert, not null |
286 * @param temporal the temporal object to convert, not null |
288 * @return the date, not null |
287 * @return the date, not null |
289 * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate} |
288 * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate} |
290 * @see Chronology#date(TemporalAccessor) |
289 * @see Chronology#date(TemporalAccessor) |
291 */ |
290 */ |
292 static ChronoLocalDate<?> from(TemporalAccessor temporal) { |
291 static ChronoLocalDate from(TemporalAccessor temporal) { |
293 if (temporal instanceof ChronoLocalDate) { |
292 if (temporal instanceof ChronoLocalDate) { |
294 return (ChronoLocalDate<?>) temporal; |
293 return (ChronoLocalDate) temporal; |
295 } |
294 } |
296 Chronology chrono = temporal.query(TemporalQuery.chronology()); |
295 Chronology chrono = temporal.query(TemporalQuery.chronology()); |
297 if (chrono == null) { |
296 if (chrono == null) { |
298 throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass()); |
297 throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass()); |
299 } |
298 } |
365 */ |
364 */ |
366 default int lengthOfYear() { |
365 default int lengthOfYear() { |
367 return (isLeapYear() ? 366 : 365); |
366 return (isLeapYear() ? 366 : 365); |
368 } |
367 } |
369 |
368 |
369 /** |
|
370 * Checks if the specified field is supported. |
|
371 * <p> |
|
372 * This checks if the specified field can be queried on this date. |
|
373 * If false, then calling the {@link #range(TemporalField) range}, |
|
374 * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} |
|
375 * methods will throw an exception. |
|
376 * <p> |
|
377 * The set of supported fields is defined by the chronology and normally includes |
|
378 * all {@code ChronoField} date fields. |
|
379 * <p> |
|
380 * If the field is not a {@code ChronoField}, then the result of this method |
|
381 * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} |
|
382 * passing {@code this} as the argument. |
|
383 * Whether the field is supported is determined by the field. |
|
384 * |
|
385 * @param field the field to check, null returns false |
|
386 * @return true if the field can be queried, false if not |
|
387 */ |
|
370 @Override |
388 @Override |
371 default boolean isSupported(TemporalField field) { |
389 default boolean isSupported(TemporalField field) { |
372 if (field instanceof ChronoField) { |
390 if (field instanceof ChronoField) { |
373 return field.isDateBased(); |
391 return field.isDateBased(); |
374 } |
392 } |
375 return field != null && field.isSupportedBy(this); |
393 return field != null && field.isSupportedBy(this); |
376 } |
394 } |
377 |
395 |
396 /** |
|
397 * Checks if the specified unit is supported. |
|
398 * <p> |
|
399 * This checks if the specified unit can be added to or subtracted from this date. |
|
400 * If false, then calling the {@link #plus(long, TemporalUnit)} and |
|
401 * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. |
|
402 * <p> |
|
403 * The set of supported units is defined by the chronology and normally includes |
|
404 * all {@code ChronoUnit} date units except {@code FOREVER}. |
|
405 * <p> |
|
406 * If the unit is not a {@code ChronoUnit}, then the result of this method |
|
407 * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} |
|
408 * passing {@code this} as the argument. |
|
409 * Whether the unit is supported is determined by the unit. |
|
410 * |
|
411 * @param unit the unit to check, null returns false |
|
412 * @return true if the unit can be added/subtracted, false if not |
|
413 */ |
|
414 @Override |
|
415 default boolean isSupported(TemporalUnit unit) { |
|
416 if (unit instanceof ChronoUnit) { |
|
417 return unit.isDateBased(); |
|
418 } |
|
419 return unit != null && unit.isSupportedBy(this); |
|
420 } |
|
421 |
|
378 //----------------------------------------------------------------------- |
422 //----------------------------------------------------------------------- |
379 // override for covariant return type |
423 // override for covariant return type |
380 /** |
424 /** |
381 * {@inheritDoc} |
425 * {@inheritDoc} |
382 * @throws DateTimeException {@inheritDoc} |
426 * @throws DateTimeException {@inheritDoc} |
383 * @throws ArithmeticException {@inheritDoc} |
427 * @throws ArithmeticException {@inheritDoc} |
384 */ |
428 */ |
385 @Override |
429 @Override |
386 default D with(TemporalAdjuster adjuster) { |
430 default ChronoLocalDate with(TemporalAdjuster adjuster) { |
387 return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster)); |
431 return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); |
388 } |
432 } |
389 |
433 |
390 /** |
434 /** |
391 * {@inheritDoc} |
435 * {@inheritDoc} |
392 * @throws DateTimeException {@inheritDoc} |
436 * @throws DateTimeException {@inheritDoc} |
393 * @throws UnsupportedTemporalTypeException {@inheritDoc} |
437 * @throws UnsupportedTemporalTypeException {@inheritDoc} |
394 * @throws ArithmeticException {@inheritDoc} |
438 * @throws ArithmeticException {@inheritDoc} |
395 */ |
439 */ |
396 @Override |
440 @Override |
397 default D with(TemporalField field, long newValue) { |
441 default ChronoLocalDate with(TemporalField field, long newValue) { |
398 if (field instanceof ChronoField) { |
442 if (field instanceof ChronoField) { |
399 throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); |
443 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); |
400 } |
444 } |
401 return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue)); |
445 return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); |
402 } |
446 } |
403 |
447 |
404 /** |
448 /** |
405 * {@inheritDoc} |
449 * {@inheritDoc} |
406 * @throws DateTimeException {@inheritDoc} |
450 * @throws DateTimeException {@inheritDoc} |
407 * @throws ArithmeticException {@inheritDoc} |
451 * @throws ArithmeticException {@inheritDoc} |
408 */ |
452 */ |
409 @Override |
453 @Override |
410 default D plus(TemporalAmount amount) { |
454 default ChronoLocalDate plus(TemporalAmount amount) { |
411 return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount)); |
455 return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); |
412 } |
456 } |
413 |
457 |
414 /** |
458 /** |
415 * {@inheritDoc} |
459 * {@inheritDoc} |
416 * @throws DateTimeException {@inheritDoc} |
460 * @throws DateTimeException {@inheritDoc} |
417 * @throws ArithmeticException {@inheritDoc} |
461 * @throws ArithmeticException {@inheritDoc} |
418 */ |
462 */ |
419 @Override |
463 @Override |
420 default D plus(long amountToAdd, TemporalUnit unit) { |
464 default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) { |
421 if (unit instanceof ChronoUnit) { |
465 if (unit instanceof ChronoUnit) { |
422 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); |
466 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); |
423 } |
467 } |
424 return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd)); |
468 return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); |
425 } |
469 } |
426 |
470 |
427 /** |
471 /** |
428 * {@inheritDoc} |
472 * {@inheritDoc} |
429 * @throws DateTimeException {@inheritDoc} |
473 * @throws DateTimeException {@inheritDoc} |
430 * @throws ArithmeticException {@inheritDoc} |
474 * @throws ArithmeticException {@inheritDoc} |
431 */ |
475 */ |
432 @Override |
476 @Override |
433 default D minus(TemporalAmount amount) { |
477 default ChronoLocalDate minus(TemporalAmount amount) { |
434 return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount)); |
478 return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); |
435 } |
479 } |
436 |
480 |
437 /** |
481 /** |
438 * {@inheritDoc} |
482 * {@inheritDoc} |
439 * @throws DateTimeException {@inheritDoc} |
483 * @throws DateTimeException {@inheritDoc} |
440 * @throws UnsupportedTemporalTypeException {@inheritDoc} |
484 * @throws UnsupportedTemporalTypeException {@inheritDoc} |
441 * @throws ArithmeticException {@inheritDoc} |
485 * @throws ArithmeticException {@inheritDoc} |
442 */ |
486 */ |
443 @Override |
487 @Override |
444 default D minus(long amountToSubtract, TemporalUnit unit) { |
488 default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { |
445 return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit)); |
489 return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); |
446 } |
490 } |
447 |
491 |
448 //----------------------------------------------------------------------- |
492 //----------------------------------------------------------------------- |
449 /** |
493 /** |
450 * Queries this date using the specified query. |
494 * Queries this date using the specified query. |
520 * The {@code Temporal} passed to this method must be a |
564 * The {@code Temporal} passed to this method must be a |
521 * {@code ChronoLocalDate} in the same chronology. |
565 * {@code ChronoLocalDate} in the same chronology. |
522 * The calculation returns a whole number, representing the number of |
566 * The calculation returns a whole number, representing the number of |
523 * complete units between the two dates. |
567 * complete units between the two dates. |
524 * For example, the amount in days between two dates can be calculated |
568 * For example, the amount in days between two dates can be calculated |
525 * using {@code startDate.periodUntil(endDate, DAYS)}. |
569 * using {@code startDate.until(endDate, DAYS)}. |
526 * <p> |
570 * <p> |
527 * There are two equivalent ways of using this method. |
571 * There are two equivalent ways of using this method. |
528 * The first is to invoke this method. |
572 * The first is to invoke this method. |
529 * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: |
573 * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: |
530 * <pre> |
574 * <pre> |
531 * // these two lines are equivalent |
575 * // these two lines are equivalent |
532 * amount = start.periodUntil(end, MONTHS); |
576 * amount = start.until(end, MONTHS); |
533 * amount = MONTHS.between(start, end); |
577 * amount = MONTHS.between(start, end); |
534 * </pre> |
578 * </pre> |
535 * The choice should be made based on which makes the code more readable. |
579 * The choice should be made based on which makes the code more readable. |
536 * <p> |
580 * <p> |
537 * The calculation is implemented in this method for {@link ChronoUnit}. |
581 * The calculation is implemented in this method for {@link ChronoUnit}. |
553 * @return the amount of time between this date and the end date |
597 * @return the amount of time between this date and the end date |
554 * @throws DateTimeException if the amount cannot be calculated |
598 * @throws DateTimeException if the amount cannot be calculated |
555 * @throws ArithmeticException if numeric overflow occurs |
599 * @throws ArithmeticException if numeric overflow occurs |
556 */ |
600 */ |
557 @Override // override for Javadoc |
601 @Override // override for Javadoc |
558 long periodUntil(Temporal endDate, TemporalUnit unit); |
602 long until(Temporal endDate, TemporalUnit unit); |
559 |
603 |
560 /** |
604 /** |
561 * Calculates the period between this date and another date as a {@code Period}. |
605 * Calculates the period between this date and another date as a {@code Period}. |
562 * <p> |
606 * <p> |
563 * This calculates the period between two dates in terms of years, months and days. |
607 * This calculates the period between two dates in terms of years, months and days. |
573 * @param endDate the end date, exclusive, which may be in any chronology, not null |
617 * @param endDate the end date, exclusive, which may be in any chronology, not null |
574 * @return the period between this date and the end date, not null |
618 * @return the period between this date and the end date, not null |
575 * @throws DateTimeException if the period cannot be calculated |
619 * @throws DateTimeException if the period cannot be calculated |
576 * @throws ArithmeticException if numeric overflow occurs |
620 * @throws ArithmeticException if numeric overflow occurs |
577 */ |
621 */ |
578 Period periodUntil(ChronoLocalDate<?> endDate); |
622 Period until(ChronoLocalDate endDate); |
579 |
623 |
580 /** |
624 /** |
581 * Formats this date using the specified formatter. |
625 * Formats this date using the specified formatter. |
582 * <p> |
626 * <p> |
583 * This date will be passed to the formatter to produce a string. |
627 * This date will be passed to the formatter to produce a string. |
604 * All possible combinations of date and time are valid. |
648 * All possible combinations of date and time are valid. |
605 * |
649 * |
606 * @param localTime the local time to use, not null |
650 * @param localTime the local time to use, not null |
607 * @return the local date-time formed from this date and the specified time, not null |
651 * @return the local date-time formed from this date and the specified time, not null |
608 */ |
652 */ |
609 default ChronoLocalDateTime<D> atTime(LocalTime localTime) { |
653 @SuppressWarnings("unchecked") |
610 return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime); |
654 default ChronoLocalDateTime<?> atTime(LocalTime localTime) { |
655 return ChronoLocalDateTimeImpl.of(this, localTime); |
|
611 } |
656 } |
612 |
657 |
613 //----------------------------------------------------------------------- |
658 //----------------------------------------------------------------------- |
614 /** |
659 /** |
615 * Converts this date to the Epoch Day. |
660 * Converts this date to the Epoch Day. |
654 * |
699 * |
655 * @param other the other date to compare to, not null |
700 * @param other the other date to compare to, not null |
656 * @return the comparator value, negative if less, positive if greater |
701 * @return the comparator value, negative if less, positive if greater |
657 */ |
702 */ |
658 @Override |
703 @Override |
659 default int compareTo(ChronoLocalDate<?> other) { |
704 default int compareTo(ChronoLocalDate other) { |
660 int cmp = Long.compare(toEpochDay(), other.toEpochDay()); |
705 int cmp = Long.compare(toEpochDay(), other.toEpochDay()); |
661 if (cmp == 0) { |
706 if (cmp == 0) { |
662 cmp = getChronology().compareTo(other.getChronology()); |
707 cmp = getChronology().compareTo(other.getChronology()); |
663 } |
708 } |
664 return cmp; |
709 return cmp; |
676 * This default implementation performs the comparison based on the epoch-day. |
721 * This default implementation performs the comparison based on the epoch-day. |
677 * |
722 * |
678 * @param other the other date to compare to, not null |
723 * @param other the other date to compare to, not null |
679 * @return true if this is after the specified date |
724 * @return true if this is after the specified date |
680 */ |
725 */ |
681 default boolean isAfter(ChronoLocalDate<?> other) { |
726 default boolean isAfter(ChronoLocalDate other) { |
682 return this.toEpochDay() > other.toEpochDay(); |
727 return this.toEpochDay() > other.toEpochDay(); |
683 } |
728 } |
684 |
729 |
685 /** |
730 /** |
686 * Checks if this date is before the specified date ignoring the chronology. |
731 * Checks if this date is before the specified date ignoring the chronology. |
694 * This default implementation performs the comparison based on the epoch-day. |
739 * This default implementation performs the comparison based on the epoch-day. |
695 * |
740 * |
696 * @param other the other date to compare to, not null |
741 * @param other the other date to compare to, not null |
697 * @return true if this is before the specified date |
742 * @return true if this is before the specified date |
698 */ |
743 */ |
699 default boolean isBefore(ChronoLocalDate<?> other) { |
744 default boolean isBefore(ChronoLocalDate other) { |
700 return this.toEpochDay() < other.toEpochDay(); |
745 return this.toEpochDay() < other.toEpochDay(); |
701 } |
746 } |
702 |
747 |
703 /** |
748 /** |
704 * Checks if this date is equal to the specified date ignoring the chronology. |
749 * Checks if this date is equal to the specified date ignoring the chronology. |
712 * This default implementation performs the comparison based on the epoch-day. |
757 * This default implementation performs the comparison based on the epoch-day. |
713 * |
758 * |
714 * @param other the other date to compare to, not null |
759 * @param other the other date to compare to, not null |
715 * @return true if the underlying date is equal to the specified date |
760 * @return true if the underlying date is equal to the specified date |
716 */ |
761 */ |
717 default boolean isEqual(ChronoLocalDate<?> other) { |
762 default boolean isEqual(ChronoLocalDate other) { |
718 return this.toEpochDay() == other.toEpochDay(); |
763 return this.toEpochDay() == other.toEpochDay(); |
719 } |
764 } |
720 |
765 |
721 //----------------------------------------------------------------------- |
766 //----------------------------------------------------------------------- |
722 /** |
767 /** |