src/share/classes/java/time/OffsetTime.java

Print this page

        

*** 57,92 **** * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time.temporal; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS; - import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_HOUR; - import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_MINUTE; - import static java.time.temporal.ChronoLocalDateTimeImpl.NANOS_PER_SECOND; - import static java.time.temporal.ChronoLocalDateTimeImpl.SECONDS_PER_DAY; import static java.time.temporal.ChronoUnit.NANOS; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; - import java.time.Clock; - import java.time.DateTimeException; - import java.time.Instant; - import java.time.LocalDate; - import java.time.LocalTime; - import java.time.ZoneId; - import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; - import java.time.format.DateTimeFormatters; import java.time.format.DateTimeParseException; import java.time.zone.ZoneRules; import java.util.Objects; /** * A time with an offset from UTC/Greenwich in the ISO-8601 calendar system, --- 57,95 ---- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time; + import static java.time.LocalTime.NANOS_PER_HOUR; + import static java.time.LocalTime.NANOS_PER_MINUTE; + import static java.time.LocalTime.NANOS_PER_SECOND; + import static java.time.LocalTime.SECONDS_PER_DAY; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS; import static java.time.temporal.ChronoUnit.NANOS; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; + import java.time.temporal.ChronoField; + import java.time.temporal.ChronoUnit; + import java.time.temporal.Queries; + import java.time.temporal.Temporal; + import java.time.temporal.TemporalAccessor; + import java.time.temporal.TemporalAdjuster; + import java.time.temporal.TemporalAmount; + import java.time.temporal.TemporalField; + import java.time.temporal.TemporalQuery; + import java.time.temporal.TemporalUnit; + import java.time.temporal.ValueRange; import java.time.zone.ZoneRules; import java.util.Objects; /** * A time with an offset from UTC/Greenwich in the ISO-8601 calendar system,
*** 200,209 **** --- 203,235 ---- */ public static OffsetTime of(LocalTime time, ZoneOffset offset) { return new OffsetTime(time, offset); } + /** + * Obtains an instance of {@code OffsetTime} from an hour, minute, second and nanosecond. + * <p> + * This creates an offset time with the four specified fields. + * <p> + * This method exists primarily for writing test cases. + * Non test-code will typically use other methods to create an offset time. + * {@code LocalTime} has two additional convenience variants of the + * equivalent factory method taking fewer arguments. + * They are not provided here to reduce the footprint of the API. + * + * @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 + * @param offset the zone offset, not null + * @return the offset time, not null + * @throws DateTimeException if the value of any field is out of range + */ + public static OffsetTime of(int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) { + return new OffsetTime(LocalTime.of(hour, minute, second, nanoOfSecond), offset); + } + //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetTime} from an {@code Instant} and zone ID. * <p> * This creates an offset time with the same instant as that specified.
*** 221,247 **** public static OffsetTime ofInstant(Instant instant, ZoneId zone) { Objects.requireNonNull(instant, "instant"); Objects.requireNonNull(zone, "zone"); ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); ! long secsOfDay = instant.getEpochSecond() % SECONDS_PER_DAY; ! secsOfDay = (secsOfDay + offset.getTotalSeconds()) % SECONDS_PER_DAY; ! if (secsOfDay < 0) { ! secsOfDay += SECONDS_PER_DAY; ! } ! LocalTime time = LocalTime.ofSecondOfDay(secsOfDay, instant.getNano()); return new OffsetTime(time, offset); } //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetTime} 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 OffsetTime}. ! * <p> ! * The conversion extracts and combines {@code LocalTime} and {@code ZoneOffset}. * <p> * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code OffsetTime::from}. * * @param temporal the temporal object to convert, not null --- 247,274 ---- public static OffsetTime ofInstant(Instant instant, ZoneId zone) { Objects.requireNonNull(instant, "instant"); Objects.requireNonNull(zone, "zone"); ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); ! long localSecond = instant.getEpochSecond() + offset.getTotalSeconds(); // overflow caught later ! int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); ! LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano()); return new OffsetTime(time, offset); } //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetTime} from a temporal object. * <p> ! * This obtains an offset 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 OffsetTime}. ! * <p> ! * The conversion extracts and combines the {@code ZoneOffset} and the ! * {@code LocalTime} from the temporal object. ! * Implementations are permitted to perform optimizations such as accessing ! * those fields that are equivalent to the relevant objects. * <p> * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code OffsetTime::from}. * * @param temporal the temporal object to convert, not null
*** 264,281 **** //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetTime} from a text string such as {@code 10:15:30+01:00}. * <p> * The string must represent a valid time and is parsed using ! * {@link java.time.format.DateTimeFormatters#isoOffsetTime()}. * * @param text the text to parse such as "10:15:30+01:00", not null * @return the parsed local time, not null * @throws DateTimeParseException if the text cannot be parsed */ public static OffsetTime parse(CharSequence text) { ! return parse(text, DateTimeFormatters.isoOffsetTime()); } /** * Obtains an instance of {@code OffsetTime} from a text string using a specific formatter. * <p> --- 291,308 ---- //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetTime} from a text string such as {@code 10:15:30+01:00}. * <p> * The string must represent a valid time and is parsed using ! * {@link java.time.format.DateTimeFormatter#ISO_OFFSET_TIME}. * * @param text the text to parse such as "10:15:30+01:00", not null * @return the parsed local time, not null * @throws DateTimeParseException if the text cannot be parsed */ public static OffsetTime parse(CharSequence text) { ! return parse(text, DateTimeFormatter.ISO_OFFSET_TIME); } /** * Obtains an instance of {@code OffsetTime} from a text string using a specific formatter. * <p>
*** 345,355 **** * <li>{@code OFFSET_SECONDS} * </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)} * 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 --- 372,382 ---- * <li>{@code OFFSET_SECONDS} * </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.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
*** 357,367 **** @Override public boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { return ((ChronoField) field).isTimeField() || field == OFFSET_SECONDS; } ! return field != null && field.doIsSupported(this); } /** * Gets the range of valid values for the specified field. * <p> --- 384,394 ---- @Override public boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { return ((ChronoField) field).isTimeField() || field == OFFSET_SECONDS; } ! return field != null && field.isSupportedBy(this); } /** * Gets the range of valid values for the specified field. * <p>
*** 374,384 **** * 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)} * 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 --- 401,411 ---- * 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.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
*** 390,400 **** if (field == OFFSET_SECONDS) { return field.range(); } return time.range(field); } ! return field.doRange(this); } /** * Gets the value of the specified field from this time as an {@code int}. * <p> --- 417,427 ---- if (field == OFFSET_SECONDS) { return field.range(); } return time.range(field); } ! return field.rangeRefinedBy(this); } /** * Gets the value of the specified field from this time as an {@code int}. * <p>
*** 408,418 **** * 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)} * 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 --- 435,445 ---- * 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.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
*** 435,445 **** * 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)} * 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 --- 462,472 ---- * 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.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
*** 448,462 **** */ @Override public long getLong(TemporalField field) { if (field instanceof ChronoField) { if (field == OFFSET_SECONDS) { ! return getOffset().getTotalSeconds(); } return time.getLong(field); } ! return field.doGet(this); } //----------------------------------------------------------------------- /** * Gets the zone offset, such as '+01:00'. --- 475,489 ---- */ @Override public long getLong(TemporalField field) { if (field instanceof ChronoField) { if (field == OFFSET_SECONDS) { ! return offset.getTotalSeconds(); } return time.getLong(field); } ! return field.getFrom(this); } //----------------------------------------------------------------------- /** * Gets the zone offset, such as '+01:00'.
*** 524,534 **** * This returns a {@code LocalTime} with the same hour, minute, second and * nanosecond as this date-time. * * @return the time part of this date-time, not null */ ! public LocalTime getTime() { return time; } //----------------------------------------------------------------------- /** --- 551,561 ---- * This returns a {@code LocalTime} with the same hour, minute, second and * nanosecond as this date-time. * * @return the time part of this date-time, not null */ ! public LocalTime toLocalTime() { return time; } //----------------------------------------------------------------------- /**
*** 569,579 **** //----------------------------------------------------------------------- /** * Returns an adjusted copy of this time. * <p> ! * This returns a new {@code OffsetTime}, 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. --- 596,606 ---- //----------------------------------------------------------------------- /** * Returns an adjusted copy of this time. * <p> ! * This returns an {@code OffsetTime}, 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.
*** 610,620 **** } /** * Returns a copy of this time with the specified field set to a new value. * <p> ! * This returns a new {@code OffsetTime}, 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> --- 637,647 ---- } /** * Returns a copy of this time with the specified field set to a new value. * <p> ! * This returns an {@code OffsetTime}, 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>
*** 629,639 **** * In this case, the offset is not part of the calculation and will be unchanged. * <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)} * 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. * --- 656,666 ---- * In this case, the offset is not part of the calculation and will be unchanged. * <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.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. *
*** 650,660 **** ChronoField f = (ChronoField) field; return with(time, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue))); } return with(time.with(field, newValue), offset); } ! return field.doWith(this, newValue); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetTime} with the hour-of-day value altered. --- 677,687 ---- ChronoField f = (ChronoField) field; return with(time, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue))); } return with(time.with(field, newValue), offset); } ! return field.adjustInto(this, newValue); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetTime} with the hour-of-day value altered.
*** 723,734 **** * Truncation 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. * <p> * The offset does not affect the calculation and will be the same in the result. * <p> * This instance is immutable and unaffected by this method call. * --- 750,763 ---- * Truncation 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> ! * 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> * The offset does not affect the calculation and will be the same in the result. * <p> * This instance is immutable and unaffected by this method call. *
*** 740,792 **** return with(time.truncatedTo(unit), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this date with the specified period added. * <p> ! * This method returns a new time based on this time with the specified period added. ! * The adder is typically {@link java.time.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)}. ! * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * ! * @param adder the adder to use, not null * @return an {@code OffsetTime} 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 OffsetTime plus(TemporalAdder adder) { ! return (OffsetTime) adder.addTo(this); } /** ! * Returns a copy of this time with the specified period 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. * The offset is not part of the calculation and will be unchanged in the result. * <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 an {@code OffsetTime} based on this time with the specified period added, not null ! * @throws DateTimeException if the unit cannot be added to this type */ @Override public OffsetTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(time.plus(amountToAdd, unit), offset); } ! return unit.doPlus(this, amountToAdd); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetTime} with the specified period in hours added. --- 769,832 ---- return with(time.truncatedTo(unit), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this time with the specified amount added. * <p> ! * This returns an {@code OffsetTime}, 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 amountToAdd the amount to add, not null * @return an {@code OffsetTime} 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 OffsetTime plus(TemporalAmount amountToAdd) { ! return (OffsetTime) amountToAdd.addTo(this); } /** ! * Returns a copy of this time with the specified amount added. * <p> ! * This returns an {@code OffsetTime}, 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 by ! * {@link LocalTime#plus(long, TemporalUnit)}. * The offset is not part of the calculation and will be unchanged in the result. * <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 amount to add, not null ! * @return an {@code OffsetTime} 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 OffsetTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(time.plus(amountToAdd, unit), offset); } ! return unit.addTo(this, amountToAdd); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetTime} with the specified period in hours added.
*** 848,893 **** return with(time.plusNanos(nanos), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this time with the specified period subtracted. * <p> ! * This method returns a new time based on this time with the specified period subtracted. ! * The subtractor is typically {@link java.time.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)}. ! * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * ! * @param subtractor the subtractor to use, not null * @return an {@code OffsetTime} 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 OffsetTime minus(TemporalSubtractor subtractor) { ! return (OffsetTime) subtractor.subtractFrom(this); } /** ! * Returns a copy of this time with the specified period subtracted. * <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. ! * The offset is not part of the calculation and will be unchanged in the result. * <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 an {@code OffsetTime} based on this time with the specified period subtracted, not null ! * @throws DateTimeException if the unit cannot be added to this type */ @Override public OffsetTime minus(long amountToSubtract, TemporalUnit unit) { return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); } --- 888,938 ---- return with(time.plusNanos(nanos), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this time with the specified amount subtracted. * <p> ! * This returns an {@code OffsetTime}, 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 amountToSubtract the amount to subtract, not null * @return an {@code OffsetTime} 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 OffsetTime minus(TemporalAmount amountToSubtract) { ! return (OffsetTime) amountToSubtract.subtractFrom(this); } /** ! * Returns a copy of this time with the specified amount subtracted. * <p> ! * This returns an {@code OffsetTime}, 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 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 amount to subtract, not null ! * @return an {@code OffsetTime} 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 OffsetTime minus(long amountToSubtract, TemporalUnit unit) { return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); }
*** 973,988 **** * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public <R> R query(TemporalQuery<R> query) { ! if (query == Queries.precision()) { return (R) NANOS; - } else if (query == Queries.offset() || query == Queries.zone()) { - return (R) getOffset(); } ! return Temporal.super.query(query); } /** * Adjusts the specified temporal object to have the same offset and time * as this object. --- 1018,1039 ---- * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public <R> R query(TemporalQuery<R> query) { ! if (query == Queries.offset() || query == Queries.zone()) { ! return (R) offset; ! } else if (query == Queries.zoneId() | query == Queries.chronology() || query == Queries.localDate()) { ! return null; ! } else if (query == Queries.localTime()) { ! return (R) time; ! } else if (query == Queries.precision()) { return (R) NANOS; } ! // inline TemporalAccessor.super.query(query) as an optimization ! // non-JDK classes are not permitted to make this optimization ! return query.queryFrom(this); } /** * Adjusts the specified temporal object to have the same offset and time * as this object.
*** 1010,1020 **** * @throws ArithmeticException if numeric overflow occurs */ @Override public Temporal adjustInto(Temporal temporal) { return temporal ! .with(OFFSET_SECONDS, getOffset().getTotalSeconds()) .with(NANO_OF_DAY, time.toNanoOfDay()); } /** * Calculates the period between this time and another time in --- 1061,1071 ---- * @throws ArithmeticException if numeric overflow occurs */ @Override public Temporal adjustInto(Temporal temporal) { return temporal ! .with(OFFSET_SECONDS, offset.getTotalSeconds()) .with(NANO_OF_DAY, time.toNanoOfDay()); } /** * Calculates the period between this time and another time in
*** 1033,1050 **** * The calculation returns a whole number, representing the number of * complete units between the two times. * For example, the period in hours between 11:30Z and 13:29Z 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: * <pre> ! * long period = start.periodUntil(end, HOURS); // this method ! * dateTime.plus(HOURS.between(start, end)); // use in plus/minus * </pre> * <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. --- 1084,1102 ---- * The calculation returns a whole number, representing the number of * complete units between the two times. * For example, the period in hours between 11:30Z and 13:29Z will only * be one hour as it is one minute short of two hours. * <p> ! * 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> ! * // 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.
*** 1080,1100 **** 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(); } //----------------------------------------------------------------------- /** ! * Returns an offset date-time formed from this time at the specified date. * <p> ! * This combines this time with the specified date to form an {@code OffsetDateTime}. * 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 offset date-time formed from this time and the specified date, not null */ public OffsetDateTime atDate(LocalDate date) { --- 1132,1150 ---- 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); } //----------------------------------------------------------------------- /** ! * Combines this date with a time to create an {@code OffsetDateTime}. * <p> ! * This returns an {@code OffsetDateTime} formed from this time and the specified date. * All possible combinations of date and time are valid. * * @param date the date to combine with, not null * @return the offset date-time formed from this time and the specified date, not null */ public OffsetDateTime atDate(LocalDate date) {
*** 1259,1285 **** /** * 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}. * * @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); } // ----------------------------------------------------------------------- /** * Writes the object using a * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>. * <pre> ! * out.writeByte(2); // identifies this as a OffsetDateTime * out.writeObject(time); * out.writeObject(offset); * </pre> * * @return the instance of {@code Ser}, not null --- 1309,1335 ---- /** * Outputs this time as a {@code String} using the formatter. * <p> * This time will be passed to the formatter ! * {@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.format(this); } // ----------------------------------------------------------------------- /** * Writes the object using a * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>. * <pre> ! * out.writeByte(9); // identifies this as a OffsetDateTime * out.writeObject(time); * out.writeObject(offset); * </pre> * * @return the instance of {@code Ser}, not null