jdk/src/share/classes/java/time/temporal/OffsetDateTime.java
changeset 15658 55b829ca2334
parent 15657 c588664d547e
child 15659 e575dab44ff5
equal deleted inserted replaced
15657:c588664d547e 15658:55b829ca2334
     1 /*
       
     2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 /*
       
    27  * This file is available under and governed by the GNU General Public
       
    28  * License version 2 only, as published by the Free Software Foundation.
       
    29  * However, the following notice accompanied the original version of this
       
    30  * file:
       
    31  *
       
    32  * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
       
    33  *
       
    34  * All rights reserved.
       
    35  *
       
    36  * Redistribution and use in source and binary forms, with or without
       
    37  * modification, are permitted provided that the following conditions are met:
       
    38  *
       
    39  *  * Redistributions of source code must retain the above copyright notice,
       
    40  *    this list of conditions and the following disclaimer.
       
    41  *
       
    42  *  * Redistributions in binary form must reproduce the above copyright notice,
       
    43  *    this list of conditions and the following disclaimer in the documentation
       
    44  *    and/or other materials provided with the distribution.
       
    45  *
       
    46  *  * Neither the name of JSR-310 nor the names of its contributors
       
    47  *    may be used to endorse or promote products derived from this software
       
    48  *    without specific prior written permission.
       
    49  *
       
    50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    54  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    55  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    56  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    57  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    58  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    61  */
       
    62 package java.time.temporal;
       
    63 
       
    64 import static java.time.temporal.ChronoField.EPOCH_DAY;
       
    65 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
       
    66 import static java.time.temporal.ChronoField.NANO_OF_DAY;
       
    67 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
       
    68 import static java.time.temporal.ChronoUnit.NANOS;
       
    69 
       
    70 import java.io.IOException;
       
    71 import java.io.InvalidObjectException;
       
    72 import java.io.ObjectInput;
       
    73 import java.io.ObjectOutput;
       
    74 import java.io.ObjectStreamException;
       
    75 import java.io.Serializable;
       
    76 import java.time.Clock;
       
    77 import java.time.DateTimeException;
       
    78 import java.time.DayOfWeek;
       
    79 import java.time.Instant;
       
    80 import java.time.LocalDate;
       
    81 import java.time.LocalDateTime;
       
    82 import java.time.LocalTime;
       
    83 import java.time.Month;
       
    84 import java.time.ZoneId;
       
    85 import java.time.ZoneOffset;
       
    86 import java.time.ZonedDateTime;
       
    87 import java.time.format.DateTimeFormatter;
       
    88 import java.time.format.DateTimeFormatters;
       
    89 import java.time.format.DateTimeParseException;
       
    90 import java.time.zone.ZoneRules;
       
    91 import java.util.Comparator;
       
    92 import java.util.Objects;
       
    93 
       
    94 /**
       
    95  * A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system,
       
    96  * such as {@code 2007-12-03T10:15:30+01:00}.
       
    97  * <p>
       
    98  * {@code OffsetDateTime} is an immutable representation of a date-time with an offset.
       
    99  * This class stores all date and time fields, to a precision of nanoseconds,
       
   100  * as well as the offset from UTC/Greenwich. For example, the value
       
   101  * "2nd October 2007 at 13:45.30.123456789 +02:00" can be stored in an {@code OffsetDateTime}.
       
   102  * <p>
       
   103  * {@code OffsetDateTime}, {@link java.time.ZonedDateTime} and {@link java.time.Instant} all store an instant
       
   104  * on the time-line to nanosecond precision.
       
   105  * {@code Instant} is the simplest, simply representing the instant.
       
   106  * {@code OffsetDateTime} adds to the instant the offset from UTC/Greenwich, which allows
       
   107  * the local date-time to be obtained.
       
   108  * {@code ZonedDateTime} adds full time-zone rules.
       
   109  * <p>
       
   110  * It is intended that {@code ZonedDateTime} or {@code Instant} is used to model data
       
   111  * in simpler applications. This class may be used when modeling date-time concepts in
       
   112  * more detail, or when communicating to a database or in a network protocol.
       
   113  *
       
   114  * <h3>Specification for implementors</h3>
       
   115  * This class is immutable and thread-safe.
       
   116  *
       
   117  * @since 1.8
       
   118  */
       
   119 public final class OffsetDateTime
       
   120         implements Temporal, TemporalAdjuster, Comparable<OffsetDateTime>, Serializable {
       
   121 
       
   122     /**
       
   123      * The minimum supported {@code OffsetDateTime}, '-999999999-01-01T00:00:00+18:00'.
       
   124      * This is the local date-time of midnight at the start of the minimum date
       
   125      * in the maximum offset (larger offsets are earlier on the time-line).
       
   126      * This combines {@link LocalDateTime#MIN} and {@link ZoneOffset#MAX}.
       
   127      * This could be used by an application as a "far past" date-time.
       
   128      */
       
   129     public static final OffsetDateTime MIN = LocalDateTime.MIN.atOffset(ZoneOffset.MAX);
       
   130     /**
       
   131      * The maximum supported {@code OffsetDateTime}, '+999999999-12-31T23:59:59.999999999-18:00'.
       
   132      * This is the local date-time just before midnight at the end of the maximum date
       
   133      * in the minimum offset (larger negative offsets are later on the time-line).
       
   134      * This combines {@link LocalDateTime#MAX} and {@link ZoneOffset#MIN}.
       
   135      * This could be used by an application as a "far future" date-time.
       
   136      */
       
   137     public static final OffsetDateTime MAX = LocalDateTime.MAX.atOffset(ZoneOffset.MIN);
       
   138 
       
   139     /**
       
   140      * Comparator for two {@code OffsetDateTime} instances based solely on the instant.
       
   141      * <p>
       
   142      * This method differs from the comparison in {@link #compareTo} in that it
       
   143      * only compares the underlying instant.
       
   144      *
       
   145      * @see #isAfter
       
   146      * @see #isBefore
       
   147      * @see #isEqual
       
   148      */
       
   149     public static final Comparator<OffsetDateTime> INSTANT_COMPARATOR = new Comparator<OffsetDateTime>() {
       
   150         @Override
       
   151         public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) {
       
   152             int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
       
   153             if (cmp == 0) {
       
   154                 cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
       
   155             }
       
   156             return cmp;
       
   157         }
       
   158     };
       
   159 
       
   160     /**
       
   161      * Serialization version.
       
   162      */
       
   163     private static final long serialVersionUID = 2287754244819255394L;
       
   164 
       
   165     /**
       
   166      * The local date-time.
       
   167      */
       
   168     private final LocalDateTime dateTime;
       
   169     /**
       
   170      * The offset from UTC/Greenwich.
       
   171      */
       
   172     private final ZoneOffset offset;
       
   173 
       
   174     //-----------------------------------------------------------------------
       
   175     /**
       
   176      * Obtains the current date-time from the system clock in the default time-zone.
       
   177      * <p>
       
   178      * This will query the {@link java.time.Clock#systemDefaultZone() system clock} in the default
       
   179      * time-zone to obtain the current date-time.
       
   180      * The offset will be calculated from the time-zone in the clock.
       
   181      * <p>
       
   182      * Using this method will prevent the ability to use an alternate clock for testing
       
   183      * because the clock is hard-coded.
       
   184      *
       
   185      * @return the current date-time using the system clock, not null
       
   186      */
       
   187     public static OffsetDateTime now() {
       
   188         return now(Clock.systemDefaultZone());
       
   189     }
       
   190 
       
   191     /**
       
   192      * Obtains the current date-time from the system clock in the specified time-zone.
       
   193      * <p>
       
   194      * This will query the {@link Clock#system(java.time.ZoneId) system clock} to obtain the current date-time.
       
   195      * Specifying the time-zone avoids dependence on the default time-zone.
       
   196      * The offset will be calculated from the specified time-zone.
       
   197      * <p>
       
   198      * Using this method will prevent the ability to use an alternate clock for testing
       
   199      * because the clock is hard-coded.
       
   200      *
       
   201      * @param zone  the zone ID to use, not null
       
   202      * @return the current date-time using the system clock, not null
       
   203      */
       
   204     public static OffsetDateTime now(ZoneId zone) {
       
   205         return now(Clock.system(zone));
       
   206     }
       
   207 
       
   208     /**
       
   209      * Obtains the current date-time from the specified clock.
       
   210      * <p>
       
   211      * This will query the specified clock to obtain the current date-time.
       
   212      * The offset will be calculated from the time-zone in the clock.
       
   213      * <p>
       
   214      * Using this method allows the use of an alternate clock for testing.
       
   215      * The alternate clock may be introduced using {@link Clock dependency injection}.
       
   216      *
       
   217      * @param clock  the clock to use, not null
       
   218      * @return the current date-time, not null
       
   219      */
       
   220     public static OffsetDateTime now(Clock clock) {
       
   221         Objects.requireNonNull(clock, "clock");
       
   222         final Instant now = clock.instant();  // called once
       
   223         return ofInstant(now, clock.getZone().getRules().getOffset(now));
       
   224     }
       
   225 
       
   226     //-----------------------------------------------------------------------
       
   227     /**
       
   228      * Obtains an instance of {@code OffsetDateTime} from a date, time and offset.
       
   229      * <p>
       
   230      * This creates an offset date-time with the specified local date, time and offset.
       
   231      *
       
   232      * @param date  the local date, not null
       
   233      * @param time  the local time, not null
       
   234      * @param offset  the zone offset, not null
       
   235      * @return the offset date-time, not null
       
   236      */
       
   237     public static OffsetDateTime of(LocalDate date, LocalTime time, ZoneOffset offset) {
       
   238         LocalDateTime dt = LocalDateTime.of(date, time);
       
   239         return new OffsetDateTime(dt, offset);
       
   240     }
       
   241 
       
   242     /**
       
   243      * Obtains an instance of {@code OffsetDateTime} from a date-time and offset.
       
   244      * <p>
       
   245      * This creates an offset date-time with the specified local date-time and offset.
       
   246      *
       
   247      * @param dateTime  the local date-time, not null
       
   248      * @param offset  the zone offset, not null
       
   249      * @return the offset date-time, not null
       
   250      */
       
   251     public static OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset) {
       
   252         return new OffsetDateTime(dateTime, offset);
       
   253     }
       
   254 
       
   255     /**
       
   256      * Obtains an instance of {@code OffsetDateTime} from a {@code ZonedDateTime}.
       
   257      * <p>
       
   258      * This creates an offset date-time with the same local date-time and offset as
       
   259      * the zoned date-time. The result will have the same instant as the input.
       
   260      *
       
   261      * @param zonedDateTime  the zoned date-time to convert from, not null
       
   262      * @return the offset date-time, not null
       
   263      * @throws DateTimeException if the result exceeds the supported range
       
   264      */
       
   265     public static OffsetDateTime of(ZonedDateTime zonedDateTime) {
       
   266         Objects.requireNonNull(zonedDateTime, "zonedDateTime");
       
   267         return new OffsetDateTime(zonedDateTime.getDateTime(), zonedDateTime.getOffset());
       
   268     }
       
   269 
       
   270     //-----------------------------------------------------------------------
       
   271     /**
       
   272      * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID.
       
   273      * <p>
       
   274      * This creates an offset date-time with the same instant as that specified.
       
   275      * Finding the offset from UTC/Greenwich is simple as there is only one valid
       
   276      * offset for each instant.
       
   277      *
       
   278      * @param instant  the instant to create the date-time from, not null
       
   279      * @param zone  the time-zone, which may be an offset, not null
       
   280      * @return the offset date-time, not null
       
   281      * @throws DateTimeException if the result exceeds the supported range
       
   282      */
       
   283     public static OffsetDateTime ofInstant(Instant instant, ZoneId zone) {
       
   284         Objects.requireNonNull(instant, "instant");
       
   285         Objects.requireNonNull(zone, "zone");
       
   286         ZoneRules rules = zone.getRules();
       
   287         ZoneOffset offset = rules.getOffset(instant);
       
   288         LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset);
       
   289         return new OffsetDateTime(ldt, offset);
       
   290     }
       
   291 
       
   292     //-----------------------------------------------------------------------
       
   293     /**
       
   294      * Obtains an instance of {@code OffsetDateTime} from a temporal object.
       
   295      * <p>
       
   296      * A {@code TemporalAccessor} represents some form of date and time information.
       
   297      * This factory converts the arbitrary temporal object to an instance of {@code OffsetDateTime}.
       
   298      * <p>
       
   299      * The conversion extracts and combines {@code LocalDateTime} and {@code ZoneOffset}.
       
   300      * If that fails it will try to extract and combine {@code Instant} and {@code ZoneOffset}.
       
   301      * <p>
       
   302      * This method matches the signature of the functional interface {@link TemporalQuery}
       
   303      * allowing it to be used in queries via method reference, {@code OffsetDateTime::from}.
       
   304      *
       
   305      * @param temporal  the temporal object to convert, not null
       
   306      * @return the offset date-time, not null
       
   307      * @throws DateTimeException if unable to convert to an {@code OffsetDateTime}
       
   308      */
       
   309     public static OffsetDateTime from(TemporalAccessor temporal) {
       
   310         if (temporal instanceof OffsetDateTime) {
       
   311             return (OffsetDateTime) temporal;
       
   312         }
       
   313         ZoneOffset offset = ZoneOffset.from(temporal);
       
   314         try {
       
   315             try {
       
   316                 LocalDateTime ldt = LocalDateTime.from(temporal);
       
   317                 return OffsetDateTime.of(ldt, offset);
       
   318             } catch (DateTimeException ignore) {
       
   319                 Instant instant = Instant.from(temporal);
       
   320                 return OffsetDateTime.ofInstant(instant, offset);
       
   321             }
       
   322         } catch (DateTimeException ex) {
       
   323             throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " + temporal.getClass(), ex);
       
   324         }
       
   325     }
       
   326 
       
   327     //-----------------------------------------------------------------------
       
   328     /**
       
   329      * Obtains an instance of {@code OffsetDateTime} from a text string
       
   330      * such as {@code 2007-12-03T10:15:30+01:00}.
       
   331      * <p>
       
   332      * The string must represent a valid date-time and is parsed using
       
   333      * {@link java.time.format.DateTimeFormatters#isoOffsetDateTime()}.
       
   334      *
       
   335      * @param text  the text to parse such as "2007-12-03T10:15:30+01:00", not null
       
   336      * @return the parsed offset date-time, not null
       
   337      * @throws DateTimeParseException if the text cannot be parsed
       
   338      */
       
   339     public static OffsetDateTime parse(CharSequence text) {
       
   340         return parse(text, DateTimeFormatters.isoOffsetDateTime());
       
   341     }
       
   342 
       
   343     /**
       
   344      * Obtains an instance of {@code OffsetDateTime} from a text string using a specific formatter.
       
   345      * <p>
       
   346      * The text is parsed using the formatter, returning a date-time.
       
   347      *
       
   348      * @param text  the text to parse, not null
       
   349      * @param formatter  the formatter to use, not null
       
   350      * @return the parsed offset date-time, not null
       
   351      * @throws DateTimeParseException if the text cannot be parsed
       
   352      */
       
   353     public static OffsetDateTime parse(CharSequence text, DateTimeFormatter formatter) {
       
   354         Objects.requireNonNull(formatter, "formatter");
       
   355         return formatter.parse(text, OffsetDateTime::from);
       
   356     }
       
   357 
       
   358     //-----------------------------------------------------------------------
       
   359     /**
       
   360      * Constructor.
       
   361      *
       
   362      * @param dateTime  the local date-time, not null
       
   363      * @param offset  the zone offset, not null
       
   364      */
       
   365     private OffsetDateTime(LocalDateTime dateTime, ZoneOffset offset) {
       
   366         this.dateTime = Objects.requireNonNull(dateTime, "dateTime");
       
   367         this.offset = Objects.requireNonNull(offset, "offset");
       
   368     }
       
   369 
       
   370     /**
       
   371      * Returns a new date-time based on this one, returning {@code this} where possible.
       
   372      *
       
   373      * @param dateTime  the date-time to create with, not null
       
   374      * @param offset  the zone offset to create with, not null
       
   375      */
       
   376     private OffsetDateTime with(LocalDateTime dateTime, ZoneOffset offset) {
       
   377         if (this.dateTime == dateTime && this.offset.equals(offset)) {
       
   378             return this;
       
   379         }
       
   380         return new OffsetDateTime(dateTime, offset);
       
   381     }
       
   382 
       
   383     //-----------------------------------------------------------------------
       
   384     /**
       
   385      * Checks if the specified field is supported.
       
   386      * <p>
       
   387      * This checks if this date-time can be queried for the specified field.
       
   388      * If false, then calling the {@link #range(TemporalField) range} and
       
   389      * {@link #get(TemporalField) get} methods will throw an exception.
       
   390      * <p>
       
   391      * If the field is a {@link ChronoField} then the query is implemented here.
       
   392      * The supported fields are:
       
   393      * <ul>
       
   394      * <li>{@code NANO_OF_SECOND}
       
   395      * <li>{@code NANO_OF_DAY}
       
   396      * <li>{@code MICRO_OF_SECOND}
       
   397      * <li>{@code MICRO_OF_DAY}
       
   398      * <li>{@code MILLI_OF_SECOND}
       
   399      * <li>{@code MILLI_OF_DAY}
       
   400      * <li>{@code SECOND_OF_MINUTE}
       
   401      * <li>{@code SECOND_OF_DAY}
       
   402      * <li>{@code MINUTE_OF_HOUR}
       
   403      * <li>{@code MINUTE_OF_DAY}
       
   404      * <li>{@code HOUR_OF_AMPM}
       
   405      * <li>{@code CLOCK_HOUR_OF_AMPM}
       
   406      * <li>{@code HOUR_OF_DAY}
       
   407      * <li>{@code CLOCK_HOUR_OF_DAY}
       
   408      * <li>{@code AMPM_OF_DAY}
       
   409      * <li>{@code DAY_OF_WEEK}
       
   410      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
       
   411      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
       
   412      * <li>{@code DAY_OF_MONTH}
       
   413      * <li>{@code DAY_OF_YEAR}
       
   414      * <li>{@code EPOCH_DAY}
       
   415      * <li>{@code ALIGNED_WEEK_OF_MONTH}
       
   416      * <li>{@code ALIGNED_WEEK_OF_YEAR}
       
   417      * <li>{@code MONTH_OF_YEAR}
       
   418      * <li>{@code EPOCH_MONTH}
       
   419      * <li>{@code YEAR_OF_ERA}
       
   420      * <li>{@code YEAR}
       
   421      * <li>{@code ERA}
       
   422      * <li>{@code INSTANT_SECONDS}
       
   423      * <li>{@code OFFSET_SECONDS}
       
   424      * </ul>
       
   425      * All other {@code ChronoField} instances will return false.
       
   426      * <p>
       
   427      * If the field is not a {@code ChronoField}, then the result of this method
       
   428      * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
       
   429      * passing {@code this} as the argument.
       
   430      * Whether the field is supported is determined by the field.
       
   431      *
       
   432      * @param field  the field to check, null returns false
       
   433      * @return true if the field is supported on this date-time, false if not
       
   434      */
       
   435     @Override
       
   436     public boolean isSupported(TemporalField field) {
       
   437         return field instanceof ChronoField || (field != null && field.doIsSupported(this));
       
   438     }
       
   439 
       
   440     /**
       
   441      * Gets the range of valid values for the specified field.
       
   442      * <p>
       
   443      * The range object expresses the minimum and maximum valid values for a field.
       
   444      * This date-time is used to enhance the accuracy of the returned range.
       
   445      * If it is not possible to return the range, because the field is not supported
       
   446      * or for some other reason, an exception is thrown.
       
   447      * <p>
       
   448      * If the field is a {@link ChronoField} then the query is implemented here.
       
   449      * The {@link #isSupported(TemporalField) supported fields} will return
       
   450      * appropriate range instances.
       
   451      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
       
   452      * <p>
       
   453      * If the field is not a {@code ChronoField}, then the result of this method
       
   454      * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
       
   455      * passing {@code this} as the argument.
       
   456      * Whether the range can be obtained is determined by the field.
       
   457      *
       
   458      * @param field  the field to query the range for, not null
       
   459      * @return the range of valid values for the field, not null
       
   460      * @throws DateTimeException if the range for the field cannot be obtained
       
   461      */
       
   462     @Override
       
   463     public ValueRange range(TemporalField field) {
       
   464         if (field instanceof ChronoField) {
       
   465             if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) {
       
   466                 return field.range();
       
   467             }
       
   468             return dateTime.range(field);
       
   469         }
       
   470         return field.doRange(this);
       
   471     }
       
   472 
       
   473     /**
       
   474      * Gets the value of the specified field from this date-time as an {@code int}.
       
   475      * <p>
       
   476      * This queries this date-time for the value for the specified field.
       
   477      * The returned value will always be within the valid range of values for the field.
       
   478      * If it is not possible to return the value, because the field is not supported
       
   479      * or for some other reason, an exception is thrown.
       
   480      * <p>
       
   481      * If the field is a {@link ChronoField} then the query is implemented here.
       
   482      * The {@link #isSupported(TemporalField) supported fields} will return valid
       
   483      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
       
   484      * {@code EPOCH_DAY}, {@code EPOCH_MONTH} and {@code INSTANT_SECONDS} which are too
       
   485      * large to fit in an {@code int} and throw a {@code DateTimeException}.
       
   486      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
       
   487      * <p>
       
   488      * If the field is not a {@code ChronoField}, then the result of this method
       
   489      * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
       
   490      * passing {@code this} as the argument. Whether the value can be obtained,
       
   491      * and what the value represents, is determined by the field.
       
   492      *
       
   493      * @param field  the field to get, not null
       
   494      * @return the value for the field
       
   495      * @throws DateTimeException if a value for the field cannot be obtained
       
   496      * @throws ArithmeticException if numeric overflow occurs
       
   497      */
       
   498     @Override
       
   499     public int get(TemporalField field) {
       
   500         if (field instanceof ChronoField) {
       
   501             switch ((ChronoField) field) {
       
   502                 case INSTANT_SECONDS: throw new DateTimeException("Field too large for an int: " + field);
       
   503                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
       
   504             }
       
   505             return dateTime.get(field);
       
   506         }
       
   507         return Temporal.super.get(field);
       
   508     }
       
   509 
       
   510     /**
       
   511      * Gets the value of the specified field from this date-time as a {@code long}.
       
   512      * <p>
       
   513      * This queries this date-time for the value for the specified field.
       
   514      * If it is not possible to return the value, because the field is not supported
       
   515      * or for some other reason, an exception is thrown.
       
   516      * <p>
       
   517      * If the field is a {@link ChronoField} then the query is implemented here.
       
   518      * The {@link #isSupported(TemporalField) supported fields} will return valid
       
   519      * values based on this date-time.
       
   520      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
       
   521      * <p>
       
   522      * If the field is not a {@code ChronoField}, then the result of this method
       
   523      * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
       
   524      * passing {@code this} as the argument. Whether the value can be obtained,
       
   525      * and what the value represents, is determined by the field.
       
   526      *
       
   527      * @param field  the field to get, not null
       
   528      * @return the value for the field
       
   529      * @throws DateTimeException if a value for the field cannot be obtained
       
   530      * @throws ArithmeticException if numeric overflow occurs
       
   531      */
       
   532     @Override
       
   533     public long getLong(TemporalField field) {
       
   534         if (field instanceof ChronoField) {
       
   535             switch ((ChronoField) field) {
       
   536                 case INSTANT_SECONDS: return toEpochSecond();
       
   537                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
       
   538             }
       
   539             return dateTime.getLong(field);
       
   540         }
       
   541         return field.doGet(this);
       
   542     }
       
   543 
       
   544     //-----------------------------------------------------------------------
       
   545     /**
       
   546      * Gets the zone offset, such as '+01:00'.
       
   547      * <p>
       
   548      * This is the offset of the local date-time from UTC/Greenwich.
       
   549      *
       
   550      * @return the zone offset, not null
       
   551      */
       
   552     public ZoneOffset getOffset() {
       
   553         return offset;
       
   554     }
       
   555 
       
   556     /**
       
   557      * Returns a copy of this {@code OffsetDateTime} with the specified offset ensuring
       
   558      * that the result has the same local date-time.
       
   559      * <p>
       
   560      * This method returns an object with the same {@code LocalDateTime} and the specified {@code ZoneOffset}.
       
   561      * No calculation is needed or performed.
       
   562      * For example, if this time represents {@code 2007-12-03T10:30+02:00} and the offset specified is
       
   563      * {@code +03:00}, then this method will return {@code 2007-12-03T10:30+03:00}.
       
   564      * <p>
       
   565      * To take into account the difference between the offsets, and adjust the time fields,
       
   566      * use {@link #withOffsetSameInstant}.
       
   567      * <p>
       
   568      * This instance is immutable and unaffected by this method call.
       
   569      *
       
   570      * @param offset  the zone offset to change to, not null
       
   571      * @return an {@code OffsetDateTime} based on this date-time with the requested offset, not null
       
   572      */
       
   573     public OffsetDateTime withOffsetSameLocal(ZoneOffset offset) {
       
   574         return with(dateTime, offset);
       
   575     }
       
   576 
       
   577     /**
       
   578      * Returns a copy of this {@code OffsetDateTime} with the specified offset ensuring
       
   579      * that the result is at the same instant.
       
   580      * <p>
       
   581      * This method returns an object with the specified {@code ZoneOffset} and a {@code LocalDateTime}
       
   582      * adjusted by the difference between the two offsets.
       
   583      * This will result in the old and new objects representing the same instant.
       
   584      * This is useful for finding the local time in a different offset.
       
   585      * For example, if this time represents {@code 2007-12-03T10:30+02:00} and the offset specified is
       
   586      * {@code +03:00}, then this method will return {@code 2007-12-03T11:30+03:00}.
       
   587      * <p>
       
   588      * To change the offset without adjusting the local time use {@link #withOffsetSameLocal}.
       
   589      * <p>
       
   590      * This instance is immutable and unaffected by this method call.
       
   591      *
       
   592      * @param offset  the zone offset to change to, not null
       
   593      * @return an {@code OffsetDateTime} based on this date-time with the requested offset, not null
       
   594      * @throws DateTimeException if the result exceeds the supported date range
       
   595      */
       
   596     public OffsetDateTime withOffsetSameInstant(ZoneOffset offset) {
       
   597         if (offset.equals(this.offset)) {
       
   598             return this;
       
   599         }
       
   600         int difference = offset.getTotalSeconds() - this.offset.getTotalSeconds();
       
   601         LocalDateTime adjusted = dateTime.plusSeconds(difference);
       
   602         return new OffsetDateTime(adjusted, offset);
       
   603     }
       
   604 
       
   605     //-----------------------------------------------------------------------
       
   606     /**
       
   607      * Gets the {@code LocalDateTime} part of this offset date-time.
       
   608      * <p>
       
   609      * This returns a {@code LocalDateTime} with the same year, month, day and time
       
   610      * as this date-time.
       
   611      *
       
   612      * @return the local date-time part of this date-time, not null
       
   613      */
       
   614     public LocalDateTime getDateTime() {
       
   615         return dateTime;
       
   616     }
       
   617 
       
   618     //-----------------------------------------------------------------------
       
   619     /**
       
   620      * Gets the {@code LocalDate} part of this date-time.
       
   621      * <p>
       
   622      * This returns a {@code LocalDate} with the same year, month and day
       
   623      * as this date-time.
       
   624      *
       
   625      * @return the date part of this date-time, not null
       
   626      */
       
   627     public LocalDate getDate() {
       
   628         return dateTime.getDate();
       
   629     }
       
   630 
       
   631     /**
       
   632      * Gets the year field.
       
   633      * <p>
       
   634      * This method returns the primitive {@code int} value for the year.
       
   635      * <p>
       
   636      * The year returned by this method is proleptic as per {@code get(YEAR)}.
       
   637      * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
       
   638      *
       
   639      * @return the year, from MIN_YEAR to MAX_YEAR
       
   640      */
       
   641     public int getYear() {
       
   642         return dateTime.getYear();
       
   643     }
       
   644 
       
   645     /**
       
   646      * Gets the month-of-year field from 1 to 12.
       
   647      * <p>
       
   648      * This method returns the month as an {@code int} from 1 to 12.
       
   649      * Application code is frequently clearer if the enum {@link Month}
       
   650      * is used by calling {@link #getMonth()}.
       
   651      *
       
   652      * @return the month-of-year, from 1 to 12
       
   653      * @see #getMonth()
       
   654      */
       
   655     public int getMonthValue() {
       
   656         return dateTime.getMonthValue();
       
   657     }
       
   658 
       
   659     /**
       
   660      * Gets the month-of-year field using the {@code Month} enum.
       
   661      * <p>
       
   662      * This method returns the enum {@link Month} for the month.
       
   663      * This avoids confusion as to what {@code int} values mean.
       
   664      * If you need access to the primitive {@code int} value then the enum
       
   665      * provides the {@link Month#getValue() int value}.
       
   666      *
       
   667      * @return the month-of-year, not null
       
   668      * @see #getMonthValue()
       
   669      */
       
   670     public Month getMonth() {
       
   671         return dateTime.getMonth();
       
   672     }
       
   673 
       
   674     /**
       
   675      * Gets the day-of-month field.
       
   676      * <p>
       
   677      * This method returns the primitive {@code int} value for the day-of-month.
       
   678      *
       
   679      * @return the day-of-month, from 1 to 31
       
   680      */
       
   681     public int getDayOfMonth() {
       
   682         return dateTime.getDayOfMonth();
       
   683     }
       
   684 
       
   685     /**
       
   686      * Gets the day-of-year field.
       
   687      * <p>
       
   688      * This method returns the primitive {@code int} value for the day-of-year.
       
   689      *
       
   690      * @return the day-of-year, from 1 to 365, or 366 in a leap year
       
   691      */
       
   692     public int getDayOfYear() {
       
   693         return dateTime.getDayOfYear();
       
   694     }
       
   695 
       
   696     /**
       
   697      * Gets the day-of-week field, which is an enum {@code DayOfWeek}.
       
   698      * <p>
       
   699      * This method returns the enum {@link java.time.DayOfWeek} for the day-of-week.
       
   700      * This avoids confusion as to what {@code int} values mean.
       
   701      * If you need access to the primitive {@code int} value then the enum
       
   702      * provides the {@link java.time.DayOfWeek#getValue() int value}.
       
   703      * <p>
       
   704      * Additional information can be obtained from the {@code DayOfWeek}.
       
   705      * This includes textual names of the values.
       
   706      *
       
   707      * @return the day-of-week, not null
       
   708      */
       
   709     public DayOfWeek getDayOfWeek() {
       
   710         return dateTime.getDayOfWeek();
       
   711     }
       
   712 
       
   713     //-----------------------------------------------------------------------
       
   714     /**
       
   715      * Gets the {@code LocalTime} part of this date-time.
       
   716      * <p>
       
   717      * This returns a {@code LocalTime} with the same hour, minute, second and
       
   718      * nanosecond as this date-time.
       
   719      *
       
   720      * @return the time part of this date-time, not null
       
   721      */
       
   722     public LocalTime getTime() {
       
   723         return dateTime.getTime();
       
   724     }
       
   725 
       
   726     /**
       
   727      * Gets the hour-of-day field.
       
   728      *
       
   729      * @return the hour-of-day, from 0 to 23
       
   730      */
       
   731     public int getHour() {
       
   732         return dateTime.getHour();
       
   733     }
       
   734 
       
   735     /**
       
   736      * Gets the minute-of-hour field.
       
   737      *
       
   738      * @return the minute-of-hour, from 0 to 59
       
   739      */
       
   740     public int getMinute() {
       
   741         return dateTime.getMinute();
       
   742     }
       
   743 
       
   744     /**
       
   745      * Gets the second-of-minute field.
       
   746      *
       
   747      * @return the second-of-minute, from 0 to 59
       
   748      */
       
   749     public int getSecond() {
       
   750         return dateTime.getSecond();
       
   751     }
       
   752 
       
   753     /**
       
   754      * Gets the nano-of-second field.
       
   755      *
       
   756      * @return the nano-of-second, from 0 to 999,999,999
       
   757      */
       
   758     public int getNano() {
       
   759         return dateTime.getNano();
       
   760     }
       
   761 
       
   762     //-----------------------------------------------------------------------
       
   763     /**
       
   764      * Returns an adjusted copy of this date-time.
       
   765      * <p>
       
   766      * This returns a new {@code OffsetDateTime}, based on this one, with the date-time adjusted.
       
   767      * The adjustment takes place using the specified adjuster strategy object.
       
   768      * Read the documentation of the adjuster to understand what adjustment will be made.
       
   769      * <p>
       
   770      * A simple adjuster might simply set the one of the fields, such as the year field.
       
   771      * A more complex adjuster might set the date to the last day of the month.
       
   772      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
       
   773      * These include finding the "last day of the month" and "next Wednesday".
       
   774      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
       
   775      * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}.
       
   776      * The adjuster is responsible for handling special cases, such as the varying
       
   777      * lengths of month and leap years.
       
   778      * <p>
       
   779      * For example this code returns a date on the last day of July:
       
   780      * <pre>
       
   781      *  import static java.time.Month.*;
       
   782      *  import static java.time.temporal.Adjusters.*;
       
   783      *
       
   784      *  result = offsetDateTime.with(JULY).with(lastDayOfMonth());
       
   785      * </pre>
       
   786      * <p>
       
   787      * The classes {@link LocalDate}, {@link LocalTime} and {@link ZoneOffset} implement
       
   788      * {@code TemporalAdjuster}, thus this method can be used to change the date, time or offset:
       
   789      * <pre>
       
   790      *  result = offsetDateTime.with(date);
       
   791      *  result = offsetDateTime.with(time);
       
   792      *  result = offsetDateTime.with(offset);
       
   793      * </pre>
       
   794      * <p>
       
   795      * The result of this method is obtained by invoking the
       
   796      * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
       
   797      * specified adjuster passing {@code this} as the argument.
       
   798      * <p>
       
   799      * This instance is immutable and unaffected by this method call.
       
   800      *
       
   801      * @param adjuster the adjuster to use, not null
       
   802      * @return an {@code OffsetDateTime} based on {@code this} with the adjustment made, not null
       
   803      * @throws DateTimeException if the adjustment cannot be made
       
   804      * @throws ArithmeticException if numeric overflow occurs
       
   805      */
       
   806     @Override
       
   807     public OffsetDateTime with(TemporalAdjuster adjuster) {
       
   808         // optimizations
       
   809         if (adjuster instanceof LocalDate || adjuster instanceof LocalTime || adjuster instanceof LocalDateTime) {
       
   810             return with(dateTime.with(adjuster), offset);
       
   811         } else if (adjuster instanceof Instant) {
       
   812             return ofInstant((Instant) adjuster, offset);
       
   813         } else if (adjuster instanceof ZoneOffset) {
       
   814             return with(dateTime, (ZoneOffset) adjuster);
       
   815         } else if (adjuster instanceof OffsetDateTime) {
       
   816             return (OffsetDateTime) adjuster;
       
   817         }
       
   818         return (OffsetDateTime) adjuster.adjustInto(this);
       
   819     }
       
   820 
       
   821     /**
       
   822      * Returns a copy of this date-time with the specified field set to a new value.
       
   823      * <p>
       
   824      * This returns a new {@code OffsetDateTime}, based on this one, with the value
       
   825      * for the specified field changed.
       
   826      * This can be used to change any supported field, such as the year, month or day-of-month.
       
   827      * If it is not possible to set the value, because the field is not supported or for
       
   828      * some other reason, an exception is thrown.
       
   829      * <p>
       
   830      * In some cases, changing the specified field can cause the resulting date-time to become invalid,
       
   831      * such as changing the month from 31st January to February would make the day-of-month invalid.
       
   832      * In cases like this, the field is responsible for resolving the date. Typically it will choose
       
   833      * the previous valid date, which would be the last valid day of February in this example.
       
   834      * <p>
       
   835      * If the field is a {@link ChronoField} then the adjustment is implemented here.
       
   836      * <p>
       
   837      * The {@code INSTANT_SECONDS} field will return a date-time with the specified instant.
       
   838      * The offset and nano-of-second are unchanged.
       
   839      * If the new instant value is outside the valid range then a {@code DateTimeException} will be thrown.
       
   840      * <p>
       
   841      * The {@code OFFSET_SECONDS} field will return a date-time with the specified offset.
       
   842      * The local date-time is unaltered. If the new offset value is outside the valid range
       
   843      * then a {@code DateTimeException} will be thrown.
       
   844      * <p>
       
   845      * The other {@link #isSupported(TemporalField) supported fields} will behave as per
       
   846      * the matching method on {@link LocalDateTime#with(TemporalField, long) LocalDateTime}.
       
   847      * In this case, the offset is not part of the calculation and will be unchanged.
       
   848      * <p>
       
   849      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
       
   850      * <p>
       
   851      * If the field is not a {@code ChronoField}, then the result of this method
       
   852      * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
       
   853      * passing {@code this} as the argument. In this case, the field determines
       
   854      * whether and how to adjust the instant.
       
   855      * <p>
       
   856      * This instance is immutable and unaffected by this method call.
       
   857      *
       
   858      * @param field  the field to set in the result, not null
       
   859      * @param newValue  the new value of the field in the result
       
   860      * @return an {@code OffsetDateTime} based on {@code this} with the specified field set, not null
       
   861      * @throws DateTimeException if the field cannot be set
       
   862      * @throws ArithmeticException if numeric overflow occurs
       
   863      */
       
   864     @Override
       
   865     public OffsetDateTime with(TemporalField field, long newValue) {
       
   866         if (field instanceof ChronoField) {
       
   867             ChronoField f = (ChronoField) field;
       
   868             switch (f) {
       
   869                 case INSTANT_SECONDS: return ofInstant(Instant.ofEpochSecond(newValue, getNano()), offset);
       
   870                 case OFFSET_SECONDS: {
       
   871                     return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
       
   872                 }
       
   873             }
       
   874             return with(dateTime.with(field, newValue), offset);
       
   875         }
       
   876         return field.doWith(this, newValue);
       
   877     }
       
   878 
       
   879     //-----------------------------------------------------------------------
       
   880     /**
       
   881      * Returns a copy of this {@code OffsetDateTime} with the year altered.
       
   882      * The offset does not affect the calculation and will be the same in the result.
       
   883      * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
       
   884      * <p>
       
   885      * This instance is immutable and unaffected by this method call.
       
   886      *
       
   887      * @param year  the year to set in the result, from MIN_YEAR to MAX_YEAR
       
   888      * @return an {@code OffsetDateTime} based on this date-time with the requested year, not null
       
   889      * @throws DateTimeException if the year value is invalid
       
   890      */
       
   891     public OffsetDateTime withYear(int year) {
       
   892         return with(dateTime.withYear(year), offset);
       
   893     }
       
   894 
       
   895     /**
       
   896      * Returns a copy of this {@code OffsetDateTime} with the month-of-year altered.
       
   897      * The offset does not affect the calculation and will be the same in the result.
       
   898      * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
       
   899      * <p>
       
   900      * This instance is immutable and unaffected by this method call.
       
   901      *
       
   902      * @param month  the month-of-year to set in the result, from 1 (January) to 12 (December)
       
   903      * @return an {@code OffsetDateTime} based on this date-time with the requested month, not null
       
   904      * @throws DateTimeException if the month-of-year value is invalid
       
   905      */
       
   906     public OffsetDateTime withMonth(int month) {
       
   907         return with(dateTime.withMonth(month), offset);
       
   908     }
       
   909 
       
   910     /**
       
   911      * Returns a copy of this {@code OffsetDateTime} with the day-of-month altered.
       
   912      * If the resulting {@code OffsetDateTime} is invalid, an exception is thrown.
       
   913      * The offset does not affect the calculation and will be the same in the result.
       
   914      * <p>
       
   915      * This instance is immutable and unaffected by this method call.
       
   916      *
       
   917      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
       
   918      * @return an {@code OffsetDateTime} based on this date-time with the requested day, not null
       
   919      * @throws DateTimeException if the day-of-month value is invalid
       
   920      * @throws DateTimeException if the day-of-month is invalid for the month-year
       
   921      */
       
   922     public OffsetDateTime withDayOfMonth(int dayOfMonth) {
       
   923         return with(dateTime.withDayOfMonth(dayOfMonth), offset);
       
   924     }
       
   925 
       
   926     /**
       
   927      * Returns a copy of this {@code OffsetDateTime} with the day-of-year altered.
       
   928      * If the resulting {@code OffsetDateTime} is invalid, an exception is thrown.
       
   929      * <p>
       
   930      * This instance is immutable and unaffected by this method call.
       
   931      *
       
   932      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
       
   933      * @return an {@code OffsetDateTime} based on this date with the requested day, not null
       
   934      * @throws DateTimeException if the day-of-year value is invalid
       
   935      * @throws DateTimeException if the day-of-year is invalid for the year
       
   936      */
       
   937     public OffsetDateTime withDayOfYear(int dayOfYear) {
       
   938         return with(dateTime.withDayOfYear(dayOfYear), offset);
       
   939     }
       
   940 
       
   941     //-----------------------------------------------------------------------
       
   942     /**
       
   943      * Returns a copy of this {@code OffsetDateTime} with the hour-of-day value altered.
       
   944      * <p>
       
   945      * The offset does not affect the calculation and will be the same in the result.
       
   946      * <p>
       
   947      * This instance is immutable and unaffected by this method call.
       
   948      *
       
   949      * @param hour  the hour-of-day to set in the result, from 0 to 23
       
   950      * @return an {@code OffsetDateTime} based on this date-time with the requested hour, not null
       
   951      * @throws DateTimeException if the hour value is invalid
       
   952      */
       
   953     public OffsetDateTime withHour(int hour) {
       
   954         return with(dateTime.withHour(hour), offset);
       
   955     }
       
   956 
       
   957     /**
       
   958      * Returns a copy of this {@code OffsetDateTime} with the minute-of-hour value altered.
       
   959      * <p>
       
   960      * The offset does not affect the calculation and will be the same in the result.
       
   961      * <p>
       
   962      * This instance is immutable and unaffected by this method call.
       
   963      *
       
   964      * @param minute  the minute-of-hour to set in the result, from 0 to 59
       
   965      * @return an {@code OffsetDateTime} based on this date-time with the requested minute, not null
       
   966      * @throws DateTimeException if the minute value is invalid
       
   967      */
       
   968     public OffsetDateTime withMinute(int minute) {
       
   969         return with(dateTime.withMinute(minute), offset);
       
   970     }
       
   971 
       
   972     /**
       
   973      * Returns a copy of this {@code OffsetDateTime} with the second-of-minute value altered.
       
   974      * <p>
       
   975      * The offset does not affect the calculation and will be the same in the result.
       
   976      * <p>
       
   977      * This instance is immutable and unaffected by this method call.
       
   978      *
       
   979      * @param second  the second-of-minute to set in the result, from 0 to 59
       
   980      * @return an {@code OffsetDateTime} based on this date-time with the requested second, not null
       
   981      * @throws DateTimeException if the second value is invalid
       
   982      */
       
   983     public OffsetDateTime withSecond(int second) {
       
   984         return with(dateTime.withSecond(second), offset);
       
   985     }
       
   986 
       
   987     /**
       
   988      * Returns a copy of this {@code OffsetDateTime} with the nano-of-second value altered.
       
   989      * <p>
       
   990      * The offset does not affect the calculation and will be the same in the result.
       
   991      * <p>
       
   992      * This instance is immutable and unaffected by this method call.
       
   993      *
       
   994      * @param nanoOfSecond  the nano-of-second to set in the result, from 0 to 999,999,999
       
   995      * @return an {@code OffsetDateTime} based on this date-time with the requested nanosecond, not null
       
   996      * @throws DateTimeException if the nanos value is invalid
       
   997      */
       
   998     public OffsetDateTime withNano(int nanoOfSecond) {
       
   999         return with(dateTime.withNano(nanoOfSecond), offset);
       
  1000     }
       
  1001 
       
  1002     //-----------------------------------------------------------------------
       
  1003     /**
       
  1004      * Returns a copy of this {@code OffsetDateTime} with the time truncated.
       
  1005      * <p>
       
  1006      * Truncation returns a copy of the original date-time with fields
       
  1007      * smaller than the specified unit set to zero.
       
  1008      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
       
  1009      * will set the second-of-minute and nano-of-second field to zero.
       
  1010      * <p>
       
  1011      * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
       
  1012      * units with an exact duration can be used, other units throw an exception.
       
  1013      * <p>
       
  1014      * The offset does not affect the calculation and will be the same in the result.
       
  1015      * <p>
       
  1016      * This instance is immutable and unaffected by this method call.
       
  1017      *
       
  1018      * @param unit  the unit to truncate to, not null
       
  1019      * @return an {@code OffsetDateTime} based on this date-time with the time truncated, not null
       
  1020      * @throws DateTimeException if unable to truncate
       
  1021      */
       
  1022     public OffsetDateTime truncatedTo(TemporalUnit unit) {
       
  1023         return with(dateTime.truncatedTo(unit), offset);
       
  1024     }
       
  1025 
       
  1026     //-----------------------------------------------------------------------
       
  1027     /**
       
  1028      * Returns a copy of this date-time with the specified period added.
       
  1029      * <p>
       
  1030      * This method returns a new date-time based on this time with the specified period added.
       
  1031      * The adder is typically {@link java.time.Period} but may be any other type implementing
       
  1032      * the {@link TemporalAdder} interface.
       
  1033      * The calculation is delegated to the specified adjuster, which typically calls
       
  1034      * back to {@link #plus(long, TemporalUnit)}.
       
  1035      * The offset is not part of the calculation and will be unchanged in the result.
       
  1036      * <p>
       
  1037      * This instance is immutable and unaffected by this method call.
       
  1038      *
       
  1039      * @param adder  the adder to use, not null
       
  1040      * @return an {@code OffsetDateTime} based on this date-time with the addition made, not null
       
  1041      * @throws DateTimeException if the addition cannot be made
       
  1042      * @throws ArithmeticException if numeric overflow occurs
       
  1043      */
       
  1044     @Override
       
  1045     public OffsetDateTime plus(TemporalAdder adder) {
       
  1046         return (OffsetDateTime) adder.addTo(this);
       
  1047     }
       
  1048 
       
  1049     /**
       
  1050      * Returns a copy of this date-time with the specified period added.
       
  1051      * <p>
       
  1052      * This method returns a new date-time based on this date-time with the specified period added.
       
  1053      * This can be used to add any period that is defined by a unit, for example to add years, months or days.
       
  1054      * The unit is responsible for the details of the calculation, including the resolution
       
  1055      * of any edge cases in the calculation.
       
  1056      * The offset is not part of the calculation and will be unchanged in the result.
       
  1057      * <p>
       
  1058      * This instance is immutable and unaffected by this method call.
       
  1059      *
       
  1060      * @param amountToAdd  the amount of the unit to add to the result, may be negative
       
  1061      * @param unit  the unit of the period to add, not null
       
  1062      * @return an {@code OffsetDateTime} based on this date-time with the specified period added, not null
       
  1063      * @throws DateTimeException if the unit cannot be added to this type
       
  1064      */
       
  1065     @Override
       
  1066     public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) {
       
  1067         if (unit instanceof ChronoUnit) {
       
  1068             return with(dateTime.plus(amountToAdd, unit), offset);
       
  1069         }
       
  1070         return unit.doPlus(this, amountToAdd);
       
  1071     }
       
  1072 
       
  1073     //-----------------------------------------------------------------------
       
  1074     /**
       
  1075      * Returns a copy of this {@code OffsetDateTime} with the specified period in years added.
       
  1076      * <p>
       
  1077      * This method adds the specified amount to the years field in three steps:
       
  1078      * <ol>
       
  1079      * <li>Add the input years to the year field</li>
       
  1080      * <li>Check if the resulting date would be invalid</li>
       
  1081      * <li>Adjust the day-of-month to the last valid day if necessary</li>
       
  1082      * </ol>
       
  1083      * <p>
       
  1084      * For example, 2008-02-29 (leap year) plus one year would result in the
       
  1085      * invalid date 2009-02-29 (standard year). Instead of returning an invalid
       
  1086      * result, the last valid day of the month, 2009-02-28, is selected instead.
       
  1087      * <p>
       
  1088      * This instance is immutable and unaffected by this method call.
       
  1089      *
       
  1090      * @param years  the years to add, may be negative
       
  1091      * @return an {@code OffsetDateTime} based on this date-time with the years added, not null
       
  1092      * @throws DateTimeException if the result exceeds the supported date range
       
  1093      */
       
  1094     public OffsetDateTime plusYears(long years) {
       
  1095         return with(dateTime.plusYears(years), offset);
       
  1096     }
       
  1097 
       
  1098     /**
       
  1099      * Returns a copy of this {@code OffsetDateTime} with the specified period in months added.
       
  1100      * <p>
       
  1101      * This method adds the specified amount to the months field in three steps:
       
  1102      * <ol>
       
  1103      * <li>Add the input months to the month-of-year field</li>
       
  1104      * <li>Check if the resulting date would be invalid</li>
       
  1105      * <li>Adjust the day-of-month to the last valid day if necessary</li>
       
  1106      * </ol>
       
  1107      * <p>
       
  1108      * For example, 2007-03-31 plus one month would result in the invalid date
       
  1109      * 2007-04-31. Instead of returning an invalid result, the last valid day
       
  1110      * of the month, 2007-04-30, is selected instead.
       
  1111      * <p>
       
  1112      * This instance is immutable and unaffected by this method call.
       
  1113      *
       
  1114      * @param months  the months to add, may be negative
       
  1115      * @return an {@code OffsetDateTime} based on this date-time with the months added, not null
       
  1116      * @throws DateTimeException if the result exceeds the supported date range
       
  1117      */
       
  1118     public OffsetDateTime plusMonths(long months) {
       
  1119         return with(dateTime.plusMonths(months), offset);
       
  1120     }
       
  1121 
       
  1122     /**
       
  1123      * Returns a copy of this OffsetDateTime with the specified period in weeks added.
       
  1124      * <p>
       
  1125      * This method adds the specified amount in weeks to the days field incrementing
       
  1126      * the month and year fields as necessary to ensure the result remains valid.
       
  1127      * The result is only invalid if the maximum/minimum year is exceeded.
       
  1128      * <p>
       
  1129      * For example, 2008-12-31 plus one week would result in the 2009-01-07.
       
  1130      * <p>
       
  1131      * This instance is immutable and unaffected by this method call.
       
  1132      *
       
  1133      * @param weeks  the weeks to add, may be negative
       
  1134      * @return an {@code OffsetDateTime} based on this date-time with the weeks added, not null
       
  1135      * @throws DateTimeException if the result exceeds the supported date range
       
  1136      */
       
  1137     public OffsetDateTime plusWeeks(long weeks) {
       
  1138         return with(dateTime.plusWeeks(weeks), offset);
       
  1139     }
       
  1140 
       
  1141     /**
       
  1142      * Returns a copy of this OffsetDateTime with the specified period in days added.
       
  1143      * <p>
       
  1144      * This method adds the specified amount to the days field incrementing the
       
  1145      * month and year fields as necessary to ensure the result remains valid.
       
  1146      * The result is only invalid if the maximum/minimum year is exceeded.
       
  1147      * <p>
       
  1148      * For example, 2008-12-31 plus one day would result in the 2009-01-01.
       
  1149      * <p>
       
  1150      * This instance is immutable and unaffected by this method call.
       
  1151      *
       
  1152      * @param days  the days to add, may be negative
       
  1153      * @return an {@code OffsetDateTime} based on this date-time with the days added, not null
       
  1154      * @throws DateTimeException if the result exceeds the supported date range
       
  1155      */
       
  1156     public OffsetDateTime plusDays(long days) {
       
  1157         return with(dateTime.plusDays(days), offset);
       
  1158     }
       
  1159 
       
  1160     /**
       
  1161      * Returns a copy of this {@code OffsetDateTime} with the specified period in hours added.
       
  1162      * <p>
       
  1163      * This instance is immutable and unaffected by this method call.
       
  1164      *
       
  1165      * @param hours  the hours to add, may be negative
       
  1166      * @return an {@code OffsetDateTime} based on this date-time with the hours added, not null
       
  1167      * @throws DateTimeException if the result exceeds the supported date range
       
  1168      */
       
  1169     public OffsetDateTime plusHours(long hours) {
       
  1170         return with(dateTime.plusHours(hours), offset);
       
  1171     }
       
  1172 
       
  1173     /**
       
  1174      * Returns a copy of this {@code OffsetDateTime} with the specified period in minutes added.
       
  1175      * <p>
       
  1176      * This instance is immutable and unaffected by this method call.
       
  1177      *
       
  1178      * @param minutes  the minutes to add, may be negative
       
  1179      * @return an {@code OffsetDateTime} based on this date-time with the minutes added, not null
       
  1180      * @throws DateTimeException if the result exceeds the supported date range
       
  1181      */
       
  1182     public OffsetDateTime plusMinutes(long minutes) {
       
  1183         return with(dateTime.plusMinutes(minutes), offset);
       
  1184     }
       
  1185 
       
  1186     /**
       
  1187      * Returns a copy of this {@code OffsetDateTime} with the specified period in seconds added.
       
  1188      * <p>
       
  1189      * This instance is immutable and unaffected by this method call.
       
  1190      *
       
  1191      * @param seconds  the seconds to add, may be negative
       
  1192      * @return an {@code OffsetDateTime} based on this date-time with the seconds added, not null
       
  1193      * @throws DateTimeException if the result exceeds the supported date range
       
  1194      */
       
  1195     public OffsetDateTime plusSeconds(long seconds) {
       
  1196         return with(dateTime.plusSeconds(seconds), offset);
       
  1197     }
       
  1198 
       
  1199     /**
       
  1200      * Returns a copy of this {@code OffsetDateTime} with the specified period in nanoseconds added.
       
  1201      * <p>
       
  1202      * This instance is immutable and unaffected by this method call.
       
  1203      *
       
  1204      * @param nanos  the nanos to add, may be negative
       
  1205      * @return an {@code OffsetDateTime} based on this date-time with the nanoseconds added, not null
       
  1206      * @throws DateTimeException if the unit cannot be added to this type
       
  1207      */
       
  1208     public OffsetDateTime plusNanos(long nanos) {
       
  1209         return with(dateTime.plusNanos(nanos), offset);
       
  1210     }
       
  1211 
       
  1212     //-----------------------------------------------------------------------
       
  1213     /**
       
  1214      * Returns a copy of this date-time with the specified period subtracted.
       
  1215      * <p>
       
  1216      * This method returns a new date-time based on this time with the specified period subtracted.
       
  1217      * The subtractor is typically {@link java.time.Period} but may be any other type implementing
       
  1218      * the {@link TemporalSubtractor} interface.
       
  1219      * The calculation is delegated to the specified adjuster, which typically calls
       
  1220      * back to {@link #minus(long, TemporalUnit)}.
       
  1221      * The offset is not part of the calculation and will be unchanged in the result.
       
  1222      * <p>
       
  1223      * This instance is immutable and unaffected by this method call.
       
  1224      *
       
  1225      * @param subtractor  the subtractor to use, not null
       
  1226      * @return an {@code OffsetDateTime} based on this date-time with the subtraction made, not null
       
  1227      * @throws DateTimeException if the subtraction cannot be made
       
  1228      * @throws ArithmeticException if numeric overflow occurs
       
  1229      */
       
  1230     @Override
       
  1231     public OffsetDateTime minus(TemporalSubtractor subtractor) {
       
  1232         return (OffsetDateTime) subtractor.subtractFrom(this);
       
  1233     }
       
  1234 
       
  1235     /**
       
  1236      * Returns a copy of this date-time with the specified period subtracted.
       
  1237      * <p>
       
  1238      * This method returns a new date-time based on this date-time with the specified period subtracted.
       
  1239      * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
       
  1240      * The unit is responsible for the details of the calculation, including the resolution
       
  1241      * of any edge cases in the calculation.
       
  1242      * The offset is not part of the calculation and will be unchanged in the result.
       
  1243      * <p>
       
  1244      * This instance is immutable and unaffected by this method call.
       
  1245      *
       
  1246      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
       
  1247      * @param unit  the unit of the period to subtract, not null
       
  1248      * @return an {@code OffsetDateTime} based on this date-time with the specified period subtracted, not null
       
  1249      */
       
  1250     @Override
       
  1251     public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
       
  1252         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
       
  1253     }
       
  1254 
       
  1255     //-----------------------------------------------------------------------
       
  1256     /**
       
  1257      * Returns a copy of this {@code OffsetDateTime} with the specified period in years subtracted.
       
  1258      * <p>
       
  1259      * This method subtracts the specified amount from the years field in three steps:
       
  1260      * <ol>
       
  1261      * <li>Subtract the input years to the year field</li>
       
  1262      * <li>Check if the resulting date would be invalid</li>
       
  1263      * <li>Adjust the day-of-month to the last valid day if necessary</li>
       
  1264      * </ol>
       
  1265      * <p>
       
  1266      * For example, 2008-02-29 (leap year) minus one year would result in the
       
  1267      * invalid date 2009-02-29 (standard year). Instead of returning an invalid
       
  1268      * result, the last valid day of the month, 2009-02-28, is selected instead.
       
  1269      * <p>
       
  1270      * This instance is immutable and unaffected by this method call.
       
  1271      *
       
  1272      * @param years  the years to subtract, may be negative
       
  1273      * @return an {@code OffsetDateTime} based on this date-time with the years subtracted, not null
       
  1274      * @throws DateTimeException if the result exceeds the supported date range
       
  1275      */
       
  1276     public OffsetDateTime minusYears(long years) {
       
  1277         return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years));
       
  1278     }
       
  1279 
       
  1280     /**
       
  1281      * Returns a copy of this {@code OffsetDateTime} with the specified period in months subtracted.
       
  1282      * <p>
       
  1283      * This method subtracts the specified amount from the months field in three steps:
       
  1284      * <ol>
       
  1285      * <li>Subtract the input months to the month-of-year field</li>
       
  1286      * <li>Check if the resulting date would be invalid</li>
       
  1287      * <li>Adjust the day-of-month to the last valid day if necessary</li>
       
  1288      * </ol>
       
  1289      * <p>
       
  1290      * For example, 2007-03-31 minus one month would result in the invalid date
       
  1291      * 2007-04-31. Instead of returning an invalid result, the last valid day
       
  1292      * of the month, 2007-04-30, is selected instead.
       
  1293      * <p>
       
  1294      * This instance is immutable and unaffected by this method call.
       
  1295      *
       
  1296      * @param months  the months to subtract, may be negative
       
  1297      * @return an {@code OffsetDateTime} based on this date-time with the months subtracted, not null
       
  1298      * @throws DateTimeException if the result exceeds the supported date range
       
  1299      */
       
  1300     public OffsetDateTime minusMonths(long months) {
       
  1301         return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months));
       
  1302     }
       
  1303 
       
  1304     /**
       
  1305      * Returns a copy of this {@code OffsetDateTime} with the specified period in weeks subtracted.
       
  1306      * <p>
       
  1307      * This method subtracts the specified amount in weeks from the days field decrementing
       
  1308      * the month and year fields as necessary to ensure the result remains valid.
       
  1309      * The result is only invalid if the maximum/minimum year is exceeded.
       
  1310      * <p>
       
  1311      * For example, 2008-12-31 minus one week would result in the 2009-01-07.
       
  1312      * <p>
       
  1313      * This instance is immutable and unaffected by this method call.
       
  1314      *
       
  1315      * @param weeks  the weeks to subtract, may be negative
       
  1316      * @return an {@code OffsetDateTime} based on this date-time with the weeks subtracted, not null
       
  1317      * @throws DateTimeException if the result exceeds the supported date range
       
  1318      */
       
  1319     public OffsetDateTime minusWeeks(long weeks) {
       
  1320         return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks));
       
  1321     }
       
  1322 
       
  1323     /**
       
  1324      * Returns a copy of this {@code OffsetDateTime} with the specified period in days subtracted.
       
  1325      * <p>
       
  1326      * This method subtracts the specified amount from the days field incrementing the
       
  1327      * month and year fields as necessary to ensure the result remains valid.
       
  1328      * The result is only invalid if the maximum/minimum year is exceeded.
       
  1329      * <p>
       
  1330      * For example, 2008-12-31 minus one day would result in the 2009-01-01.
       
  1331      * <p>
       
  1332      * This instance is immutable and unaffected by this method call.
       
  1333      *
       
  1334      * @param days  the days to subtract, may be negative
       
  1335      * @return an {@code OffsetDateTime} based on this date-time with the days subtracted, not null
       
  1336      * @throws DateTimeException if the result exceeds the supported date range
       
  1337      */
       
  1338     public OffsetDateTime minusDays(long days) {
       
  1339         return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days));
       
  1340     }
       
  1341 
       
  1342     /**
       
  1343      * Returns a copy of this {@code OffsetDateTime} with the specified period in hours subtracted.
       
  1344      * <p>
       
  1345      * This instance is immutable and unaffected by this method call.
       
  1346      *
       
  1347      * @param hours  the hours to subtract, may be negative
       
  1348      * @return an {@code OffsetDateTime} based on this date-time with the hours subtracted, not null
       
  1349      * @throws DateTimeException if the result exceeds the supported date range
       
  1350      */
       
  1351     public OffsetDateTime minusHours(long hours) {
       
  1352         return (hours == Long.MIN_VALUE ? plusHours(Long.MAX_VALUE).plusHours(1) : plusHours(-hours));
       
  1353     }
       
  1354 
       
  1355     /**
       
  1356      * Returns a copy of this {@code OffsetDateTime} with the specified period in minutes subtracted.
       
  1357      * <p>
       
  1358      * This instance is immutable and unaffected by this method call.
       
  1359      *
       
  1360      * @param minutes  the minutes to subtract, may be negative
       
  1361      * @return an {@code OffsetDateTime} based on this date-time with the minutes subtracted, not null
       
  1362      * @throws DateTimeException if the result exceeds the supported date range
       
  1363      */
       
  1364     public OffsetDateTime minusMinutes(long minutes) {
       
  1365         return (minutes == Long.MIN_VALUE ? plusMinutes(Long.MAX_VALUE).plusMinutes(1) : plusMinutes(-minutes));
       
  1366     }
       
  1367 
       
  1368     /**
       
  1369      * Returns a copy of this {@code OffsetDateTime} with the specified period in seconds subtracted.
       
  1370      * <p>
       
  1371      * This instance is immutable and unaffected by this method call.
       
  1372      *
       
  1373      * @param seconds  the seconds to subtract, may be negative
       
  1374      * @return an {@code OffsetDateTime} based on this date-time with the seconds subtracted, not null
       
  1375      * @throws DateTimeException if the result exceeds the supported date range
       
  1376      */
       
  1377     public OffsetDateTime minusSeconds(long seconds) {
       
  1378         return (seconds == Long.MIN_VALUE ? plusSeconds(Long.MAX_VALUE).plusSeconds(1) : plusSeconds(-seconds));
       
  1379     }
       
  1380 
       
  1381     /**
       
  1382      * Returns a copy of this {@code OffsetDateTime} with the specified period in nanoseconds subtracted.
       
  1383      * <p>
       
  1384      * This instance is immutable and unaffected by this method call.
       
  1385      *
       
  1386      * @param nanos  the nanos to subtract, may be negative
       
  1387      * @return an {@code OffsetDateTime} based on this date-time with the nanoseconds subtracted, not null
       
  1388      * @throws DateTimeException if the result exceeds the supported date range
       
  1389      */
       
  1390     public OffsetDateTime minusNanos(long nanos) {
       
  1391         return (nanos == Long.MIN_VALUE ? plusNanos(Long.MAX_VALUE).plusNanos(1) : plusNanos(-nanos));
       
  1392     }
       
  1393 
       
  1394     //-----------------------------------------------------------------------
       
  1395     /**
       
  1396      * Queries this date-time using the specified query.
       
  1397      * <p>
       
  1398      * This queries this date-time using the specified query strategy object.
       
  1399      * The {@code TemporalQuery} object defines the logic to be used to
       
  1400      * obtain the result. Read the documentation of the query to understand
       
  1401      * what the result of this method will be.
       
  1402      * <p>
       
  1403      * The result of this method is obtained by invoking the
       
  1404      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
       
  1405      * specified query passing {@code this} as the argument.
       
  1406      *
       
  1407      * @param <R> the type of the result
       
  1408      * @param query  the query to invoke, not null
       
  1409      * @return the query result, null may be returned (defined by the query)
       
  1410      * @throws DateTimeException if unable to query (defined by the query)
       
  1411      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
       
  1412      */
       
  1413     @SuppressWarnings("unchecked")
       
  1414     @Override
       
  1415     public <R> R query(TemporalQuery<R> query) {
       
  1416         if (query == Queries.chrono()) {
       
  1417             return (R) getDate().getChrono();
       
  1418         } else if (query == Queries.precision()) {
       
  1419             return (R) NANOS;
       
  1420         } else if (query == Queries.offset() || query == Queries.zone()) {
       
  1421             return (R) getOffset();
       
  1422         }
       
  1423         return Temporal.super.query(query);
       
  1424     }
       
  1425 
       
  1426     /**
       
  1427      * Adjusts the specified temporal object to have the same offset, date
       
  1428      * and time as this object.
       
  1429      * <p>
       
  1430      * This returns a temporal object of the same observable type as the input
       
  1431      * with the offset, date and time changed to be the same as this.
       
  1432      * <p>
       
  1433      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
       
  1434      * three times, passing {@link ChronoField#OFFSET_SECONDS},
       
  1435      * {@link ChronoField#EPOCH_DAY} and {@link ChronoField#NANO_OF_DAY} as the fields.
       
  1436      * <p>
       
  1437      * In most cases, it is clearer to reverse the calling pattern by using
       
  1438      * {@link Temporal#with(TemporalAdjuster)}:
       
  1439      * <pre>
       
  1440      *   // these two lines are equivalent, but the second approach is recommended
       
  1441      *   temporal = thisOffsetDateTime.adjustInto(temporal);
       
  1442      *   temporal = temporal.with(thisOffsetDateTime);
       
  1443      * </pre>
       
  1444      * <p>
       
  1445      * This instance is immutable and unaffected by this method call.
       
  1446      *
       
  1447      * @param temporal  the target object to be adjusted, not null
       
  1448      * @return the adjusted object, not null
       
  1449      * @throws DateTimeException if unable to make the adjustment
       
  1450      * @throws ArithmeticException if numeric overflow occurs
       
  1451      */
       
  1452     @Override
       
  1453     public Temporal adjustInto(Temporal temporal) {
       
  1454         return temporal
       
  1455                 .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
       
  1456                 .with(EPOCH_DAY, getDate().toEpochDay())
       
  1457                 .with(NANO_OF_DAY, getTime().toNanoOfDay());
       
  1458     }
       
  1459 
       
  1460     /**
       
  1461      * Calculates the period between this date-time and another date-time in
       
  1462      * terms of the specified unit.
       
  1463      * <p>
       
  1464      * This calculates the period between two date-times in terms of a single unit.
       
  1465      * The start and end points are {@code this} and the specified date-time.
       
  1466      * The result will be negative if the end is before the start.
       
  1467      * For example, the period in days between two date-times can be calculated
       
  1468      * using {@code startDateTime.periodUntil(endDateTime, DAYS)}.
       
  1469      * <p>
       
  1470      * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}.
       
  1471      * If the offset differs between the two date-times, the specified
       
  1472      * end date-time is normalized to have the same offset as this date-time.
       
  1473      * <p>
       
  1474      * The calculation returns a whole number, representing the number of
       
  1475      * complete units between the two date-times.
       
  1476      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
       
  1477      * will only be one month as it is one minute short of two months.
       
  1478      * <p>
       
  1479      * This method operates in association with {@link TemporalUnit#between}.
       
  1480      * The result of this method is a {@code long} representing the amount of
       
  1481      * the specified unit. By contrast, the result of {@code between} is an
       
  1482      * object that can be used directly in addition/subtraction:
       
  1483      * <pre>
       
  1484      *   long period = start.periodUntil(end, MONTHS);   // this method
       
  1485      *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
       
  1486      * </pre>
       
  1487      * <p>
       
  1488      * The calculation is implemented in this method for {@link ChronoUnit}.
       
  1489      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
       
  1490      * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS},
       
  1491      * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},
       
  1492      * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.
       
  1493      * Other {@code ChronoUnit} values will throw an exception.
       
  1494      * <p>
       
  1495      * If the unit is not a {@code ChronoUnit}, then the result of this method
       
  1496      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
       
  1497      * passing {@code this} as the first argument and the input temporal as
       
  1498      * the second argument.
       
  1499      * <p>
       
  1500      * This instance is immutable and unaffected by this method call.
       
  1501      *
       
  1502      * @param endDateTime  the end date-time, which must be an {@code OffsetDateTime}, not null
       
  1503      * @param unit  the unit to measure the period in, not null
       
  1504      * @return the amount of the period between this date-time and the end date-time
       
  1505      * @throws DateTimeException if the period cannot be calculated
       
  1506      * @throws ArithmeticException if numeric overflow occurs
       
  1507      */
       
  1508     @Override
       
  1509     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
       
  1510         if (endDateTime instanceof OffsetDateTime == false) {
       
  1511             Objects.requireNonNull(endDateTime, "endDateTime");
       
  1512             throw new DateTimeException("Unable to calculate period between objects of two different types");
       
  1513         }
       
  1514         if (unit instanceof ChronoUnit) {
       
  1515             OffsetDateTime end = (OffsetDateTime) endDateTime;
       
  1516             end = end.withOffsetSameInstant(offset);
       
  1517             return dateTime.periodUntil(end.dateTime, unit);
       
  1518         }
       
  1519         return unit.between(this, endDateTime).getAmount();
       
  1520     }
       
  1521 
       
  1522     //-----------------------------------------------------------------------
       
  1523     /**
       
  1524      * Returns a zoned date-time formed from the instant represented by this
       
  1525      * date-time and the specified zone ID.
       
  1526      * <p>
       
  1527      * This conversion will ignore the visible local date-time and use the underlying instant instead.
       
  1528      * This avoids any problems with local time-line gaps or overlaps.
       
  1529      * The result might have different values for fields such as hour, minute an even day.
       
  1530      * <p>
       
  1531      * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}.
       
  1532      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
       
  1533      * <p>
       
  1534      * This instance is immutable and unaffected by this method call.
       
  1535      *
       
  1536      * @param zone  the time-zone to use, not null
       
  1537      * @return the zoned date-time formed from this date-time, not null
       
  1538      */
       
  1539     public ZonedDateTime atZoneSameInstant(ZoneId zone) {
       
  1540         return ZonedDateTime.ofInstant(dateTime, offset, zone);
       
  1541     }
       
  1542 
       
  1543     /**
       
  1544      * Returns a zoned date-time formed from this date-time and the specified zone ID.
       
  1545      * <p>
       
  1546      * Time-zone rules, such as daylight savings, mean that not every time on the
       
  1547      * local time-line exists. If the local date-time is in a gap or overlap according to
       
  1548      * the rules then a resolver is used to determine the resultant local time and offset.
       
  1549      * This method uses {@link ZonedDateTime#ofLocal(LocalDateTime, ZoneId, ZoneOffset)}
       
  1550      * to retain the offset from this instance if possible.
       
  1551      * <p>
       
  1552      * Finer control over gaps and overlaps is available in two ways.
       
  1553      * If you simply want to use the later offset at overlaps then call
       
  1554      * {@link ZonedDateTime#withLaterOffsetAtOverlap()} immediately after this method.
       
  1555      * <p>
       
  1556      * To create a zoned date-time at the same instant irrespective of the local time-line,
       
  1557      * use {@link #atZoneSameInstant(ZoneId)}.
       
  1558      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
       
  1559      * <p>
       
  1560      * This instance is immutable and unaffected by this method call.
       
  1561      *
       
  1562      * @param zone  the time-zone to use, not null
       
  1563      * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
       
  1564      */
       
  1565     public ZonedDateTime atZoneSimilarLocal(ZoneId zone) {
       
  1566         return ZonedDateTime.ofLocal(dateTime, zone, offset);
       
  1567     }
       
  1568 
       
  1569     //-----------------------------------------------------------------------
       
  1570     /**
       
  1571      * Converts this date-time to an {@code OffsetDate}.
       
  1572      * <p>
       
  1573      * This returns an offset date with the same local date and offset.
       
  1574      *
       
  1575      * @return an OffsetDate representing the date and offset, not null
       
  1576      */
       
  1577     public OffsetDate toOffsetDate() {
       
  1578         return OffsetDate.of(dateTime.getDate(), offset);
       
  1579     }
       
  1580 
       
  1581     /**
       
  1582      * Converts this date-time to an {@code OffsetTime}.
       
  1583      * <p>
       
  1584      * This returns an offset time with the same local time and offset.
       
  1585      *
       
  1586      * @return an OffsetTime representing the time and offset, not null
       
  1587      */
       
  1588     public OffsetTime toOffsetTime() {
       
  1589         return OffsetTime.of(dateTime.getTime(), offset);
       
  1590     }
       
  1591 
       
  1592     /**
       
  1593      * Converts this date-time to a {@code ZonedDateTime} using the offset as the zone ID.
       
  1594      * <p>
       
  1595      * This creates the simplest possible {@code ZonedDateTime} using the offset
       
  1596      * as the zone ID.
       
  1597      * <p>
       
  1598      * To control the time-zone used, see {@link #atZoneSameInstant(ZoneId)} and
       
  1599      * {@link #atZoneSimilarLocal(ZoneId)}.
       
  1600      *
       
  1601      * @return a zoned date-time representing the same local date-time and offset, not null
       
  1602      */
       
  1603     public ZonedDateTime toZonedDateTime() {
       
  1604         return ZonedDateTime.of(dateTime, offset);
       
  1605     }
       
  1606 
       
  1607     /**
       
  1608      * Converts this date-time to an {@code Instant}.
       
  1609      *
       
  1610      * @return an {@code Instant} representing the same instant, not null
       
  1611      */
       
  1612     public Instant toInstant() {
       
  1613         return dateTime.toInstant(offset);
       
  1614     }
       
  1615 
       
  1616     /**
       
  1617      * Converts this date-time to the number of seconds from the epoch of 1970-01-01T00:00:00Z.
       
  1618      * <p>
       
  1619      * This allows this date-time to be converted to a value of the
       
  1620      * {@link ChronoField#INSTANT_SECONDS epoch-seconds} field. This is primarily
       
  1621      * intended for low-level conversions rather than general application usage.
       
  1622      *
       
  1623      * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
       
  1624      */
       
  1625     public long toEpochSecond() {
       
  1626         return dateTime.toEpochSecond(offset);
       
  1627     }
       
  1628 
       
  1629     //-----------------------------------------------------------------------
       
  1630     /**
       
  1631      * Compares this {@code OffsetDateTime} to another date-time.
       
  1632      * <p>
       
  1633      * The comparison is based on the instant then on the local date-time.
       
  1634      * It is "consistent with equals", as defined by {@link Comparable}.
       
  1635      * <p>
       
  1636      * For example, the following is the comparator order:
       
  1637      * <ol>
       
  1638      * <li>{@code 2008-12-03T10:30+01:00}</li>
       
  1639      * <li>{@code 2008-12-03T11:00+01:00}</li>
       
  1640      * <li>{@code 2008-12-03T12:00+02:00}</li>
       
  1641      * <li>{@code 2008-12-03T11:30+01:00}</li>
       
  1642      * <li>{@code 2008-12-03T12:00+01:00}</li>
       
  1643      * <li>{@code 2008-12-03T12:30+01:00}</li>
       
  1644      * </ol>
       
  1645      * Values #2 and #3 represent the same instant on the time-line.
       
  1646      * When two values represent the same instant, the local date-time is compared
       
  1647      * to distinguish them. This step is needed to make the ordering
       
  1648      * consistent with {@code equals()}.
       
  1649      *
       
  1650      * @param other  the other date-time to compare to, not null
       
  1651      * @return the comparator value, negative if less, positive if greater
       
  1652      */
       
  1653     @Override
       
  1654     public int compareTo(OffsetDateTime other) {
       
  1655         if (getOffset().equals(other.getOffset())) {
       
  1656             return getDateTime().compareTo(other.getDateTime());
       
  1657         }
       
  1658         int cmp = Long.compare(toEpochSecond(), other.toEpochSecond());
       
  1659         if (cmp == 0) {
       
  1660             cmp = getTime().getNano() - other.getTime().getNano();
       
  1661             if (cmp == 0) {
       
  1662                 cmp = getDateTime().compareTo(other.getDateTime());
       
  1663             }
       
  1664         }
       
  1665         return cmp;
       
  1666     }
       
  1667 
       
  1668     //-----------------------------------------------------------------------
       
  1669     /**
       
  1670      * Checks if the instant of this date-time is after that of the specified date-time.
       
  1671      * <p>
       
  1672      * This method differs from the comparison in {@link #compareTo} and {@link #equals} in that it
       
  1673      * only compares the instant of the date-time. This is equivalent to using
       
  1674      * {@code dateTime1.toInstant().isAfter(dateTime2.toInstant());}.
       
  1675      *
       
  1676      * @param other  the other date-time to compare to, not null
       
  1677      * @return true if this is after the instant of the specified date-time
       
  1678      */
       
  1679     public boolean isAfter(OffsetDateTime other) {
       
  1680         long thisEpochSec = toEpochSecond();
       
  1681         long otherEpochSec = other.toEpochSecond();
       
  1682         return thisEpochSec > otherEpochSec ||
       
  1683             (thisEpochSec == otherEpochSec && getTime().getNano() > other.getTime().getNano());
       
  1684     }
       
  1685 
       
  1686     /**
       
  1687      * Checks if the instant of this date-time is before that of the specified date-time.
       
  1688      * <p>
       
  1689      * This method differs from the comparison in {@link #compareTo} in that it
       
  1690      * only compares the instant of the date-time. This is equivalent to using
       
  1691      * {@code dateTime1.toInstant().isBefore(dateTime2.toInstant());}.
       
  1692      *
       
  1693      * @param other  the other date-time to compare to, not null
       
  1694      * @return true if this is before the instant of the specified date-time
       
  1695      */
       
  1696     public boolean isBefore(OffsetDateTime other) {
       
  1697         long thisEpochSec = toEpochSecond();
       
  1698         long otherEpochSec = other.toEpochSecond();
       
  1699         return thisEpochSec < otherEpochSec ||
       
  1700             (thisEpochSec == otherEpochSec && getTime().getNano() < other.getTime().getNano());
       
  1701     }
       
  1702 
       
  1703     /**
       
  1704      * Checks if the instant of this date-time is equal to that of the specified date-time.
       
  1705      * <p>
       
  1706      * This method differs from the comparison in {@link #compareTo} and {@link #equals}
       
  1707      * in that it only compares the instant of the date-time. This is equivalent to using
       
  1708      * {@code dateTime1.toInstant().equals(dateTime2.toInstant());}.
       
  1709      *
       
  1710      * @param other  the other date-time to compare to, not null
       
  1711      * @return true if the instant equals the instant of the specified date-time
       
  1712      */
       
  1713     public boolean isEqual(OffsetDateTime other) {
       
  1714         return toEpochSecond() == other.toEpochSecond() &&
       
  1715                 getTime().getNano() == other.getTime().getNano();
       
  1716     }
       
  1717 
       
  1718     //-----------------------------------------------------------------------
       
  1719     /**
       
  1720      * Checks if this date-time is equal to another date-time.
       
  1721      * <p>
       
  1722      * The comparison is based on the local date-time and the offset.
       
  1723      * To compare for the same instant on the time-line, use {@link #isEqual}.
       
  1724      * Only objects of type {@code OffsetDateTime} are compared, other types return false.
       
  1725      *
       
  1726      * @param obj  the object to check, null returns false
       
  1727      * @return true if this is equal to the other date-time
       
  1728      */
       
  1729     @Override
       
  1730     public boolean equals(Object obj) {
       
  1731         if (this == obj) {
       
  1732             return true;
       
  1733         }
       
  1734         if (obj instanceof OffsetDateTime) {
       
  1735             OffsetDateTime other = (OffsetDateTime) obj;
       
  1736             return dateTime.equals(other.dateTime) && offset.equals(other.offset);
       
  1737         }
       
  1738         return false;
       
  1739     }
       
  1740 
       
  1741     /**
       
  1742      * A hash code for this date-time.
       
  1743      *
       
  1744      * @return a suitable hash code
       
  1745      */
       
  1746     @Override
       
  1747     public int hashCode() {
       
  1748         return dateTime.hashCode() ^ offset.hashCode();
       
  1749     }
       
  1750 
       
  1751     //-----------------------------------------------------------------------
       
  1752     /**
       
  1753      * Outputs this date-time as a {@code String}, such as {@code 2007-12-03T10:15:30+01:00}.
       
  1754      * <p>
       
  1755      * The output will be one of the following ISO-8601 formats:
       
  1756      * <p><ul>
       
  1757      * <li>{@code yyyy-MM-dd'T'HH:mmXXXXX}</li>
       
  1758      * <li>{@code yyyy-MM-dd'T'HH:mm:ssXXXXX}</li>
       
  1759      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX}</li>
       
  1760      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXXXX}</li>
       
  1761      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX}</li>
       
  1762      * </ul><p>
       
  1763      * The format used will be the shortest that outputs the full value of
       
  1764      * the time where the omitted parts are implied to be zero.
       
  1765      *
       
  1766      * @return a string representation of this date-time, not null
       
  1767      */
       
  1768     @Override
       
  1769     public String toString() {
       
  1770         return dateTime.toString() + offset.toString();
       
  1771     }
       
  1772 
       
  1773     /**
       
  1774      * Outputs this date-time as a {@code String} using the formatter.
       
  1775      * <p>
       
  1776      * This date-time will be passed to the formatter
       
  1777      * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
       
  1778      *
       
  1779      * @param formatter  the formatter to use, not null
       
  1780      * @return the formatted date-time string, not null
       
  1781      * @throws DateTimeException if an error occurs during printing
       
  1782      */
       
  1783     public String toString(DateTimeFormatter formatter) {
       
  1784         Objects.requireNonNull(formatter, "formatter");
       
  1785         return formatter.print(this);
       
  1786     }
       
  1787 
       
  1788     //-----------------------------------------------------------------------
       
  1789     /**
       
  1790      * Writes the object using a
       
  1791      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
       
  1792      * <pre>
       
  1793      *  out.writeByte(3);  // identifies this as a OffsetDateTime
       
  1794      *  out.writeObject(dateTime);
       
  1795      *  out.writeObject(offset);
       
  1796      * </pre>
       
  1797      *
       
  1798      * @return the instance of {@code Ser}, not null
       
  1799      */
       
  1800     private Object writeReplace() {
       
  1801         return new Ser(Ser.OFFSET_DATE_TIME_TYPE, this);
       
  1802     }
       
  1803 
       
  1804     /**
       
  1805      * Defend against malicious streams.
       
  1806      * @return never
       
  1807      * @throws InvalidObjectException always
       
  1808      */
       
  1809     private Object readResolve() throws ObjectStreamException {
       
  1810         throw new InvalidObjectException("Deserialization via serialization delegate");
       
  1811     }
       
  1812 
       
  1813     void writeExternal(ObjectOutput out) throws IOException {
       
  1814         out.writeObject(dateTime);
       
  1815         out.writeObject(offset);
       
  1816     }
       
  1817 
       
  1818     static OffsetDateTime readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       
  1819         LocalDateTime dateTime = (LocalDateTime) in.readObject();
       
  1820         ZoneOffset offset = (ZoneOffset) in.readObject();
       
  1821         return OffsetDateTime.of(dateTime, offset);
       
  1822     }
       
  1823 
       
  1824 }