< prev index next >

src/java.base/share/classes/java/time/LocalDate.java

Print this page




  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


1696      *
1697      * @param endDateExclusive  the end date, exclusive, which may be in any chronology, not null
1698      * @return the period between this date and the end date, not null
1699      */
1700     @Override
1701     public Period until(ChronoLocalDate endDateExclusive) {
1702         LocalDate end = LocalDate.from(endDateExclusive);
1703         long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
1704         int days = end.day - this.day;
1705         if (totalMonths > 0 && days < 0) {
1706             totalMonths--;
1707             LocalDate calcDate = this.plusMonths(totalMonths);
1708             days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
1709         } else if (totalMonths < 0 && days > 0) {
1710             totalMonths++;
1711             days -= end.lengthOfMonth();
1712         }
1713         long years = totalMonths / 12;  // safe
1714         int months = (int) (totalMonths % 12);  // safe
1715         return Period.of(Math.toIntExact(years), months, days);



















































































1716     }
1717 
1718     /**
1719      * Formats this date using the specified formatter.
1720      * <p>
1721      * This date will be passed to the formatter to produce a string.
1722      *
1723      * @param formatter  the formatter to use, not null
1724      * @return the formatted date string, not null
1725      * @throws DateTimeException if an error occurs during printing
1726      */
1727     @Override  // override for Javadoc and performance
1728     public String format(DateTimeFormatter formatter) {
1729         Objects.requireNonNull(formatter, "formatter");
1730         return formatter.format(this);
1731     }
1732 
1733     //-----------------------------------------------------------------------
1734     /**
1735      * 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


1698      *
1699      * @param endDateExclusive  the end date, exclusive, which may be in any chronology, not null
1700      * @return the period between this date and the end date, not null
1701      */
1702     @Override
1703     public Period until(ChronoLocalDate endDateExclusive) {
1704         LocalDate end = LocalDate.from(endDateExclusive);
1705         long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
1706         int days = end.day - this.day;
1707         if (totalMonths > 0 && days < 0) {
1708             totalMonths--;
1709             LocalDate calcDate = this.plusMonths(totalMonths);
1710             days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
1711         } else if (totalMonths < 0 && days > 0) {
1712             totalMonths++;
1713             days -= end.lengthOfMonth();
1714         }
1715         long years = totalMonths / 12;  // safe
1716         int months = (int) (totalMonths % 12);  // safe
1717         return Period.of(Math.toIntExact(years), months, days);
1718     }
1719     
1720     /**
1721      * Returns a sequential ordered stream of dates. The returned stream starts from this date
1722      * (inclusive) and goes to {@code endExclusive} (exclusive) by an incremental step of 1 day.
1723      * <p>
1724      * This method is equivalent to {@code datesUntil(endExclusive, Period.ofDays(1))}.
1725      *
1726      * @param endExclusive  the end date, exclusive, not null
1727      * @return a sequential {@code Stream} for the range of {@code LocalDate} values
1728      * @throws IllegalArgumentException if end date is before this date
1729      * @since 9
1730      */
1731     public Stream<LocalDate> datesUntil(LocalDate endExclusive) {
1732         long end = endExclusive.toEpochDay();
1733         long start = toEpochDay();
1734         if (end < start) {
1735             throw new IllegalArgumentException(endExclusive + " < " + this);
1736         }
1737         return LongStream.range(start, end).mapToObj(LocalDate::ofEpochDay);
1738     }
1739 
1740     /**
1741      * Returns a sequential ordered stream of dates by given incremental step. The returned stream
1742      * starts from this date (inclusive) and goes to {@code endExclusive} (exclusive).
1743      * <p>
1744      * The n-th date which appears in the stream is equal to {@code this.plus(step.multipliedBy(n))}
1745      * (but the result of step multiplication never overflows). For example, if this date is
1746      * {@code 2015-01-31}, the end date is {@code 2015-05-01} and the step is 1 month, then the
1747      * stream contains {@code 2015-01-31}, {@code 2015-02-28}, {@code 2015-03-31}, and
1748      * {@code 2015-04-30}.
1749      * 
1750      * @param endExclusive  the end date, exclusive, not null
1751      * @param step  the non-zero, non-negative {@code Period} which represents the step.
1752      * @return a sequential {@code Stream} for the range of {@code LocalDate} values
1753      * @throws IllegalArgumentException if step is zero, or {@code step.getDays()} and
1754      *             {@code step.toTotalMonths()} have opposite sign, or end date is before this date
1755      *             and step is positive, or end date is after this date and step is negative
1756      * @since 9
1757      */
1758     public Stream<LocalDate> datesUntil(LocalDate endExclusive, Period step) {
1759         if (step.isZero()) {
1760             throw new IllegalArgumentException("step is zero");
1761         }
1762         long end = endExclusive.toEpochDay();
1763         long start = toEpochDay();
1764         long until = end - start;
1765         long months = step.toTotalMonths();
1766         long days = step.getDays();
1767         if ((months < 0 && days > 0) || (months > 0 && days < 0)) {
1768             throw new IllegalArgumentException("period months and days are of opposite sign");
1769         }
1770         if (until == 0) {
1771             return Stream.empty();
1772         }
1773         int sign = months > 0 || days > 0 ? 1 : -1;
1774         if (sign < 0 ^ until < 0) {
1775             throw new IllegalArgumentException(endExclusive + (sign < 0 ? " > " : " < ") + this);
1776         }
1777         if (months == 0) {
1778             long steps = (until - sign) / days; // non-negative
1779             return LongStream.rangeClosed(0, steps).mapToObj(
1780                     n -> LocalDate.ofEpochDay(start + n * days));
1781         }
1782         // 48699/1600 = 365.2425/12, no overflow, non-negative result
1783         long steps = until * 1600 / (months * 48699 + days * 1600) + 1;
1784         long addMonths = months * steps;
1785         long addDays = days * steps;
1786         long maxAddMonths = months > 0 ? MAX.getProlepticMonth() - getProlepticMonth()
1787                 : getProlepticMonth() - MIN.getProlepticMonth();
1788         // adjust steps estimation
1789         if (addMonths * sign > maxAddMonths
1790                 || (plusMonths(addMonths).toEpochDay() + addDays) * sign >= end * sign) {
1791             steps--;
1792             addMonths -= months;
1793             addDays -= days;
1794             if (addMonths * sign > maxAddMonths
1795                     || (plusMonths(addMonths).toEpochDay() + addDays) * sign >= end * sign) {
1796                 steps--;
1797             }
1798         }
1799         return LongStream.rangeClosed(0, steps).mapToObj(
1800                 n -> this.plusMonths(months * n).plusDays(days * n));
1801     }
1802 
1803     /**
1804      * Formats this date using the specified formatter.
1805      * <p>
1806      * This date will be passed to the formatter to produce a string.
1807      *
1808      * @param formatter  the formatter to use, not null
1809      * @return the formatted date string, not null
1810      * @throws DateTimeException if an error occurs during printing
1811      */
1812     @Override  // override for Javadoc and performance
1813     public String format(DateTimeFormatter formatter) {
1814         Objects.requireNonNull(formatter, "formatter");
1815         return formatter.format(this);
1816     }
1817 
1818     //-----------------------------------------------------------------------
1819     /**
1820      * Combines this date with a time to create a {@code LocalDateTime}.


< prev index next >