src/share/classes/java/time/chrono/ChronoDateImpl.java
Print this page
*** 57,79 ****
package java.time.chrono;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.ERA;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
import java.io.Serializable;
import java.time.DateTimeException;
- import java.time.LocalDate;
- import java.time.LocalTime;
- import java.time.chrono.Chronology;
- import java.time.chrono.ChronoLocalDate;
- import java.time.chrono.ChronoLocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalUnit;
/**
* A date expressed in terms of a standard year-month-day calendar system.
* <p>
* This class is used by applications seeking to handle dates in non-ISO calendar systems.
--- 57,78 ----
package java.time.chrono;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.ERA;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+ import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
import java.io.Serializable;
import java.time.DateTimeException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalUnit;
+ import java.time.temporal.UnsupportedTemporalTypeException;
+ import java.time.temporal.ValueRange;
+ import java.util.Objects;
/**
* A date expressed in terms of a standard year-month-day calendar system.
* <p>
* This class is used by applications seeking to handle dates in non-ISO calendar systems.
*** 95,122 ****
* <pre>
* System.out.printf("Example()%n");
* // Enumerate the list of available calendars and print today for each
* Set<Chronology> chronos = Chronology.getAvailableChronologies();
* for (Chronology chrono : chronos) {
! * ChronoLocalDate<?> date = chrono.dateNow();
* System.out.printf(" %20s: %s%n", chrono.getID(), date.toString());
* }
*
* // Print the Hijrah date and calendar
! * ChronoLocalDate<?> date = Chronology.of("Hijrah").dateNow();
* int day = date.get(ChronoField.DAY_OF_MONTH);
* int dow = date.get(ChronoField.DAY_OF_WEEK);
* int month = date.get(ChronoField.MONTH_OF_YEAR);
* int year = date.get(ChronoField.YEAR);
* System.out.printf(" Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
* dow, day, month, year);
* // Print today's date and the last day of the year
! * ChronoLocalDate<?> now1 = Chronology.of("Hijrah").dateNow();
! * ChronoLocalDate<?> first = now1.with(ChronoField.DAY_OF_MONTH, 1)
* .with(ChronoField.MONTH_OF_YEAR, 1);
! * ChronoLocalDate<?> last = first.plus(1, ChronoUnit.YEARS)
* .minus(1, ChronoUnit.DAYS);
* System.out.printf(" Today is %s: start: %s; end: %s%n", last.getChronology().getID(),
* first, last);
* </pre>
*
--- 94,121 ----
* <pre>
* System.out.printf("Example()%n");
* // Enumerate the list of available calendars and print today for each
* Set<Chronology> chronos = Chronology.getAvailableChronologies();
* for (Chronology chrono : chronos) {
! * ChronoLocalDate<?> date = chrono.dateNow();
* System.out.printf(" %20s: %s%n", chrono.getID(), date.toString());
* }
*
* // Print the Hijrah date and calendar
! * ChronoLocalDate<?> date = Chronology.of("Hijrah").dateNow();
* int day = date.get(ChronoField.DAY_OF_MONTH);
* int dow = date.get(ChronoField.DAY_OF_WEEK);
* int month = date.get(ChronoField.MONTH_OF_YEAR);
* int year = date.get(ChronoField.YEAR);
* System.out.printf(" Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
* dow, day, month, year);
* // Print today's date and the last day of the year
! * ChronoLocalDate<?> now1 = Chronology.of("Hijrah").dateNow();
! * ChronoLocalDate<?> first = now1.with(ChronoField.DAY_OF_MONTH, 1)
* .with(ChronoField.MONTH_OF_YEAR, 1);
! * ChronoLocalDate<?> last = first.plus(1, ChronoUnit.YEARS)
* .minus(1, ChronoUnit.DAYS);
* System.out.printf(" Today is %s: start: %s; end: %s%n", last.getChronology().getID(),
* first, last);
* </pre>
*
*** 166,176 ****
case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
}
! throw new DateTimeException("Unsupported unit: " + unit.getName());
}
return ChronoLocalDate.super.plus(amountToAdd, unit);
}
//-----------------------------------------------------------------------
--- 165,175 ----
case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
}
! throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
}
return ChronoLocalDate.super.plus(amountToAdd, unit);
}
//-----------------------------------------------------------------------
*** 321,343 ****
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
if (endDateTime instanceof ChronoLocalDate == false) {
throw new DateTimeException("Unable to calculate period between objects of two different types");
}
ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime;
if (getChronology().equals(end.getChronology()) == false) {
throw new DateTimeException("Unable to calculate period between two different chronologies");
}
if (unit instanceof ChronoUnit) {
! return LocalDate.from(this).periodUntil(end, unit); // TODO: this is wrong
}
return unit.between(this, endDateTime);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
--- 320,368 ----
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
+ Objects.requireNonNull(endDateTime, "endDateTime");
+ Objects.requireNonNull(unit, "unit");
if (endDateTime instanceof ChronoLocalDate == false) {
throw new DateTimeException("Unable to calculate period between objects of two different types");
}
ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime;
if (getChronology().equals(end.getChronology()) == false) {
throw new DateTimeException("Unable to calculate period between two different chronologies");
}
if (unit instanceof ChronoUnit) {
! switch ((ChronoUnit) unit) {
! case DAYS: return daysUntil(end);
! case WEEKS: return daysUntil(end) / 7;
! case MONTHS: return monthsUntil(end);
! case YEARS: return monthsUntil(end) / 12;
! case DECADES: return monthsUntil(end) / 120;
! case CENTURIES: return monthsUntil(end) / 1200;
! case MILLENNIA: return monthsUntil(end) / 12000;
! case ERAS: return end.getLong(ERA) - getLong(ERA);
! }
! throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
}
return unit.between(this, endDateTime);
}
+ private long daysUntil(ChronoLocalDate<?> end) {
+ return end.toEpochDay() - toEpochDay(); // no overflow
+ }
+
+ private long monthsUntil(ChronoLocalDate<?> end) {
+ ValueRange range = getChronology().range(MONTH_OF_YEAR);
+ if (range.getMaximum() != 12) {
+ throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year");
+ }
+ long packed1 = getLong(PROLEPTIC_MONTH) * 32L + get(DAY_OF_MONTH); // no overflow
+ long packed2 = end.getLong(PROLEPTIC_MONTH) * 32L + end.get(DAY_OF_MONTH); // no overflow
+ return (packed2 - packed1) / 32;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}