83 import java.time.chrono.ChronoLocalDate;
84 import java.time.chrono.IsoEra;
85 import java.time.chrono.IsoChronology;
86 import java.time.format.DateTimeFormatter;
87 import java.time.format.DateTimeParseException;
88 import java.time.temporal.ChronoField;
89 import java.time.temporal.ChronoUnit;
90 import java.time.temporal.Temporal;
91 import java.time.temporal.TemporalAccessor;
92 import java.time.temporal.TemporalAdjuster;
93 import java.time.temporal.TemporalAmount;
94 import java.time.temporal.TemporalField;
95 import java.time.temporal.TemporalQueries;
96 import java.time.temporal.TemporalQuery;
97 import java.time.temporal.TemporalUnit;
98 import java.time.temporal.UnsupportedTemporalTypeException;
99 import java.time.temporal.ValueRange;
100 import java.time.zone.ZoneOffsetTransition;
101 import java.time.zone.ZoneRules;
102 import java.util.Objects;
103
104 /**
105 * A date without a time-zone in the ISO-8601 calendar system,
106 * such as {@code 2007-12-03}.
107 * <p>
108 * {@code LocalDate} is an immutable date-time object that represents a date,
109 * often viewed as year-month-day. Other date fields, such as day-of-year,
110 * day-of-week and week-of-year, can also be accessed.
111 * For example, the value "2nd October 2007" can be stored in a {@code LocalDate}.
112 * <p>
113 * This class does not store or represent a time or time-zone.
114 * Instead, it is a description of the date, as used for birthdays.
115 * It cannot represent an instant on the time-line without additional information
116 * such as an offset or time-zone.
117 * <p>
118 * The ISO-8601 calendar system is the modern civil calendar system used today
119 * in most of the world. It is equivalent to the proleptic Gregorian calendar
120 * system, in which today's rules for leap years are applied for all time.
121 * For most applications written today, the ISO-8601 rules are entirely suitable.
122 * However, any application that makes use of historical dates, and requires them
1679 *
1680 * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null
1681 * @return the period between this date and the end date, not null
1682 */
1683 @Override
1684 public Period until(ChronoLocalDate endDateExclusive) {
1685 LocalDate end = LocalDate.from(endDateExclusive);
1686 long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe
1687 int days = end.day - this.day;
1688 if (totalMonths > 0 && days < 0) {
1689 totalMonths--;
1690 LocalDate calcDate = this.plusMonths(totalMonths);
1691 days = (int) (end.toEpochDay() - calcDate.toEpochDay()); // safe
1692 } else if (totalMonths < 0 && days > 0) {
1693 totalMonths++;
1694 days -= end.lengthOfMonth();
1695 }
1696 long years = totalMonths / 12; // safe
1697 int months = (int) (totalMonths % 12); // safe
1698 return Period.of(Math.toIntExact(years), months, days);
1699 }
1700
1701 /**
1702 * Formats this date using the specified formatter.
1703 * <p>
1704 * This date will be passed to the formatter to produce a string.
1705 *
1706 * @param formatter the formatter to use, not null
1707 * @return the formatted date string, not null
1708 * @throws DateTimeException if an error occurs during printing
1709 */
1710 @Override // override for Javadoc and performance
1711 public String format(DateTimeFormatter formatter) {
1712 Objects.requireNonNull(formatter, "formatter");
1713 return formatter.format(this);
1714 }
1715
1716 //-----------------------------------------------------------------------
1717 /**
1718 * Combines this date with a time to create a {@code LocalDateTime}.
|
83 import java.time.chrono.ChronoLocalDate;
84 import java.time.chrono.IsoEra;
85 import java.time.chrono.IsoChronology;
86 import java.time.format.DateTimeFormatter;
87 import java.time.format.DateTimeParseException;
88 import java.time.temporal.ChronoField;
89 import java.time.temporal.ChronoUnit;
90 import java.time.temporal.Temporal;
91 import java.time.temporal.TemporalAccessor;
92 import java.time.temporal.TemporalAdjuster;
93 import java.time.temporal.TemporalAmount;
94 import java.time.temporal.TemporalField;
95 import java.time.temporal.TemporalQueries;
96 import java.time.temporal.TemporalQuery;
97 import java.time.temporal.TemporalUnit;
98 import java.time.temporal.UnsupportedTemporalTypeException;
99 import java.time.temporal.ValueRange;
100 import java.time.zone.ZoneOffsetTransition;
101 import java.time.zone.ZoneRules;
102 import java.util.Objects;
103 import java.util.stream.LongStream;
104 import java.util.stream.Stream;
105
106 /**
107 * A date without a time-zone in the ISO-8601 calendar system,
108 * such as {@code 2007-12-03}.
109 * <p>
110 * {@code LocalDate} is an immutable date-time object that represents a date,
111 * often viewed as year-month-day. Other date fields, such as day-of-year,
112 * day-of-week and week-of-year, can also be accessed.
113 * For example, the value "2nd October 2007" can be stored in a {@code LocalDate}.
114 * <p>
115 * This class does not store or represent a time or time-zone.
116 * Instead, it is a description of the date, as used for birthdays.
117 * It cannot represent an instant on the time-line without additional information
118 * such as an offset or time-zone.
119 * <p>
120 * The ISO-8601 calendar system is the modern civil calendar system used today
121 * in most of the world. It is equivalent to the proleptic Gregorian calendar
122 * system, in which today's rules for leap years are applied for all time.
123 * For most applications written today, the ISO-8601 rules are entirely suitable.
124 * However, any application that makes use of historical dates, and requires them
1681 *
1682 * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null
1683 * @return the period between this date and the end date, not null
1684 */
1685 @Override
1686 public Period until(ChronoLocalDate endDateExclusive) {
1687 LocalDate end = LocalDate.from(endDateExclusive);
1688 long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe
1689 int days = end.day - this.day;
1690 if (totalMonths > 0 && days < 0) {
1691 totalMonths--;
1692 LocalDate calcDate = this.plusMonths(totalMonths);
1693 days = (int) (end.toEpochDay() - calcDate.toEpochDay()); // safe
1694 } else if (totalMonths < 0 && days > 0) {
1695 totalMonths++;
1696 days -= end.lengthOfMonth();
1697 }
1698 long years = totalMonths / 12; // safe
1699 int months = (int) (totalMonths % 12); // safe
1700 return Period.of(Math.toIntExact(years), months, days);
1701 }
1702
1703 /**
1704 * Returns a sequential ordered {@link Stream} containing all the
1705 * {@code LocalDate} values starting from this (inclusive) to
1706 * {@code endExclusive} (exclusive) by an incremental step of 1 day.
1707 * <p>
1708 * This method is equivalent to {@code datesUntil(endExclusive, Period.ofDays(1))}.
1709 * <p>
1710 * The resulting stream will be empty if the end date is equal to or before the start.
1711 *
1712 * @param endExclusive the end date, exclusive, not null
1713 * @return a sequential {@code Stream} for the range of {@code LocalDate}
1714 * values
1715 * @since 9
1716 */
1717 public Stream<LocalDate> datesUntil(LocalDate endExclusive) {
1718 return LongStream.range(0, daysUntil(endExclusive)).mapToObj(this::plusDays);
1719 }
1720
1721 /**
1722 * Returns a sequential ordered {@link Stream} containing the
1723 * {@code LocalDate} values starting from this (inclusive) to
1724 * {@code endExclusive} (exclusive) by the supplied incremental {@code step}.
1725 * <p>
1726 * The resulting stream will be empty if the end date is equal to or before the start.
1727 *
1728 * @param endExclusive the end date, exclusive, not null
1729 * @param step the non-zero, non-negative {@code Period} which represents
1730 * the step.
1731 * @return a sequential {@code Stream} for the range of {@code LocalDate}
1732 * values
1733 * @throws IllegalArgumentException if step is zero or is negative
1734 * @since 9
1735 */
1736 public Stream<LocalDate> datesUntil(LocalDate endExclusive, Period step) {
1737 if (step.isZero() || step.isNegative())
1738 throw new IllegalArgumentException("step must be positive");
1739 long until = daysUntil(endExclusive);
1740 if (until <= 0)
1741 return Stream.empty();
1742 long months = step.toTotalMonths();
1743 long days = step.getDays();
1744 long steps;
1745 if (months != 0) {
1746 // 48699/1600 = 365.2425/12, no overflow
1747 steps = until * 1600 / (months * 48699 + days * 1600) + 1;
1748 long endDays = endExclusive.toEpochDay();
1749 long maxAddMonths = MAX.getProlepticMonth() - getProlepticMonth();
1750 long addMonths = months * steps;
1751 long addDays = days * steps;
1752 // adjust steps estimation
1753 if (addMonths > maxAddMonths
1754 || plusMonths(addMonths).toEpochDay() + addDays >= endDays) {
1755 steps--;
1756 addMonths -= months;
1757 addDays -= days;
1758 if (addMonths > maxAddMonths
1759 || plusMonths(addMonths).toEpochDay() + addDays >= endDays) {
1760 steps--;
1761 }
1762 }
1763 } else {
1764 steps = (until - 1) / days;
1765 }
1766 return LongStream.rangeClosed(0, steps).mapToObj(
1767 n -> this.plusMonths(months * n).plusDays(days * n));
1768 }
1769
1770 /**
1771 * Formats this date using the specified formatter.
1772 * <p>
1773 * This date will be passed to the formatter to produce a string.
1774 *
1775 * @param formatter the formatter to use, not null
1776 * @return the formatted date string, not null
1777 * @throws DateTimeException if an error occurs during printing
1778 */
1779 @Override // override for Javadoc and performance
1780 public String format(DateTimeFormatter formatter) {
1781 Objects.requireNonNull(formatter, "formatter");
1782 return formatter.format(this);
1783 }
1784
1785 //-----------------------------------------------------------------------
1786 /**
1787 * Combines this date with a time to create a {@code LocalDateTime}.
|