src/share/classes/java/time/LocalTime.java
Print this page
@@ -74,27 +74,21 @@
import java.io.DataOutput;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
-import java.time.format.DateTimeBuilder;
import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatters;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoLocalDateTime;
import java.time.temporal.ChronoUnit;
-import java.time.temporal.ChronoZonedDateTime;
-import java.time.temporal.OffsetTime;
import java.time.temporal.Queries;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalAdder;
import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQuery;
-import java.time.temporal.TemporalSubtractor;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ValueRange;
import java.util.Objects;
/**
@@ -127,11 +121,11 @@
* The minimum supported {@code LocalTime}, '00:00'.
* This is the time of midnight at the start of the day.
*/
public static final LocalTime MIN;
/**
- * The minimum supported {@code LocalTime}, '23:59:59.999999999'.
+ * The maximum supported {@code LocalTime}, '23:59:59.999999999'.
* This is the time just before midnight at the end of the day.
*/
public static final LocalTime MAX;
/**
* The time of midnight at the start of the day, '00:00'.
@@ -271,25 +265,21 @@
public static LocalTime now(Clock clock) {
Objects.requireNonNull(clock, "clock");
// inline OffsetTime factory to avoid creating object and InstantProvider checks
final Instant now = clock.instant(); // called once
ZoneOffset offset = clock.getZone().getRules().getOffset(now);
- long secsOfDay = now.getEpochSecond() % SECONDS_PER_DAY;
- secsOfDay = (secsOfDay + offset.getTotalSeconds()) % SECONDS_PER_DAY;
- if (secsOfDay < 0) {
- secsOfDay += SECONDS_PER_DAY;
- }
- return LocalTime.ofSecondOfDay(secsOfDay, now.getNano());
+ long localSecond = now.getEpochSecond() + offset.getTotalSeconds(); // overflow caught later
+ int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
+ return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + now.getNano());
}
//------------------------get-----------------------------------------------
/**
* Obtains an instance of {@code LocalTime} from an hour and minute.
* <p>
- * The second and nanosecond fields will be set to zero by this factory method.
- * <p>
- * This factory may return a cached value, but applications must not rely on this.
+ * This returns a {@code LocalTime} with the specified hour and minute.
+ * The second and nanosecond fields will be set to zero.
*
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @return the local time, not null
* @throws DateTimeException if the value of any field is out of range
@@ -304,13 +294,12 @@
}
/**
* Obtains an instance of {@code LocalTime} from an hour, minute and second.
* <p>
- * The nanosecond field will be set to zero by this factory method.
- * <p>
- * This factory may return a cached value, but applications must not rely on this.
+ * This returns a {@code LocalTime} with the specified hour, minute and second.
+ * The nanosecond field will be set to zero.
*
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @param second the second-of-minute to represent, from 0 to 59
* @return the local time, not null
@@ -327,11 +316,11 @@
}
/**
* Obtains an instance of {@code LocalTime} from an hour, minute, second and nanosecond.
* <p>
- * This factory may return a cached value, but applications must not rely on this.
+ * This returns a {@code LocalTime} with the specified hour, minute, second and nanosecond.
*
* @param hour the hour-of-day to represent, from 0 to 23
* @param minute the minute-of-hour to represent, from 0 to 59
* @param second the second-of-minute to represent, from 0 to 59
* @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999
@@ -348,11 +337,12 @@
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code LocalTime} from a second-of-day value.
* <p>
- * This factory may return a cached value, but applications must not rely on this.
+ * This returns a {@code LocalTime} with the specified second-of-day.
+ * The nanosecond field will be set to zero.
*
* @param secondOfDay the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}
* @return the local time, not null
* @throws DateTimeException if the second-of-day value is invalid
*/
@@ -364,34 +354,13 @@
secondOfDay -= minutes * SECONDS_PER_MINUTE;
return create(hours, minutes, (int) secondOfDay, 0);
}
/**
- * Obtains an instance of {@code LocalTime} from a second-of-day value, with
- * associated nanos of second.
- * <p>
- * This factory may return a cached value, but applications must not rely on this.
- *
- * @param secondOfDay the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}
- * @param nanoOfSecond the nano-of-second, from 0 to 999,999,999
- * @return the local time, not null
- * @throws DateTimeException if the either input value is invalid
- */
- public static LocalTime ofSecondOfDay(long secondOfDay, int nanoOfSecond) {
- SECOND_OF_DAY.checkValidValue(secondOfDay);
- NANO_OF_SECOND.checkValidValue(nanoOfSecond);
- int hours = (int) (secondOfDay / SECONDS_PER_HOUR);
- secondOfDay -= hours * SECONDS_PER_HOUR;
- int minutes = (int) (secondOfDay / SECONDS_PER_MINUTE);
- secondOfDay -= minutes * SECONDS_PER_MINUTE;
- return create(hours, minutes, (int) secondOfDay, nanoOfSecond);
- }
-
- /**
* Obtains an instance of {@code LocalTime} from a nanos-of-day value.
* <p>
- * This factory may return a cached value, but applications must not rely on this.
+ * This returns a {@code LocalTime} with the specified nanosecond-of-day.
*
* @param nanoOfDay the nano of day, from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1}
* @return the local time, not null
* @throws DateTimeException if the nanos of day value is invalid
*/
@@ -408,58 +377,45 @@
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code LocalTime} from a temporal object.
* <p>
- * A {@code TemporalAccessor} represents some form of date and time information.
- * This factory converts the arbitrary temporal object to an instance of {@code LocalTime}.
+ * This obtains a local time based on the specified temporal.
+ * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+ * which this factory converts to an instance of {@code LocalTime}.
* <p>
- * The conversion extracts the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
+ * The conversion uses the {@link Queries#localTime()} query, which relies
+ * on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
* <p>
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@code LocalTime::from}.
*
* @param temporal the temporal object to convert, not null
* @return the local time, not null
* @throws DateTimeException if unable to convert to a {@code LocalTime}
*/
public static LocalTime from(TemporalAccessor temporal) {
- if (temporal instanceof LocalTime) {
- return (LocalTime) temporal;
- } else if (temporal instanceof ChronoLocalDateTime) {
- return ((ChronoLocalDateTime) temporal).getTime();
- } else if (temporal instanceof ChronoZonedDateTime) {
- return ((ChronoZonedDateTime) temporal).getTime();
- }
- // handle builder as a special case
- if (temporal instanceof DateTimeBuilder) {
- DateTimeBuilder builder = (DateTimeBuilder) temporal;
- LocalTime time = builder.extract(LocalTime.class);
- if (time != null) {
- return time;
- }
- }
- try {
- return ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
- } catch (DateTimeException ex) {
- throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass(), ex);
+ LocalTime time = temporal.query(Queries.localTime());
+ if (time == null) {
+ throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
}
+ return time;
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}.
* <p>
* The string must represent a valid time and is parsed using
- * {@link java.time.format.DateTimeFormatters#isoLocalTime()}.
+ * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}.
*
* @param text the text to parse such as "10:15:30", not null
* @return the parsed local time, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
public static LocalTime parse(CharSequence text) {
- return parse(text, DateTimeFormatters.isoLocalTime());
+ return parse(text, DateTimeFormatter.ISO_LOCAL_TIME);
}
/**
* Obtains an instance of {@code LocalTime} from a text string using a specific formatter.
* <p>
@@ -537,11 +493,11 @@
* <li>{@code AMPM_OF_DAY}
* </ul>
* All other {@code ChronoField} instances will return false.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the field is supported is determined by the field.
*
* @param field the field to check, null returns false
* @return true if the field is supported on this time, false if not
@@ -549,11 +505,11 @@
@Override
public boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) {
return ((ChronoField) field).isTimeField();
}
- return field != null && field.doIsSupported(this);
+ return field != null && field.isSupportedBy(this);
}
/**
* Gets the range of valid values for the specified field.
* <p>
@@ -566,11 +522,11 @@
* The {@link #isSupported(TemporalField) supported fields} will return
* appropriate range instances.
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
* passing {@code this} as the argument.
* Whether the range can be obtained is determined by the field.
*
* @param field the field to query the range for, not null
* @return the range of valid values for the field, not null
@@ -594,11 +550,11 @@
* values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
* which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param field the field to get, not null
* @return the value for the field
@@ -624,11 +580,11 @@
* The {@link #isSupported(TemporalField) supported fields} will return valid
* values based on this time.
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
* passing {@code this} as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param field the field to get, not null
* @return the value for the field
@@ -644,11 +600,11 @@
if (field == MICRO_OF_DAY) {
return toNanoOfDay() / 1000;
}
return get0(field);
}
- return field.doGet(this);
+ return field.getFrom(this);
}
private int get0(TemporalField field) {
switch ((ChronoField) field) {
case NANO_OF_SECOND: return nano;
@@ -709,11 +665,11 @@
//-----------------------------------------------------------------------
/**
* Returns an adjusted copy of this time.
* <p>
- * This returns a new {@code LocalTime}, based on this one, with the time adjusted.
+ * This returns a {@code LocalTime}, based on this one, with the time adjusted.
* The adjustment takes place using the specified adjuster strategy object.
* Read the documentation of the adjuster to understand what adjustment will be made.
* <p>
* A simple adjuster might simply set the one of the fields, such as the hour field.
* A more complex adjuster might set the time to the last hour of the day.
@@ -739,11 +695,11 @@
}
/**
* Returns a copy of this time with the specified field set to a new value.
* <p>
- * This returns a new {@code LocalTime}, based on this one, with the value
+ * This returns a {@code LocalTime}, based on this one, with the value
* for the specified field changed.
* This can be used to change any supported field, such as the hour, minute or second.
* If it is not possible to set the value, because the field is not supported or for
* some other reason, an exception is thrown.
* <p>
@@ -805,11 +761,11 @@
* then a {@code DateTimeException} will be thrown.
* <p>
* All other {@code ChronoField} instances will throw a {@code DateTimeException}.
* <p>
* If the field is not a {@code ChronoField}, then the result of this method
- * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+ * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
* passing {@code this} as the argument. In this case, the field determines
* whether and how to adjust the instant.
* <p>
* This instance is immutable and unaffected by this method call.
*
@@ -841,11 +797,11 @@
case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue));
case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12);
}
throw new DateTimeException("Unsupported field: " + field.getName());
}
- return field.doWith(this, newValue);
+ return field.adjustInto(this, newValue);
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this {@code LocalTime} with the hour-of-day value altered.
@@ -922,72 +878,116 @@
* Truncating the time returns a copy of the original time with fields
* smaller than the specified unit set to zero.
* For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
* will set the second-of-minute and nano-of-second field to zero.
* <p>
- * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
- * units with an exact duration can be used, other units throw an exception.
+ * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+ * that divides into the length of a standard day without remainder.
+ * This includes all supplied time units on {@link ChronoUnit} and
+ * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param unit the unit to truncate to, not null
* @return a {@code LocalTime} based on this time with the time truncated, not null
* @throws DateTimeException if unable to truncate
*/
public LocalTime truncatedTo(TemporalUnit unit) {
if (unit == ChronoUnit.NANOS) {
return this;
- } else if (unit == ChronoUnit.DAYS) {
- return MIDNIGHT;
- } else if (unit.isDurationEstimated()) {
- throw new DateTimeException("Unit must not have an estimated duration");
}
- long nod = toNanoOfDay();
- long dur = unit.getDuration().toNanos();
- if (dur >= NANOS_PER_DAY) {
- throw new DateTimeException("Unit must not be a date unit");
+ Duration unitDur = unit.getDuration();
+ if (unitDur.getSeconds() > SECONDS_PER_DAY) {
+ throw new DateTimeException("Unit is too large to be used for truncation");
+ }
+ long dur = unitDur.toNanos();
+ if ((NANOS_PER_DAY % dur) != 0) {
+ throw new DateTimeException("Unit must divide into a standard day without remainder");
}
- nod = (nod / dur) * dur;
- return ofNanoOfDay(nod);
+ long nod = toNanoOfDay();
+ return ofNanoOfDay((nod / dur) * dur);
}
//-----------------------------------------------------------------------
/**
- * Returns a copy of this date with the specified period added.
+ * Returns a copy of this time with the specified amount added.
* <p>
- * This method returns a new time based on this time with the specified period added.
- * The adder is typically {@link Period} but may be any other type implementing
- * the {@link TemporalAdder} interface.
- * The calculation is delegated to the specified adjuster, which typically calls
- * back to {@link #plus(long, TemporalUnit)}.
+ * This returns a {@code LocalTime}, based on this one, with the specified amount added.
+ * The amount is typically {@link Duration} but may be any other type implementing
+ * the {@link TemporalAmount} interface.
+ * <p>
+ * The calculation is delegated to the amount object by calling
+ * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+ * to implement the addition in any way it wishes, however it typically
+ * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+ * of the amount implementation to determine if it can be successfully added.
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @param adder the adder to use, not null
+ * @param amountToAdd the amount to add, not null
* @return a {@code LocalTime} based on this time with the addition made, not null
* @throws DateTimeException if the addition cannot be made
* @throws ArithmeticException if numeric overflow occurs
*/
@Override
- public LocalTime plus(TemporalAdder adder) {
- return (LocalTime) adder.addTo(this);
+ public LocalTime plus(TemporalAmount amountToAdd) {
+ return (LocalTime) amountToAdd.addTo(this);
}
/**
- * Returns a copy of this time with the specified period added.
+ * Returns a copy of this time with the specified amount added.
* <p>
- * This method returns a new time based on this time with the specified period added.
- * This can be used to add any period that is defined by a unit, for example to add hours, minutes or seconds.
- * The unit is responsible for the details of the calculation, including the resolution
- * of any edge cases in the calculation.
+ * This returns a {@code LocalTime}, based on this one, with the amount
+ * in terms of the unit added. If it is not possible to add the amount, because the
+ * unit is not supported or for some other reason, an exception is thrown.
+ * <p>
+ * If the field is a {@link ChronoUnit} then the addition is implemented here.
+ * The supported fields behave as follows:
+ * <ul>
+ * <li>{@code NANOS} -
+ * Returns a {@code LocalTime} with the specified number of nanoseconds added.
+ * This is equivalent to {@link #plusNanos(long)}.
+ * <li>{@code MICROS} -
+ * Returns a {@code LocalTime} with the specified number of microseconds added.
+ * This is equivalent to {@link #plusNanos(long)} with the amount
+ * multiplied by 1,000.
+ * <li>{@code MILLIS} -
+ * Returns a {@code LocalTime} with the specified number of milliseconds added.
+ * This is equivalent to {@link #plusNanos(long)} with the amount
+ * multiplied by 1,000,000.
+ * <li>{@code SECONDS} -
+ * Returns a {@code LocalTime} with the specified number of seconds added.
+ * This is equivalent to {@link #plusSeconds(long)}.
+ * <li>{@code MINUTES} -
+ * Returns a {@code LocalTime} with the specified number of minutes added.
+ * This is equivalent to {@link #plusMinutes(long)}.
+ * <li>{@code HOURS} -
+ * Returns a {@code LocalTime} with the specified number of hours added.
+ * This is equivalent to {@link #plusHours(long)}.
+ * <li>{@code HALF_DAYS} -
+ * Returns a {@code LocalTime} with the specified number of half-days added.
+ * This is equivalent to {@link #plusHours(long)} with the amount
+ * multiplied by 12.
+ * <li>{@code DAYS} -
+ * Returns a {@code LocalTime} with the specified number of days added.
+ * This returns {@code this} time.
+ * </ul>
+ * <p>
+ * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+ * <p>
+ * If the field is not a {@code ChronoUnit}, then the result of this method
+ * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+ * passing {@code this} as the argument. In this case, the unit determines
+ * whether and how to perform the addition.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToAdd the amount of the unit to add to the result, may be negative
- * @param unit the unit of the period to add, not null
- * @return a {@code LocalTime} based on this time with the specified period added, not null
- * @throws DateTimeException if the unit cannot be added to this type
+ * @param unit the unit of the amount to add, not null
+ * @return a {@code LocalTime} based on this time with the specified amount added, not null
+ * @throws DateTimeException if the addition cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
public LocalTime plus(long amountToAdd, TemporalUnit unit) {
if (unit instanceof ChronoUnit) {
ChronoUnit f = (ChronoUnit) unit;
@@ -1001,11 +1001,11 @@
case HALF_DAYS: return plusHours((amountToAdd % 2) * 12);
case DAYS: return this;
}
throw new DateTimeException("Unsupported unit: " + unit.getName());
}
- return unit.doPlus(this, amountToAdd);
+ return unit.addTo(this, amountToAdd);
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this {@code LocalTime} with the specified period in hours added.
@@ -1105,44 +1105,51 @@
return create(newHour, newMinute, newSecond, newNano);
}
//-----------------------------------------------------------------------
/**
- * Returns a copy of this time with the specified period subtracted.
+ * Returns a copy of this time with the specified amount subtracted.
* <p>
- * This method returns a new time based on this time with the specified period subtracted.
- * The subtractor is typically {@link Period} but may be any other type implementing
- * the {@link TemporalSubtractor} interface.
- * The calculation is delegated to the specified adjuster, which typically calls
- * back to {@link #minus(long, TemporalUnit)}.
+ * This returns a {@code LocalTime}, based on this one, with the specified amount subtracted.
+ * The amount is typically {@link Duration} but may be any other type implementing
+ * the {@link TemporalAmount} interface.
+ * <p>
+ * The calculation is delegated to the amount object by calling
+ * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+ * to implement the subtraction in any way it wishes, however it typically
+ * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+ * of the amount implementation to determine if it can be successfully subtracted.
* <p>
* This instance is immutable and unaffected by this method call.
*
- * @param subtractor the subtractor to use, not null
+ * @param amountToSubtract the amount to subtract, not null
* @return a {@code LocalTime} based on this time with the subtraction made, not null
* @throws DateTimeException if the subtraction cannot be made
* @throws ArithmeticException if numeric overflow occurs
*/
@Override
- public LocalTime minus(TemporalSubtractor subtractor) {
- return (LocalTime) subtractor.subtractFrom(this);
+ public LocalTime minus(TemporalAmount amountToSubtract) {
+ return (LocalTime) amountToSubtract.subtractFrom(this);
}
/**
- * Returns a copy of this time with the specified period subtracted.
+ * Returns a copy of this time with the specified amount subtracted.
+ * <p>
+ * This returns a {@code LocalTime}, based on this one, with the amount
+ * in terms of the unit subtracted. If it is not possible to subtract the amount,
+ * because the unit is not supported or for some other reason, an exception is thrown.
* <p>
- * This method returns a new time based on this time with the specified period subtracted.
- * This can be used to subtract any period that is defined by a unit, for example to subtract hours, minutes or seconds.
- * The unit is responsible for the details of the calculation, including the resolution
- * of any edge cases in the calculation.
+ * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+ * See that method for a full description of how addition, and thus subtraction, works.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param amountToSubtract the amount of the unit to subtract from the result, may be negative
- * @param unit the unit of the period to subtract, not null
- * @return a {@code LocalTime} based on this time with the specified period subtracted, not null
- * @throws DateTimeException if the unit cannot be added to this type
+ * @param unit the unit of the amount to subtract, not null
+ * @return a {@code LocalTime} based on this time with the specified amount subtracted, not null
+ * @throws DateTimeException if the subtraction cannot be made
+ * @throws ArithmeticException if numeric overflow occurs
*/
@Override
public LocalTime minus(long amountToSubtract, TemporalUnit unit) {
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
}
@@ -1228,17 +1235,21 @@
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
@SuppressWarnings("unchecked")
@Override
public <R> R query(TemporalQuery<R> query) {
- if (query == Queries.precision()) {
+ if (query == Queries.chronology() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+ return null;
+ } else if (query == Queries.localTime()) {
+ return (R) this;
+ } else if (query == Queries.localDate()) {
+ return null;
+ } else if (query == Queries.precision()) {
return (R) NANOS;
}
// inline TemporalAccessor.super.query(query) as an optimization
- if (query == Queries.chrono() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
- return null;
- }
+ // non-JDK classes are not permitted to make this optimization
return query.queryFrom(this);
}
/**
* Adjusts the specified temporal object to have the same time as this object.
@@ -1283,18 +1294,19 @@
* The calculation returns a whole number, representing the number of
* complete units between the two times.
* For example, the period in hours between 11:30 and 13:29 will only
* be one hour as it is one minute short of two hours.
* <p>
- * This method operates in association with {@link TemporalUnit#between}.
- * The result of this method is a {@code long} representing the amount of
- * the specified unit. By contrast, the result of {@code between} is an
- * object that can be used directly in addition/subtraction:
+ * There are two equivalent ways of using this method.
+ * The first is to invoke this method.
+ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
* <pre>
- * long period = start.periodUntil(end, HOURS); // this method
- * dateTime.plus(HOURS.between(start, end)); // use in plus/minus
+ * // these two lines are equivalent
+ * amount = start.periodUntil(end, MINUTES);
+ * amount = MINUTES.between(start, end);
* </pre>
+ * The choice should be made based on which makes the code more readable.
* <p>
* The calculation is implemented in this method for {@link ChronoUnit}.
* The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
* {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS} are supported.
* Other {@code ChronoUnit} values will throw an exception.
@@ -1330,36 +1342,32 @@
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, endTime).getAmount();
+ return unit.between(this, endTime);
}
//-----------------------------------------------------------------------
/**
- * Returns a local date-time formed from this time at the specified date.
+ * Combines this time with a date to create a {@code LocalDateTime}.
* <p>
- * This combines this time with the specified date to form a {@code LocalDateTime}.
+ * This returns a {@code LocalDateTime} formed from this time at the specified date.
* All possible combinations of date and time are valid.
- * <p>
- * This instance is immutable and unaffected by this method call.
*
* @param date the date to combine with, not null
* @return the local date-time formed from this time and the specified date, not null
*/
public LocalDateTime atDate(LocalDate date) {
return LocalDateTime.of(date, this);
}
/**
- * Returns an offset time formed from this time and the specified offset.
+ * Combines this time with a date to create an {@code OffsetTime}.
* <p>
- * This combines this time with the specified offset to form an {@code OffsetTime}.
+ * This returns an {@code OffsetTime} formed from this time at the specified offset.
* All possible combinations of time and offset are valid.
- * <p>
- * This instance is immutable and unaffected by this method call.
*
* @param offset the offset to combine with, not null
* @return the offset time formed from this time and the specified offset, not null
*/
public OffsetTime atOffset(ZoneOffset offset) {
@@ -1527,19 +1535,19 @@
/**
* Outputs this time as a {@code String} using the formatter.
* <p>
* This time will be passed to the formatter
- * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+ * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
*
* @param formatter the formatter to use, not null
* @return the formatted time string, not null
* @throws DateTimeException if an error occurs during printing
*/
public String toString(DateTimeFormatter formatter) {
Objects.requireNonNull(formatter, "formatter");
- return formatter.print(this);
+ return formatter.format(this);
}
//-----------------------------------------------------------------------
/**
* Writes the object using a