src/share/classes/java/time/OffsetDateTime.java

Print this page

        

@@ -57,11 +57,11 @@
  * 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.temporal.ChronoField.EPOCH_DAY;
 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
 import static java.time.temporal.ChronoField.NANO_OF_DAY;
 import static java.time.temporal.ChronoField.OFFSET_SECONDS;

@@ -71,24 +71,24 @@
 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.DayOfWeek;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+import java.time.chrono.IsoChronology;
 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.Comparator;
 import java.util.Objects;
 
 /**

@@ -149,11 +149,11 @@
     public static final Comparator<OffsetDateTime> INSTANT_COMPARATOR = new Comparator<OffsetDateTime>() {
         @Override
         public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) {
             int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
             if (cmp == 0) {
-                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
+                cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
             }
             return cmp;
         }
     };
 

@@ -251,22 +251,38 @@
     public static OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset) {
         return new OffsetDateTime(dateTime, offset);
     }
 
     /**
-     * Obtains an instance of {@code OffsetDateTime} from a {@code ZonedDateTime}.
+     * Obtains an instance of {@code OffsetDateTime} from a year, month, day,
+     * hour, minute, second, nanosecond and offset.
      * <p>
-     * This creates an offset date-time with the same local date-time and offset as
-     * the zoned date-time. The result will have the same instant as the input.
-     *
-     * @param zonedDateTime  the zoned date-time to convert from, not null
+     * This creates an offset date-time with the seven 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 LocalDateTime} has five additional convenience variants of the
+     * equivalent factory method taking fewer arguments.
+     * They are not provided here to reduce the footprint of the API.
+     *
+     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
+     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
+     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
+     * @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 date-time, not null
-     * @throws DateTimeException if the result exceeds the supported range
+     * @throws DateTimeException if the value of any field is out of range, or
+     *  if the day-of-month is invalid for the month-year
      */
-    public static OffsetDateTime of(ZonedDateTime zonedDateTime) {
-        Objects.requireNonNull(zonedDateTime, "zonedDateTime");
-        return new OffsetDateTime(zonedDateTime.getDateTime(), zonedDateTime.getOffset());
+    public static OffsetDateTime of(
+            int year, int month, int dayOfMonth,
+            int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) {
+        LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
+        return new OffsetDateTime(dt, offset);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID.

@@ -291,15 +307,20 @@
 
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code OffsetDateTime} 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 OffsetDateTime}.
-     * <p>
-     * The conversion extracts and combines {@code LocalDateTime} and {@code ZoneOffset}.
-     * If that fails it will try to extract and combine {@code Instant} and {@code ZoneOffset}.
+     * This obtains an offset date-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 OffsetDateTime}.
+     * <p>
+     * The conversion will first obtain a {@code ZoneOffset} from the temporal object.
+     * It will then try to obtain a {@code LocalDateTime}, falling back to an {@code Instant} if necessary.
+     * The result will be the combination of {@code ZoneOffset} with either
+     * with {@code LocalDateTime} or {@code Instant}.
+     * 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 OffsetDateTime::from}.
      *
      * @param temporal  the temporal object to convert, not null

@@ -328,18 +349,18 @@
     /**
      * Obtains an instance of {@code OffsetDateTime} from a text string
      * such as {@code 2007-12-03T10:15:30+01:00}.
      * <p>
      * The string must represent a valid date-time and is parsed using
-     * {@link java.time.format.DateTimeFormatters#isoOffsetDateTime()}.
+     * {@link java.time.format.DateTimeFormatter#ISO_OFFSET_DATE_TIME}.
      *
      * @param text  the text to parse such as "2007-12-03T10:15:30+01:00", not null
      * @return the parsed offset date-time, not null
      * @throws DateTimeParseException if the text cannot be parsed
      */
     public static OffsetDateTime parse(CharSequence text) {
-        return parse(text, DateTimeFormatters.isoOffsetDateTime());
+        return parse(text, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
     }
 
     /**
      * Obtains an instance of {@code OffsetDateTime} from a text string using a specific formatter.
      * <p>

@@ -423,20 +444,20 @@
      * <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 date-time, false if not
      */
     @Override
     public boolean isSupported(TemporalField field) {
-        return field instanceof ChronoField || (field != null && field.doIsSupported(this));
+        return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
     }
 
     /**
      * Gets the range of valid values for the specified field.
      * <p>

@@ -449,11 +470,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

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

@@ -484,11 +505,11 @@
      * {@code EPOCH_DAY}, {@code EPOCH_MONTH} and {@code INSTANT_SECONDS} 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

@@ -518,11 +539,11 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this date-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

@@ -536,11 +557,11 @@
                 case INSTANT_SECONDS: return toEpochSecond();
                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
             }
             return dateTime.getLong(field);
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Gets the zone offset, such as '+01:00'.

@@ -609,11 +630,11 @@
      * This returns a {@code LocalDateTime} with the same year, month, day and time
      * as this date-time.
      *
      * @return the local date-time part of this date-time, not null
      */
-    public LocalDateTime getDateTime() {
+    public LocalDateTime toLocalDateTime() {
         return dateTime;
     }
 
     //-----------------------------------------------------------------------
     /**

@@ -622,21 +643,21 @@
      * This returns a {@code LocalDate} with the same year, month and day
      * as this date-time.
      *
      * @return the date part of this date-time, not null
      */
-    public LocalDate getDate() {
-        return dateTime.getDate();
+    public LocalDate toLocalDate() {
+        return dateTime.toLocalDate();
     }
 
     /**
      * Gets the year field.
      * <p>
      * This method returns the primitive {@code int} value for the year.
      * <p>
      * The year returned by this method is proleptic as per {@code get(YEAR)}.
-     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
+     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
      *
      * @return the year, from MIN_YEAR to MAX_YEAR
      */
     public int getYear() {
         return dateTime.getYear();

@@ -717,12 +738,12 @@
      * 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 dateTime.getTime();
+    public LocalTime toLocalTime() {
+        return dateTime.toLocalTime();
     }
 
     /**
      * Gets the hour-of-day field.
      *

@@ -761,20 +782,20 @@
 
     //-----------------------------------------------------------------------
     /**
      * Returns an adjusted copy of this date-time.
      * <p>
-     * This returns a new {@code OffsetDateTime}, based on this one, with the date-time adjusted.
+     * This returns an {@code OffsetDateTime}, based on this one, with the date-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 year field.
      * A more complex adjuster might set the date to the last day of the month.
      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
      * These include finding the "last day of the month" and "next Wednesday".
      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
-     * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
+     * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
      * The adjuster is responsible for handling special cases, such as the varying
      * lengths of month and leap years.
      * <p>
      * For example this code returns a date on the last day of July:
      * <pre>

@@ -819,11 +840,11 @@
     }
 
     /**
      * Returns a copy of this date-time with the specified field set to a new value.
      * <p>
-     * This returns a new {@code OffsetDateTime}, based on this one, with the value
+     * TThis returns an {@code OffsetDateTime}, based on this one, with the value
      * for the specified field changed.
      * This can be used to change any supported field, such as the year, month or day-of-month.
      * 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>

@@ -847,11 +868,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.
      *

@@ -871,11 +892,11 @@
                     return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
                 }
             }
             return with(dateTime.with(field, newValue), offset);
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Returns a copy of this {@code OffsetDateTime} with the year altered.

@@ -914,12 +935,12 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
      * @return an {@code OffsetDateTime} based on this date-time with the requested day, not null
-     * @throws DateTimeException if the day-of-month value is invalid
-     * @throws DateTimeException if the day-of-month is invalid for the month-year
+     * @throws DateTimeException if the day-of-month value is invalid,
+     *  or if the day-of-month is invalid for the month-year
      */
     public OffsetDateTime withDayOfMonth(int dayOfMonth) {
         return with(dateTime.withDayOfMonth(dayOfMonth), offset);
     }
 

@@ -929,12 +950,12 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
      * @return an {@code OffsetDateTime} based on this date with the requested day, not null
-     * @throws DateTimeException if the day-of-year value is invalid
-     * @throws DateTimeException if the day-of-year is invalid for the year
+     * @throws DateTimeException if the day-of-year value is invalid,
+     *  or if the day-of-year is invalid for the year
      */
     public OffsetDateTime withDayOfYear(int dayOfYear) {
         return with(dateTime.withDayOfYear(dayOfYear), offset);
     }
 

@@ -1006,12 +1027,14 @@
      * Truncation returns a copy of the original date-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.
      *

@@ -1023,53 +1046,64 @@
         return with(dateTime.truncatedTo(unit), offset);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
      * <p>
-     * This method returns a new date-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 OffsetDateTime}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} or {@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 OffsetDateTime} based on this date-time with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetDateTime plus(TemporalAdder adder) {
-        return (OffsetDateTime) adder.addTo(this);
+    public OffsetDateTime plus(TemporalAmount amountToAdd) {
+        return (OffsetDateTime) amountToAdd.addTo(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period added.
+     * Returns a copy of this date-time with the specified amount added.
+     * <p>
+     * This returns an {@code OffsetDateTime}, 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>
-     * This method returns a new date-time based on this date-time with the specified period added.
-     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
-     * The unit is responsible for the details of the calculation, including the resolution
-     * of any edge cases in the calculation.
+     * If the field is a {@link ChronoUnit} then the addition is implemented by
+     * {@link LocalDateTime#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 OffsetDateTime} based on this date-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 OffsetDateTime} based on this date-time with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             return with(dateTime.plus(amountToAdd, unit), offset);
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Returns a copy of this {@code OffsetDateTime} with the specified period in years added.

@@ -1209,45 +1243,51 @@
         return with(dateTime.plusNanos(nanos), offset);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-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 OffsetDateTime}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} or {@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 OffsetDateTime} based on this date-time with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public OffsetDateTime minus(TemporalSubtractor subtractor) {
-        return (OffsetDateTime) subtractor.subtractFrom(this);
+    public OffsetDateTime minus(TemporalAmount amountToSubtract) {
+        return (OffsetDateTime) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * Returns a copy of this date-time with the specified period subtracted.
+     * Returns a copy of this date-time with the specified amount subtracted.
      * <p>
-     * This method returns a new date-time based on this date-time with the specified period subtracted.
-     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
-     * 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 OffsetDateTime}, 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 OffsetDateTime} based on this date-time with the specified period subtracted, not null
+     * @param unit  the unit of the amount to subtract, not null
+     * @return an {@code OffsetDateTime} based on this date-time with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
     }

@@ -1411,18 +1451,26 @@
      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
      */
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) getDate().getChrono();
+        if (query == Queries.offset() || query == Queries.zone()) {
+            return (R) getOffset();
+        } else if (query == Queries.zoneId()) {
+            return null;
+        } else if (query == Queries.localDate()) {
+            return (R) toLocalDate();
+        } else if (query == Queries.localTime()) {
+            return (R) toLocalTime();
+        } else if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } 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, date
      * and time as this object.

@@ -1451,12 +1499,12 @@
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
         return temporal
                 .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
-                .with(EPOCH_DAY, getDate().toEpochDay())
-                .with(NANO_OF_DAY, getTime().toNanoOfDay());
+                .with(EPOCH_DAY, toLocalDate().toEpochDay())
+                .with(NANO_OF_DAY, toLocalTime().toNanoOfDay());
     }
 
     /**
      * Calculates the period between this date-time and another date-time in
      * terms of the specified unit.

@@ -1474,18 +1522,19 @@
      * The calculation returns a whole number, representing the number of
      * complete units between the two date-times.
      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
      * will only be one month as it is one minute short of two months.
      * <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, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, MONTHS);
+     *   amount = MONTHS.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}, {@code DAYS},
      * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},

@@ -1514,36 +1563,39 @@
         if (unit instanceof ChronoUnit) {
             OffsetDateTime end = (OffsetDateTime) endDateTime;
             end = end.withOffsetSameInstant(offset);
             return dateTime.periodUntil(end.dateTime, unit);
         }
-        return unit.between(this, endDateTime).getAmount();
+        return unit.between(this, endDateTime);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a zoned date-time formed from the instant represented by this
-     * date-time and the specified zone ID.
+     * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
+     * ensuring that the result has the same instant.
      * <p>
+     * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
      * This conversion will ignore the visible local date-time and use the underlying instant instead.
      * This avoids any problems with local time-line gaps or overlaps.
      * The result might have different values for fields such as hour, minute an even day.
      * <p>
      * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}.
      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date-time, not null
      */
     public ZonedDateTime atZoneSameInstant(ZoneId zone) {
         return ZonedDateTime.ofInstant(dateTime, offset, zone);
     }
 
     /**
-     * Returns a zoned date-time formed from this date-time and the specified zone ID.
+     * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
+     * trying to keep the same local date and time.
+     * <p>
+     * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
+     * Where possible, the result will have the same local date-time as this object.
      * <p>
      * Time-zone rules, such as daylight savings, mean that not every time on the
      * local time-line exists. If the local date-time is in a gap or overlap according to
      * the rules then a resolver is used to determine the resultant local time and offset.
      * This method uses {@link ZonedDateTime#ofLocal(LocalDateTime, ZoneId, ZoneOffset)}

@@ -1554,41 +1606,28 @@
      * {@link ZonedDateTime#withLaterOffsetAtOverlap()} immediately after this method.
      * <p>
      * To create a zoned date-time at the same instant irrespective of the local time-line,
      * use {@link #atZoneSameInstant(ZoneId)}.
      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param zone  the time-zone to use, not null
      * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
      */
     public ZonedDateTime atZoneSimilarLocal(ZoneId zone) {
         return ZonedDateTime.ofLocal(dateTime, zone, offset);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Converts this date-time to an {@code OffsetDate}.
-     * <p>
-     * This returns an offset date with the same local date and offset.
-     *
-     * @return an OffsetDate representing the date and offset, not null
-     */
-    public OffsetDate toOffsetDate() {
-        return OffsetDate.of(dateTime.getDate(), offset);
-    }
-
-    /**
      * Converts this date-time to an {@code OffsetTime}.
      * <p>
      * This returns an offset time with the same local time and offset.
      *
      * @return an OffsetTime representing the time and offset, not null
      */
     public OffsetTime toOffsetTime() {
-        return OffsetTime.of(dateTime.getTime(), offset);
+        return OffsetTime.of(dateTime.toLocalTime(), offset);
     }
 
     /**
      * Converts this date-time to a {@code ZonedDateTime} using the offset as the zone ID.
      * <p>

@@ -1604,10 +1643,13 @@
         return ZonedDateTime.of(dateTime, offset);
     }
 
     /**
      * Converts this date-time to an {@code Instant}.
+     * <p>
+     * This returns an {@code Instant} representing the same point on the
+     * time-line as this date-time.
      *
      * @return an {@code Instant} representing the same instant, not null
      */
     public Instant toInstant() {
         return dateTime.toInstant(offset);

@@ -1651,17 +1693,17 @@
      * @return the comparator value, negative if less, positive if greater
      */
     @Override
     public int compareTo(OffsetDateTime other) {
         if (getOffset().equals(other.getOffset())) {
-            return getDateTime().compareTo(other.getDateTime());
+            return toLocalDateTime().compareTo(other.toLocalDateTime());
         }
         int cmp = Long.compare(toEpochSecond(), other.toEpochSecond());
         if (cmp == 0) {
-            cmp = getTime().getNano() - other.getTime().getNano();
+            cmp = toLocalTime().getNano() - other.toLocalTime().getNano();
             if (cmp == 0) {
-                cmp = getDateTime().compareTo(other.getDateTime());
+                cmp = toLocalDateTime().compareTo(other.toLocalDateTime());
             }
         }
         return cmp;
     }
 

@@ -1678,11 +1720,11 @@
      */
     public boolean isAfter(OffsetDateTime other) {
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec > otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() > other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano());
     }
 
     /**
      * Checks if the instant of this date-time is before that of the specified date-time.
      * <p>

@@ -1695,11 +1737,11 @@
      */
     public boolean isBefore(OffsetDateTime other) {
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec < otherEpochSec ||
-            (thisEpochSec == otherEpochSec && getTime().getNano() < other.getTime().getNano());
+            (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano());
     }
 
     /**
      * Checks if the instant of this date-time is equal to that of the specified date-time.
      * <p>

@@ -1710,11 +1752,11 @@
      * @param other  the other date-time to compare to, not null
      * @return true if the instant equals the instant of the specified date-time
      */
     public boolean isEqual(OffsetDateTime other) {
         return toEpochSecond() == other.toEpochSecond() &&
-                getTime().getNano() == other.getTime().getNano();
+                toLocalTime().getNano() == other.toLocalTime().getNano();
     }
 
     //-----------------------------------------------------------------------
     /**
      * Checks if this date-time is equal to another date-time.

@@ -1772,27 +1814,27 @@
 
     /**
      * Outputs this date-time as a {@code String} using the formatter.
      * <p>
      * This date-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 date-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(3);  // identifies this as a OffsetDateTime
+     *  out.writeByte(10);  // identifies this as a OffsetDateTime
      *  out.writeObject(dateTime);
      *  out.writeObject(offset);
      * </pre>
      *
      * @return the instance of {@code Ser}, not null