/** * Adds this period to the specified date-time object. * <p> * This method is not intended to be called by application code directly. Applications should use the * {@code plus(PlusAdjuster)} method on the date-time object passing this period as the argument. * <p> * The calculation will add the years, then months, then days, then nanos. Only non-zero amounts will be * added. If the date-time has a calendar system with a fixed number of months in a year, then the years and * months will be combined before being added. * * @param dateTime the date-time object to adjust, not null * @return an object of the same type with the adjustment made, not null * @throws DateTimeException if unable to add * @throws ArithmeticException if numeric overflow occurs */ @Override public DateTime doPlusAdjustment(DateTime dateTime) { if ((this.years | this.months) != 0) { DateTimeValueRange startRange = Chrono.from(dateTime).range(MONTH_OF_YEAR); if (startRange.isFixed() && startRange.isIntValue()) { long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1; dateTime = dateTime.plus(this.years * monthCount + this.months, MONTHS); } else { if (this.years != 0) { dateTime = dateTime.plus(this.years, YEARS); } if (this.months != 0) { dateTime = dateTime.plus(this.months, MONTHS); } } } if (this.days != 0) { dateTime = dateTime.plus(this.days, DAYS); } if (this.nanos != 0) { dateTime = dateTime.plus(this.nanos, NANOS); } return dateTime; }
/** * Subtracts this period from the specified date-time object. * <p> * This method is not intended to be called by application code directly. Applications should use the * {@code minus(MinusAdjuster)} method on the date-time object passing this period as the argument. * <p> * The calculation will subtract the years, then months, then days, then nanos. Only non-zero amounts will * be subtracted. If the date-time has a calendar system with a fixed number of months in a year, then the * years and months will be combined before being subtracted. * * @param dateTime the date-time object to adjust, not null * @return an object of the same type with the adjustment made, not null * @throws DateTimeException if unable to subtract * @throws ArithmeticException if numeric overflow occurs */ @Override public DateTime doMinusAdjustment(DateTime dateTime) { if ((this.years | this.months) != 0) { DateTimeValueRange startRange = Chrono.from(dateTime).range(MONTH_OF_YEAR); if (startRange.isFixed() && startRange.isIntValue()) { long monthCount = startRange.getMaximum() - startRange.getMinimum() + 1; dateTime = dateTime.minus(this.years * monthCount + this.months, MONTHS); } else { if (this.years != 0) { dateTime = dateTime.minus(this.years, YEARS); } if (this.months != 0) { dateTime = dateTime.minus(this.months, MONTHS); } } } if (this.days != 0) { dateTime = dateTime.minus(this.days, DAYS); } if (this.nanos != 0) { dateTime = dateTime.minus(this.nanos, NANOS); } return dateTime; }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof ChronoZonedDateTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } @SuppressWarnings("unchecked") ChronoZonedDateTime<C> end = (ChronoZonedDateTime<C>) endDateTime; if (getDate().getChrono().equals(end.getDate().getChrono()) == false) { throw new DateTimeException("Unable to calculate period between two different chronologies"); } if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(this.offset); return this.dateTime.periodUntil(end.getDateTime(), unit); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof Year == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } Year end = (Year) endDateTime; if (unit instanceof ChronoUnit) { long yearsUntil = ((long) end.year) - this.year; // no overflow switch ((ChronoUnit) unit) { case YEARS: return yearsUntil; case DECADES: return yearsUntil / 10; case CENTURIES: return yearsUntil / 100; case MILLENNIA: return yearsUntil / 1000; case ERAS: return end.getLong(ERA) - getLong(ERA); } throw new DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badMinusAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoLocalDateTime cdt = chrono.date(refDate).atTime(LocalTime.NOON); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoLocalDateTime<?> cdt2 = chrono2.date(refDate).atTime(LocalTime.NOON); DateTime.MinusAdjuster adjuster = new FixedAdjuster(cdt2); if (chrono != chrono2) { try { ChronoLocalDateTime<?> notreached = cdt.minus(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException, " + "required: " + cdt + ", supplied: " + cdt2); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoLocalDateTime<?> result = cdt.minus(adjuster); assertEquals(result, cdt2, "WithAdjuster failed to replace date"); } } }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badMinusAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoLocalDate date = chrono.date(refDate); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoLocalDate<?> date2 = chrono2.date(refDate); DateTime.MinusAdjuster adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { ChronoLocalDate<?> notreached = date.minus(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException"); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoLocalDate<?> result = date.minus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badPlusAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoLocalDate date = chrono.date(refDate); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoLocalDate<?> date2 = chrono2.date(refDate); DateTime.PlusAdjuster adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { ChronoLocalDate<?> notreached = date.plus(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException"); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoLocalDate<?> result = date.plus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badWithAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoLocalDate date = chrono.date(refDate); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoLocalDate<?> date2 = chrono2.date(refDate); DateTime.WithAdjuster adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { ChronoLocalDate<?> notreached = date.with(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException"); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoLocalDate<?> result = date.with(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badPlusAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoZonedDateTime czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC); DateTime.PlusAdjuster adjuster = new FixedAdjuster(czdt2); if (chrono != chrono2) { try { ChronoZonedDateTime<?> notreached = czdt.plus(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException, " + "required: " + czdt + ", supplied: " + czdt2); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoZonedDateTime<?> result = czdt.plus(adjuster); assertEquals(result, czdt2, "WithAdjuster failed to replace date time"); } } }
@Test(groups = { "tck" }, dataProvider = "calendars") public void test_badMinusAdjusterChrono(Chrono chrono) { LocalDate refDate = LocalDate.of(1900, 1, 1); ChronoZonedDateTime czdt = chrono.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC); for (Chrono[] clist : data_of_calendars()) { Chrono chrono2 = clist[0]; ChronoZonedDateTime<?> czdt2 = chrono2.date(refDate).atTime(LocalTime.NOON).atZone(ZoneOffset.UTC); DateTime.MinusAdjuster adjuster = new FixedAdjuster(czdt2); if (chrono != chrono2) { try { ChronoZonedDateTime<?> notreached = czdt.minus(adjuster); Assert.fail("WithAdjuster should have thrown a ClassCastException, " + "required: " + czdt + ", supplied: " + czdt2); } catch (ClassCastException cce) { // Expected exception; not an error } } else { // Same chronology, ChronoZonedDateTime<?> result = czdt.minus(adjuster); assertEquals(result, czdt2, "WithAdjuster failed to replace date"); } } }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof OffsetTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } if (unit instanceof ChronoUnit) { OffsetTime end = (OffsetTime) endDateTime; long nanosUntil = end.toEpochNano() - toEpochNano(); // no overflow switch ((ChronoUnit) unit) { case NANOS: return nanosUntil; case MICROS: return nanosUntil / 1000; case MILLIS: return nanosUntil / 1000000; case SECONDS: return nanosUntil / NANOS_PER_SECOND; case MINUTES: return nanosUntil / NANOS_PER_MINUTE; case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } throw new DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof YearMonth == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } YearMonth end = (YearMonth) endDateTime; if (unit instanceof ChronoUnit) { long monthsUntil = end.getEpochMonth() - getEpochMonth(); // no overflow switch ((ChronoUnit) unit) { case MONTHS: return monthsUntil; case QUARTER_YEARS: return monthsUntil / 3; case HALF_YEARS: return monthsUntil / 6; case YEARS: return monthsUntil / 12; case DECADES: return monthsUntil / 120; case CENTURIES: return monthsUntil / 1200; case MILLENNIA: return monthsUntil / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } throw new DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof Instant == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } Instant end = (Instant) endDateTime; if (unit instanceof ChronoUnit) { ChronoUnit f = (ChronoUnit) unit; switch (f) { case NANOS: return nanosUntil(end); case MICROS: return nanosUntil(end) / 1000; case MILLIS: return Jdk8Methods.safeSubtract(end.toEpochMilli(), toEpochMilli()); case SECONDS: return secondsUntil(end); case MINUTES: return secondsUntil(end) / SECONDS_PER_MINUTE; case HOURS: return secondsUntil(end) / SECONDS_PER_HOUR; case HALF_DAYS: return secondsUntil(end) / (12 * SECONDS_PER_HOUR); case DAYS: return secondsUntil(end) / (SECONDS_PER_DAY); } throw new DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof OffsetDateTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } if (unit instanceof ChronoUnit) { OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(this.offset); return this.dateTime.periodUntil(end.dateTime, unit); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof LocalTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } LocalTime end = (LocalTime) endDateTime; if (unit instanceof ChronoUnit) { long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow switch ((ChronoUnit) unit) { case NANOS: return nanosUntil; case MICROS: return nanosUntil / 1000; case MILLIS: return nanosUntil / 1000000; case SECONDS: return nanosUntil / NANOS_PER_SECOND; case MINUTES: return nanosUntil / NANOS_PER_MINUTE; case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } throw new DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof LocalDate == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } LocalDate end = (LocalDate) endDateTime; if (unit instanceof ChronoUnit) { switch ((ChronoUnit) unit) { case DAYS: return daysUntil(end); case WEEKS: return daysUntil(end) / 7; case MONTHS: return monthsUntil(end); case QUARTER_YEARS: return monthsUntil(end) / 3; case HALF_YEARS: return monthsUntil(end) / 6; 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 DateTimeException("Unsupported unit: " + unit.getName()); } return unit.between(this, endDateTime).getAmount(); }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof ZonedDateTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } if (unit instanceof ChronoUnit) { ZonedDateTime end = (ZonedDateTime) endDateTime; end = end.withZoneSameInstant(this.offset); return this.dateTime.periodUntil(end.dateTime, unit); } return unit.between(this, endDateTime).getAmount(); }
/** * Returns a copy of this date-time with the new date and time, checking to see if a new object is in fact * required. * * @param newDate the date of the new date-time, not null * @param newTime the time of the new date-time, not null * @return the date-time, not null */ private ChronoDateTimeImpl<C> with(DateTime newDate, LocalTime newTime) { if (this.date == newDate && this.time == newTime) { return this; } // Validate that the new DateTime is a ChronoLocalDate (and not something else) ChronoLocalDate<C> cd = this.date.getChrono().ensureChronoLocalDate(newDate); return new ChronoDateTimeImpl<C>(cd, newTime); }
/** * Casts the {@code DateTime} to {@code ChronoLocalDate} with the same chronology. * * @param dateTime a date-time to cast, not null * @return the date-time checked and cast to {@code ChronoLocalDate}, not null * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate or the chronology is not * equal this Chrono */ public/* package-scoped */ChronoLocalDate<C> ensureChronoLocalDate(DateTime dateTime) { // TODO: non-public @SuppressWarnings("unchecked") ChronoLocalDate<C> other = (ChronoLocalDate<C>) dateTime; if (this.equals(other.getChrono()) == false) { throw new ClassCastException("Chrono mismatch, expected: " + getId() + ", actual: " + other.getChrono().getId()); } return other; }
/** * Casts the {@code DateTime} to {@code ChronoLocalDateTime} with the same chronology. * * @param dateTime a date-time to cast, not null * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null * @throws ClassCastException if the date-time cannot be cast to ChronoDateTimeImpl or the chronology is not * equal this Chrono */ public/* package-scoped */ChronoDateTimeImpl<C> ensureChronoLocalDateTime(DateTime dateTime) { // TODO: // non-public @SuppressWarnings("unchecked") ChronoDateTimeImpl<C> other = (ChronoDateTimeImpl<C>) dateTime; if (this.equals(other.getDate().getChrono()) == false) { throw new ClassCastException("Chrono mismatch, required: " + getId() + ", supplied: " + other.getDate().getChrono().getId()); } return other; }
/** * Casts the {@code DateTime} to {@code ChronoZonedDateTimeImpl} with the same chronology. * * @param dateTime a date-time to cast, not null * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl or the chronology * is not equal this Chrono */ public/* package-scoped */ChronoZonedDateTimeImpl<C> ensureChronoZonedDateTime(DateTime dateTime) { // TODO: // non-public @SuppressWarnings("unchecked") ChronoZonedDateTimeImpl<C> other = (ChronoZonedDateTimeImpl<C>) dateTime; if (this.equals(other.getDate().getChrono()) == false) { throw new ClassCastException("Chrono mismatch, required: " + getId() + ", supplied: " + other.getDate().getChrono().getId()); } return other; }
@Override public long periodUntil(DateTime endDateTime, PeriodUnit unit) { if (endDateTime instanceof OffsetDate == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } if (unit instanceof ChronoUnit) { OffsetDate end = (OffsetDate) endDateTime; long offsetDiff = end.offset.getTotalSeconds() - this.offset.getTotalSeconds(); LocalDate endLocal = end.date.plusDays(Jdk8Methods.floorDiv(-offsetDiff, SECONDS_PER_DAY)); return this.date.periodUntil(endLocal, unit); } return unit.between(this, endDateTime).getAmount(); }