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

Print this page

        

@@ -57,36 +57,39 @@
  * 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;
+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.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.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,10 +203,33 @@
      */
     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,27 +247,28 @@
     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());
+        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>
-     * 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}.
+     * 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,18 +291,18 @@
     //-----------------------------------------------------------------------
     /**
      * 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()}.
+     * {@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, DateTimeFormatters.isoOffsetTime());
+        return parse(text, DateTimeFormatter.ISO_OFFSET_TIME);
     }
 
     /**
      * Obtains an instance of {@code OffsetTime} from a text string using a specific formatter.
      * <p>

@@ -345,11 +372,11 @@
      * <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)}
+     * 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,11 +384,11 @@
     @Override
     public boolean isSupported(TemporalField field) {
         if (field instanceof ChronoField) {
             return ((ChronoField) field).isTimeField() || field == OFFSET_SECONDS;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
      * Gets the range of valid values for the specified field.
      * <p>

@@ -374,11 +401,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

@@ -390,11 +417,11 @@
             if (field == OFFSET_SECONDS) {
                 return field.range();
             }
             return time.range(field);
         }
-        return field.doRange(this);
+        return field.rangeRefinedBy(this);
     }
 
     /**
      * Gets the value of the specified field from this time as an {@code int}.
      * <p>

@@ -408,11 +435,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

@@ -435,11 +462,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

@@ -448,15 +475,15 @@
      */
     @Override
     public long getLong(TemporalField field) {
         if (field instanceof ChronoField) {
             if (field == OFFSET_SECONDS) {
-                return getOffset().getTotalSeconds();
+                return offset.getTotalSeconds();
             }
             return time.getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Gets the zone offset, such as '+01:00'.

@@ -524,11 +551,11 @@
      * 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() {
+    public LocalTime toLocalTime() {
         return time;
     }
 
     //-----------------------------------------------------------------------
     /**

@@ -569,11 +596,11 @@
 
     //-----------------------------------------------------------------------
     /**
      * Returns an adjusted copy of this time.
      * <p>
-     * This returns a new {@code OffsetTime}, based on this one, with the time adjusted.
+     * 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,11 +637,11 @@
     }
 
     /**
      * 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
+     * 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,11 +656,11 @@
      * 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)}
+     * 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,11 +677,11 @@
                 ChronoField f = (ChronoField) field;
                 return with(time, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
             }
             return with(time.with(field, newValue), offset);
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Returns a copy of this {@code OffsetTime} with the hour-of-day value altered.

@@ -723,12 +750,14 @@
      * 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.
+     * 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,53 +769,64 @@
         return with(time.truncatedTo(unit), offset);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * 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 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.
+     * 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 adder  the adder to use, not null
+     * @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(TemporalAdder adder) {
-        return (OffsetTime) adder.addTo(this);
+    public OffsetTime plus(TemporalAmount amountToAdd) {
+        return (OffsetTime) 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 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 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
+     * @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.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Returns a copy of this {@code OffsetTime} with the specified period in hours added.

@@ -848,46 +888,51 @@
         return with(time.plusNanos(nanos), offset);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * 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 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.
+     * 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 subtractor  the subtractor to use, not null
+     * @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(TemporalSubtractor subtractor) {
-        return (OffsetTime) subtractor.subtractFrom(this);
+    public OffsetTime minus(TemporalAmount amountToSubtract) {
+        return (OffsetTime) 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 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.
+     * 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 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
+     * @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,16 +1018,22 @@
      * @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.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;
-        } else if (query == Queries.offset() || query == Queries.zone()) {
-            return (R) getOffset();
         }
-        return Temporal.super.query(query);
+        // 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,11 +1061,11 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
         return temporal
-                .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
+                .with(OFFSET_SECONDS, offset.getTotalSeconds())
                 .with(NANO_OF_DAY, time.toNanoOfDay());
     }
 
     /**
      * Calculates the period between this time and another time in

@@ -1033,18 +1084,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: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:
+     * 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.

@@ -1080,21 +1132,19 @@
                 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 an offset date-time formed from this time at the specified date.
+     * Combines this date with a time to create an {@code OffsetDateTime}.
      * <p>
-     * This combines this time with the specified date to form an {@code OffsetDateTime}.
+     * This returns an {@code OffsetDateTime} formed from this time and 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 offset date-time formed from this time and the specified date, not null
      */
     public OffsetDateTime atDate(LocalDate date) {

@@ -1259,27 +1309,27 @@
 
     /**
      * 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
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(2);  // identifies this as a OffsetDateTime
+     *  out.writeByte(9);  // identifies this as a OffsetDateTime
      *  out.writeObject(time);
      *  out.writeObject(offset);
      * </pre>
      *
      * @return the instance of {@code Ser}, not null