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

Print this page




  61  */
  62 package java.time;
  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.chrono.IsoChronology;
  77 import java.time.format.DateTimeFormatter;
  78 import java.time.format.DateTimeParseException;
  79 import java.time.temporal.ChronoField;
  80 import java.time.temporal.ChronoUnit;
  81 import java.time.temporal.Queries;
  82 import java.time.temporal.Temporal;
  83 import java.time.temporal.TemporalAccessor;
  84 import java.time.temporal.TemporalAdjuster;
  85 import java.time.temporal.TemporalAmount;
  86 import java.time.temporal.TemporalField;
  87 import java.time.temporal.TemporalQuery;
  88 import java.time.temporal.TemporalUnit;

  89 import java.time.temporal.ValueRange;
  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.


 419      * <li>{@code MILLI_OF_SECOND}
 420      * <li>{@code MILLI_OF_DAY}
 421      * <li>{@code SECOND_OF_MINUTE}
 422      * <li>{@code SECOND_OF_DAY}
 423      * <li>{@code MINUTE_OF_HOUR}
 424      * <li>{@code MINUTE_OF_DAY}
 425      * <li>{@code HOUR_OF_AMPM}
 426      * <li>{@code CLOCK_HOUR_OF_AMPM}
 427      * <li>{@code HOUR_OF_DAY}
 428      * <li>{@code CLOCK_HOUR_OF_DAY}
 429      * <li>{@code AMPM_OF_DAY}
 430      * <li>{@code DAY_OF_WEEK}
 431      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
 432      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
 433      * <li>{@code DAY_OF_MONTH}
 434      * <li>{@code DAY_OF_YEAR}
 435      * <li>{@code EPOCH_DAY}
 436      * <li>{@code ALIGNED_WEEK_OF_MONTH}
 437      * <li>{@code ALIGNED_WEEK_OF_YEAR}
 438      * <li>{@code MONTH_OF_YEAR}
 439      * <li>{@code EPOCH_MONTH}
 440      * <li>{@code YEAR_OF_ERA}
 441      * <li>{@code YEAR}
 442      * <li>{@code ERA}
 443      * <li>{@code INSTANT_SECONDS}
 444      * <li>{@code OFFSET_SECONDS}
 445      * </ul>
 446      * All other {@code ChronoField} instances will return false.
 447      * <p>
 448      * If the field is not a {@code ChronoField}, then the result of this method
 449      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
 450      * passing {@code this} as the argument.
 451      * Whether the field is supported is determined by the field.
 452      *
 453      * @param field  the field to check, null returns false
 454      * @return true if the field is supported on this date-time, false if not
 455      */
 456     @Override
 457     public boolean isSupported(TemporalField field) {
 458         return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
 459     }
 460 
 461     /**
 462      * Gets the range of valid values for the specified field.
 463      * <p>
 464      * The range object expresses the minimum and maximum valid values for a field.
 465      * This date-time is used to enhance the accuracy of the returned range.
 466      * If it is not possible to return the range, because the field is not supported
 467      * or for some other reason, an exception is thrown.
 468      * <p>
 469      * If the field is a {@link ChronoField} then the query is implemented here.
 470      * The {@link #isSupported(TemporalField) supported fields} will return
 471      * appropriate range instances.
 472      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
 473      * <p>
 474      * If the field is not a {@code ChronoField}, then the result of this method
 475      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
 476      * passing {@code this} as the argument.
 477      * Whether the range can be obtained is determined by the field.
 478      *
 479      * @param field  the field to query the range for, not null
 480      * @return the range of valid values for the field, not null
 481      * @throws DateTimeException if the range for the field cannot be obtained

 482      */
 483     @Override
 484     public ValueRange range(TemporalField field) {
 485         if (field instanceof ChronoField) {
 486             if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) {
 487                 return field.range();
 488             }
 489             return dateTime.range(field);
 490         }
 491         return field.rangeRefinedBy(this);
 492     }
 493 
 494     /**
 495      * Gets the value of the specified field from this date-time as an {@code int}.
 496      * <p>
 497      * This queries this date-time for the value for the specified field.
 498      * The returned value will always be within the valid range of values for the field.
 499      * If it is not possible to return the value, because the field is not supported
 500      * or for some other reason, an exception is thrown.
 501      * <p>
 502      * If the field is a {@link ChronoField} then the query is implemented here.
 503      * The {@link #isSupported(TemporalField) supported fields} will return valid
 504      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
 505      * {@code EPOCH_DAY}, {@code EPOCH_MONTH} and {@code INSTANT_SECONDS} which are too
 506      * large to fit in an {@code int} and throw a {@code DateTimeException}.
 507      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
 508      * <p>
 509      * If the field is not a {@code ChronoField}, then the result of this method
 510      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 511      * passing {@code this} as the argument. Whether the value can be obtained,
 512      * and what the value represents, is determined by the field.
 513      *
 514      * @param field  the field to get, not null
 515      * @return the value for the field
 516      * @throws DateTimeException if a value for the field cannot be obtained



 517      * @throws ArithmeticException if numeric overflow occurs
 518      */
 519     @Override
 520     public int get(TemporalField field) {
 521         if (field instanceof ChronoField) {
 522             switch ((ChronoField) field) {
 523                 case INSTANT_SECONDS: throw new DateTimeException("Field too large for an int: " + field);
 524                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();


 525             }
 526             return dateTime.get(field);
 527         }
 528         return Temporal.super.get(field);
 529     }
 530 
 531     /**
 532      * Gets the value of the specified field from this date-time as a {@code long}.
 533      * <p>
 534      * This queries this date-time for the value for the specified field.
 535      * If it is not possible to return the value, because the field is not supported
 536      * or for some other reason, an exception is thrown.
 537      * <p>
 538      * If the field is a {@link ChronoField} then the query is implemented here.
 539      * The {@link #isSupported(TemporalField) supported fields} will return valid
 540      * values based on this date-time.
 541      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
 542      * <p>
 543      * If the field is not a {@code ChronoField}, then the result of this method
 544      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 545      * passing {@code this} as the argument. Whether the value can be obtained,
 546      * and what the value represents, is determined by the field.
 547      *
 548      * @param field  the field to get, not null
 549      * @return the value for the field
 550      * @throws DateTimeException if a value for the field cannot be obtained

 551      * @throws ArithmeticException if numeric overflow occurs
 552      */
 553     @Override
 554     public long getLong(TemporalField field) {
 555         if (field instanceof ChronoField) {
 556             switch ((ChronoField) field) {
 557                 case INSTANT_SECONDS: return toEpochSecond();
 558                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
 559             }
 560             return dateTime.getLong(field);
 561         }
 562         return field.getFrom(this);
 563     }
 564 
 565     //-----------------------------------------------------------------------
 566     /**
 567      * Gets the zone offset, such as '+01:00'.
 568      * <p>
 569      * This is the offset of the local date-time from UTC/Greenwich.
 570      *


 773 
 774     /**
 775      * Gets the nano-of-second field.
 776      *
 777      * @return the nano-of-second, from 0 to 999,999,999
 778      */
 779     public int getNano() {
 780         return dateTime.getNano();
 781     }
 782 
 783     //-----------------------------------------------------------------------
 784     /**
 785      * Returns an adjusted copy of this date-time.
 786      * <p>
 787      * This returns an {@code OffsetDateTime}, based on this one, with the date-time adjusted.
 788      * The adjustment takes place using the specified adjuster strategy object.
 789      * Read the documentation of the adjuster to understand what adjustment will be made.
 790      * <p>
 791      * A simple adjuster might simply set the one of the fields, such as the year field.
 792      * A more complex adjuster might set the date to the last day of the month.
 793      * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}.
 794      * These include finding the "last day of the month" and "next Wednesday".
 795      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
 796      * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
 797      * The adjuster is responsible for handling special cases, such as the varying
 798      * lengths of month and leap years.
 799      * <p>
 800      * For example this code returns a date on the last day of July:
 801      * <pre>
 802      *  import static java.time.Month.*;
 803      *  import static java.time.temporal.Adjusters.*;
 804      *
 805      *  result = offsetDateTime.with(JULY).with(lastDayOfMonth());
 806      * </pre>
 807      * <p>
 808      * The classes {@link LocalDate}, {@link LocalTime} and {@link ZoneOffset} implement
 809      * {@code TemporalAdjuster}, thus this method can be used to change the date, time or offset:
 810      * <pre>
 811      *  result = offsetDateTime.with(date);
 812      *  result = offsetDateTime.with(time);
 813      *  result = offsetDateTime.with(offset);


 850      * <p>
 851      * In some cases, changing the specified field can cause the resulting date-time to become invalid,
 852      * such as changing the month from 31st January to February would make the day-of-month invalid.
 853      * In cases like this, the field is responsible for resolving the date. Typically it will choose
 854      * the previous valid date, which would be the last valid day of February in this example.
 855      * <p>
 856      * If the field is a {@link ChronoField} then the adjustment is implemented here.
 857      * <p>
 858      * The {@code INSTANT_SECONDS} field will return a date-time with the specified instant.
 859      * The offset and nano-of-second are unchanged.
 860      * If the new instant value is outside the valid range then a {@code DateTimeException} will be thrown.
 861      * <p>
 862      * The {@code OFFSET_SECONDS} field will return a date-time with the specified offset.
 863      * The local date-time is unaltered. If the new offset value is outside the valid range
 864      * then a {@code DateTimeException} will be thrown.
 865      * <p>
 866      * The other {@link #isSupported(TemporalField) supported fields} will behave as per
 867      * the matching method on {@link LocalDateTime#with(TemporalField, long) LocalDateTime}.
 868      * In this case, the offset is not part of the calculation and will be unchanged.
 869      * <p>
 870      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
 871      * <p>
 872      * If the field is not a {@code ChronoField}, then the result of this method
 873      * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
 874      * passing {@code this} as the argument. In this case, the field determines
 875      * whether and how to adjust the instant.
 876      * <p>
 877      * This instance is immutable and unaffected by this method call.
 878      *
 879      * @param field  the field to set in the result, not null
 880      * @param newValue  the new value of the field in the result
 881      * @return an {@code OffsetDateTime} based on {@code this} with the specified field set, not null
 882      * @throws DateTimeException if the field cannot be set

 883      * @throws ArithmeticException if numeric overflow occurs
 884      */
 885     @Override
 886     public OffsetDateTime with(TemporalField field, long newValue) {
 887         if (field instanceof ChronoField) {
 888             ChronoField f = (ChronoField) field;
 889             switch (f) {
 890                 case INSTANT_SECONDS: return ofInstant(Instant.ofEpochSecond(newValue, getNano()), offset);
 891                 case OFFSET_SECONDS: {
 892                     return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
 893                 }
 894             }
 895             return with(dateTime.with(field, newValue), offset);
 896         }
 897         return field.adjustInto(this, newValue);
 898     }
 899 
 900     //-----------------------------------------------------------------------
 901     /**
 902      * Returns a copy of this {@code OffsetDateTime} with the year altered.


1024     /**
1025      * Returns a copy of this {@code OffsetDateTime} with the time truncated.
1026      * <p>
1027      * Truncation returns a copy of the original date-time with fields
1028      * smaller than the specified unit set to zero.
1029      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
1030      * will set the second-of-minute and nano-of-second field to zero.
1031      * <p>
1032      * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
1033      * that divides into the length of a standard day without remainder.
1034      * This includes all supplied time units on {@link ChronoUnit} and
1035      * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
1036      * <p>
1037      * The offset does not affect the calculation and will be the same in the result.
1038      * <p>
1039      * This instance is immutable and unaffected by this method call.
1040      *
1041      * @param unit  the unit to truncate to, not null
1042      * @return an {@code OffsetDateTime} based on this date-time with the time truncated, not null
1043      * @throws DateTimeException if unable to truncate

1044      */
1045     public OffsetDateTime truncatedTo(TemporalUnit unit) {
1046         return with(dateTime.truncatedTo(unit), offset);
1047     }
1048 
1049     //-----------------------------------------------------------------------
1050     /**
1051      * Returns a copy of this date-time with the specified amount added.
1052      * <p>
1053      * This returns an {@code OffsetDateTime}, based on this one, with the specified amount added.
1054      * The amount is typically {@link Period} or {@link Duration} but may be
1055      * any other type implementing the {@link TemporalAmount} interface.
1056      * <p>
1057      * The calculation is delegated to the amount object by calling
1058      * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
1059      * to implement the addition in any way it wishes, however it typically
1060      * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
1061      * of the amount implementation to determine if it can be successfully added.
1062      * <p>
1063      * This instance is immutable and unaffected by this method call.


1077      * <p>
1078      * This returns an {@code OffsetDateTime}, based on this one, with the amount
1079      * in terms of the unit added. If it is not possible to add the amount, because the
1080      * unit is not supported or for some other reason, an exception is thrown.
1081      * <p>
1082      * If the field is a {@link ChronoUnit} then the addition is implemented by
1083      * {@link LocalDateTime#plus(long, TemporalUnit)}.
1084      * The offset is not part of the calculation and will be unchanged in the result.
1085      * <p>
1086      * If the field is not a {@code ChronoUnit}, then the result of this method
1087      * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
1088      * passing {@code this} as the argument. In this case, the unit determines
1089      * whether and how to perform the addition.
1090      * <p>
1091      * This instance is immutable and unaffected by this method call.
1092      *
1093      * @param amountToAdd  the amount of the unit to add to the result, may be negative
1094      * @param unit  the unit of the amount to add, not null
1095      * @return an {@code OffsetDateTime} based on this date-time with the specified amount added, not null
1096      * @throws DateTimeException if the addition cannot be made

1097      * @throws ArithmeticException if numeric overflow occurs
1098      */
1099     @Override
1100     public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) {
1101         if (unit instanceof ChronoUnit) {
1102             return with(dateTime.plus(amountToAdd, unit), offset);
1103         }
1104         return unit.addTo(this, amountToAdd);
1105     }
1106 
1107     //-----------------------------------------------------------------------
1108     /**
1109      * Returns a copy of this {@code OffsetDateTime} with the specified period in years added.
1110      * <p>
1111      * This method adds the specified amount to the years field in three steps:
1112      * <ol>
1113      * <li>Add the input years to the year field</li>
1114      * <li>Check if the resulting date would be invalid</li>
1115      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1116      * </ol>


1268     public OffsetDateTime minus(TemporalAmount amountToSubtract) {
1269         return (OffsetDateTime) amountToSubtract.subtractFrom(this);
1270     }
1271 
1272     /**
1273      * Returns a copy of this date-time with the specified amount subtracted.
1274      * <p>
1275      * This returns an {@code OffsetDateTime}, based on this one, with the amount
1276      * in terms of the unit subtracted. If it is not possible to subtract the amount,
1277      * because the unit is not supported or for some other reason, an exception is thrown.
1278      * <p>
1279      * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
1280      * See that method for a full description of how addition, and thus subtraction, works.
1281      * <p>
1282      * This instance is immutable and unaffected by this method call.
1283      *
1284      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
1285      * @param unit  the unit of the amount to subtract, not null
1286      * @return an {@code OffsetDateTime} based on this date-time with the specified amount subtracted, not null
1287      * @throws DateTimeException if the subtraction cannot be made

1288      * @throws ArithmeticException if numeric overflow occurs
1289      */
1290     @Override
1291     public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
1292         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1293     }
1294 
1295     //-----------------------------------------------------------------------
1296     /**
1297      * Returns a copy of this {@code OffsetDateTime} with the specified period in years subtracted.
1298      * <p>
1299      * This method subtracts the specified amount from the years field in three steps:
1300      * <ol>
1301      * <li>Subtract the input years to the year field</li>
1302      * <li>Check if the resulting date would be invalid</li>
1303      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1304      * </ol>
1305      * <p>
1306      * For example, 2008-02-29 (leap year) minus one year would result in the
1307      * invalid date 2009-02-29 (standard year). Instead of returning an invalid


1436      * Queries this date-time using the specified query.
1437      * <p>
1438      * This queries this date-time using the specified query strategy object.
1439      * The {@code TemporalQuery} object defines the logic to be used to
1440      * obtain the result. Read the documentation of the query to understand
1441      * what the result of this method will be.
1442      * <p>
1443      * The result of this method is obtained by invoking the
1444      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1445      * specified query passing {@code this} as the argument.
1446      *
1447      * @param <R> the type of the result
1448      * @param query  the query to invoke, not null
1449      * @return the query result, null may be returned (defined by the query)
1450      * @throws DateTimeException if unable to query (defined by the query)
1451      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1452      */
1453     @SuppressWarnings("unchecked")
1454     @Override
1455     public <R> R query(TemporalQuery<R> query) {
1456         if (query == Queries.offset() || query == Queries.zone()) {
1457             return (R) getOffset();
1458         } else if (query == Queries.zoneId()) {
1459             return null;
1460         } else if (query == Queries.localDate()) {
1461             return (R) toLocalDate();
1462         } else if (query == Queries.localTime()) {
1463             return (R) toLocalTime();
1464         } else if (query == Queries.chronology()) {
1465             return (R) IsoChronology.INSTANCE;
1466         } else if (query == Queries.precision()) {
1467             return (R) NANOS;
1468         }
1469         // inline TemporalAccessor.super.query(query) as an optimization
1470         // non-JDK classes are not permitted to make this optimization
1471         return query.queryFrom(this);
1472     }
1473 
1474     /**
1475      * Adjusts the specified temporal object to have the same offset, date
1476      * and time as this object.
1477      * <p>
1478      * This returns a temporal object of the same observable type as the input
1479      * with the offset, date and time changed to be the same as this.
1480      * <p>
1481      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1482      * three times, passing {@link ChronoField#OFFSET_SECONDS},
1483      * {@link ChronoField#EPOCH_DAY} and {@link ChronoField#NANO_OF_DAY} as the fields.
1484      * <p>
1485      * In most cases, it is clearer to reverse the calling pattern by using
1486      * {@link Temporal#with(TemporalAdjuster)}:
1487      * <pre>
1488      *   // these two lines are equivalent, but the second approach is recommended
1489      *   temporal = thisOffsetDateTime.adjustInto(temporal);
1490      *   temporal = temporal.with(thisOffsetDateTime);
1491      * </pre>
1492      * <p>
1493      * This instance is immutable and unaffected by this method call.
1494      *
1495      * @param temporal  the target object to be adjusted, not null
1496      * @return the adjusted object, not null
1497      * @throws DateTimeException if unable to make the adjustment
1498      * @throws ArithmeticException if numeric overflow occurs
1499      */
1500     @Override
1501     public Temporal adjustInto(Temporal temporal) {




1502         return temporal
1503                 .with(OFFSET_SECONDS, getOffset().getTotalSeconds())
1504                 .with(EPOCH_DAY, toLocalDate().toEpochDay())
1505                 .with(NANO_OF_DAY, toLocalTime().toNanoOfDay());

1506     }
1507 
1508     /**
1509      * Calculates the period between this date-time and another date-time in
1510      * terms of the specified unit.
1511      * <p>
1512      * This calculates the period between two date-times in terms of a single unit.
1513      * The start and end points are {@code this} and the specified date-time.
1514      * The result will be negative if the end is before the start.
1515      * For example, the period in days between two date-times can be calculated
1516      * using {@code startDateTime.periodUntil(endDateTime, DAYS)}.
1517      * <p>
1518      * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}.
1519      * If the offset differs between the two date-times, the specified
1520      * end date-time is normalized to have the same offset as this date-time.
1521      * <p>
1522      * The calculation returns a whole number, representing the number of
1523      * complete units between the two date-times.
1524      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
1525      * will only be one month as it is one minute short of two months.


1535      * The choice should be made based on which makes the code more readable.
1536      * <p>
1537      * The calculation is implemented in this method for {@link ChronoUnit}.
1538      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
1539      * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS},
1540      * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},
1541      * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.
1542      * Other {@code ChronoUnit} values will throw an exception.
1543      * <p>
1544      * If the unit is not a {@code ChronoUnit}, then the result of this method
1545      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1546      * passing {@code this} as the first argument and the input temporal as
1547      * the second argument.
1548      * <p>
1549      * This instance is immutable and unaffected by this method call.
1550      *
1551      * @param endDateTime  the end date-time, which must be an {@code OffsetDateTime}, not null
1552      * @param unit  the unit to measure the period in, not null
1553      * @return the amount of the period between this date-time and the end date-time
1554      * @throws DateTimeException if the period cannot be calculated

1555      * @throws ArithmeticException if numeric overflow occurs
1556      */
1557     @Override
1558     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
1559         if (endDateTime instanceof OffsetDateTime == false) {
1560             Objects.requireNonNull(endDateTime, "endDateTime");
1561             throw new DateTimeException("Unable to calculate period between objects of two different types");
1562         }
1563         if (unit instanceof ChronoUnit) {
1564             OffsetDateTime end = (OffsetDateTime) endDateTime;
1565             end = end.withOffsetSameInstant(offset);
1566             return dateTime.periodUntil(end.dateTime, unit);
1567         }
1568         return unit.between(this, endDateTime);
1569     }
1570 














1571     //-----------------------------------------------------------------------
1572     /**
1573      * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
1574      * ensuring that the result has the same instant.
1575      * <p>
1576      * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
1577      * This conversion will ignore the visible local date-time and use the underlying instant instead.
1578      * This avoids any problems with local time-line gaps or overlaps.
1579      * The result might have different values for fields such as hour, minute an even day.
1580      * <p>
1581      * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}.
1582      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
1583      *
1584      * @param zone  the time-zone to use, not null
1585      * @return the zoned date-time formed from this date-time, not null
1586      */
1587     public ZonedDateTime atZoneSameInstant(ZoneId zone) {
1588         return ZonedDateTime.ofInstant(dateTime, offset, zone);
1589     }
1590 


1779         }
1780         return false;
1781     }
1782 
1783     /**
1784      * A hash code for this date-time.
1785      *
1786      * @return a suitable hash code
1787      */
1788     @Override
1789     public int hashCode() {
1790         return dateTime.hashCode() ^ offset.hashCode();
1791     }
1792 
1793     //-----------------------------------------------------------------------
1794     /**
1795      * Outputs this date-time as a {@code String}, such as {@code 2007-12-03T10:15:30+01:00}.
1796      * <p>
1797      * The output will be one of the following ISO-8601 formats:
1798      * <p><ul>
1799      * <li>{@code yyyy-MM-dd'T'HH:mmXXXXX}</li>
1800      * <li>{@code yyyy-MM-dd'T'HH:mm:ssXXXXX}</li>
1801      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX}</li>
1802      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXXXX}</li>
1803      * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX}</li>
1804      * </ul><p>
1805      * The format used will be the shortest that outputs the full value of
1806      * the time where the omitted parts are implied to be zero.
1807      *
1808      * @return a string representation of this date-time, not null
1809      */
1810     @Override
1811     public String toString() {
1812         return dateTime.toString() + offset.toString();
1813     }
1814 
1815     /**
1816      * Outputs this date-time as a {@code String} using the formatter.
1817      * <p>
1818      * This date-time will be passed to the formatter
1819      * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
1820      *
1821      * @param formatter  the formatter to use, not null
1822      * @return the formatted date-time string, not null
1823      * @throws DateTimeException if an error occurs during printing
1824      */
1825     public String toString(DateTimeFormatter formatter) {
1826         Objects.requireNonNull(formatter, "formatter");
1827         return formatter.format(this);
1828     }
1829 
1830     //-----------------------------------------------------------------------
1831     /**
1832      * Writes the object using a
1833      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
1834      * <pre>
1835      *  out.writeByte(10);  // identifies this as a OffsetDateTime
1836      *  out.writeObject(dateTime);
1837      *  out.writeObject(offset);
1838      * </pre>
1839      *
1840      * @return the instance of {@code Ser}, not null
1841      */
1842     private Object writeReplace() {
1843         return new Ser(Ser.OFFSET_DATE_TIME_TYPE, this);
1844     }
1845 
1846     /**
1847      * Defend against malicious streams.
1848      * @return never
1849      * @throws InvalidObjectException always


  61  */
  62 package java.time;
  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.chrono.IsoChronology;
  77 import java.time.format.DateTimeFormatter;
  78 import java.time.format.DateTimeParseException;
  79 import java.time.temporal.ChronoField;
  80 import java.time.temporal.ChronoUnit;

  81 import java.time.temporal.Temporal;
  82 import java.time.temporal.TemporalAccessor;
  83 import java.time.temporal.TemporalAdjuster;
  84 import java.time.temporal.TemporalAmount;
  85 import java.time.temporal.TemporalField;
  86 import java.time.temporal.TemporalQuery;
  87 import java.time.temporal.TemporalUnit;
  88 import java.time.temporal.UnsupportedTemporalTypeException;
  89 import java.time.temporal.ValueRange;
  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.


 419      * <li>{@code MILLI_OF_SECOND}
 420      * <li>{@code MILLI_OF_DAY}
 421      * <li>{@code SECOND_OF_MINUTE}
 422      * <li>{@code SECOND_OF_DAY}
 423      * <li>{@code MINUTE_OF_HOUR}
 424      * <li>{@code MINUTE_OF_DAY}
 425      * <li>{@code HOUR_OF_AMPM}
 426      * <li>{@code CLOCK_HOUR_OF_AMPM}
 427      * <li>{@code HOUR_OF_DAY}
 428      * <li>{@code CLOCK_HOUR_OF_DAY}
 429      * <li>{@code AMPM_OF_DAY}
 430      * <li>{@code DAY_OF_WEEK}
 431      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
 432      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
 433      * <li>{@code DAY_OF_MONTH}
 434      * <li>{@code DAY_OF_YEAR}
 435      * <li>{@code EPOCH_DAY}
 436      * <li>{@code ALIGNED_WEEK_OF_MONTH}
 437      * <li>{@code ALIGNED_WEEK_OF_YEAR}
 438      * <li>{@code MONTH_OF_YEAR}
 439      * <li>{@code PROLEPTIC_MONTH}
 440      * <li>{@code YEAR_OF_ERA}
 441      * <li>{@code YEAR}
 442      * <li>{@code ERA}
 443      * <li>{@code INSTANT_SECONDS}
 444      * <li>{@code OFFSET_SECONDS}
 445      * </ul>
 446      * All other {@code ChronoField} instances will return false.
 447      * <p>
 448      * If the field is not a {@code ChronoField}, then the result of this method
 449      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
 450      * passing {@code this} as the argument.
 451      * Whether the field is supported is determined by the field.
 452      *
 453      * @param field  the field to check, null returns false
 454      * @return true if the field is supported on this date-time, false if not
 455      */
 456     @Override
 457     public boolean isSupported(TemporalField field) {
 458         return field instanceof ChronoField || (field != null && field.isSupportedBy(this));
 459     }
 460 
 461     /**
 462      * Gets the range of valid values for the specified field.
 463      * <p>
 464      * The range object expresses the minimum and maximum valid values for a field.
 465      * This date-time is used to enhance the accuracy of the returned range.
 466      * If it is not possible to return the range, because the field is not supported
 467      * or for some other reason, an exception is thrown.
 468      * <p>
 469      * If the field is a {@link ChronoField} then the query is implemented here.
 470      * The {@link #isSupported(TemporalField) supported fields} will return
 471      * appropriate range instances.
 472      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
 473      * <p>
 474      * If the field is not a {@code ChronoField}, then the result of this method
 475      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
 476      * passing {@code this} as the argument.
 477      * Whether the range can be obtained is determined by the field.
 478      *
 479      * @param field  the field to query the range for, not null
 480      * @return the range of valid values for the field, not null
 481      * @throws DateTimeException if the range for the field cannot be obtained
 482      * @throws UnsupportedTemporalTypeException if the field is not supported
 483      */
 484     @Override
 485     public ValueRange range(TemporalField field) {
 486         if (field instanceof ChronoField) {
 487             if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) {
 488                 return field.range();
 489             }
 490             return dateTime.range(field);
 491         }
 492         return field.rangeRefinedBy(this);
 493     }
 494 
 495     /**
 496      * Gets the value of the specified field from this date-time as an {@code int}.
 497      * <p>
 498      * This queries this date-time for the value for the specified field.
 499      * The returned value will always be within the valid range of values for the field.
 500      * If it is not possible to return the value, because the field is not supported
 501      * or for some other reason, an exception is thrown.
 502      * <p>
 503      * If the field is a {@link ChronoField} then the query is implemented here.
 504      * The {@link #isSupported(TemporalField) supported fields} will return valid
 505      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
 506      * {@code EPOCH_DAY}, {@code PROLEPTIC_MONTH} and {@code INSTANT_SECONDS} which are too
 507      * large to fit in an {@code int} and throw a {@code DateTimeException}.
 508      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
 509      * <p>
 510      * If the field is not a {@code ChronoField}, then the result of this method
 511      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 512      * passing {@code this} as the argument. Whether the value can be obtained,
 513      * and what the value represents, is determined by the field.
 514      *
 515      * @param field  the field to get, not null
 516      * @return the value for the field
 517      * @throws DateTimeException if a value for the field cannot be obtained or
 518      *         the value is outside the range of valid values for the field
 519      * @throws UnsupportedTemporalTypeException if the field is not supported or
 520      *         the range of values exceeds an {@code int}
 521      * @throws ArithmeticException if numeric overflow occurs
 522      */
 523     @Override
 524     public int get(TemporalField field) {
 525         if (field instanceof ChronoField) {
 526             switch ((ChronoField) field) {
 527                 case INSTANT_SECONDS:
 528                     throw new UnsupportedTemporalTypeException("Invalid field 'InstantSeconds' for get() method, use getLong() instead");
 529                 case OFFSET_SECONDS:
 530                     return getOffset().getTotalSeconds();
 531             }
 532             return dateTime.get(field);
 533         }
 534         return Temporal.super.get(field);
 535     }
 536 
 537     /**
 538      * Gets the value of the specified field from this date-time as a {@code long}.
 539      * <p>
 540      * This queries this date-time for the value for the specified field.
 541      * If it is not possible to return the value, because the field is not supported
 542      * or for some other reason, an exception is thrown.
 543      * <p>
 544      * If the field is a {@link ChronoField} then the query is implemented here.
 545      * The {@link #isSupported(TemporalField) supported fields} will return valid
 546      * values based on this date-time.
 547      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
 548      * <p>
 549      * If the field is not a {@code ChronoField}, then the result of this method
 550      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
 551      * passing {@code this} as the argument. Whether the value can be obtained,
 552      * and what the value represents, is determined by the field.
 553      *
 554      * @param field  the field to get, not null
 555      * @return the value for the field
 556      * @throws DateTimeException if a value for the field cannot be obtained
 557      * @throws UnsupportedTemporalTypeException if the field is not supported
 558      * @throws ArithmeticException if numeric overflow occurs
 559      */
 560     @Override
 561     public long getLong(TemporalField field) {
 562         if (field instanceof ChronoField) {
 563             switch ((ChronoField) field) {
 564                 case INSTANT_SECONDS: return toEpochSecond();
 565                 case OFFSET_SECONDS: return getOffset().getTotalSeconds();
 566             }
 567             return dateTime.getLong(field);
 568         }
 569         return field.getFrom(this);
 570     }
 571 
 572     //-----------------------------------------------------------------------
 573     /**
 574      * Gets the zone offset, such as '+01:00'.
 575      * <p>
 576      * This is the offset of the local date-time from UTC/Greenwich.
 577      *


 780 
 781     /**
 782      * Gets the nano-of-second field.
 783      *
 784      * @return the nano-of-second, from 0 to 999,999,999
 785      */
 786     public int getNano() {
 787         return dateTime.getNano();
 788     }
 789 
 790     //-----------------------------------------------------------------------
 791     /**
 792      * Returns an adjusted copy of this date-time.
 793      * <p>
 794      * This returns an {@code OffsetDateTime}, based on this one, with the date-time adjusted.
 795      * The adjustment takes place using the specified adjuster strategy object.
 796      * Read the documentation of the adjuster to understand what adjustment will be made.
 797      * <p>
 798      * A simple adjuster might simply set the one of the fields, such as the year field.
 799      * A more complex adjuster might set the date to the last day of the month.
 800      * A selection of common adjustments is provided in {@link TemporalAdjuster}.
 801      * These include finding the "last day of the month" and "next Wednesday".
 802      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
 803      * such as {@link Month} and {@link java.time.MonthDay MonthDay}.
 804      * The adjuster is responsible for handling special cases, such as the varying
 805      * lengths of month and leap years.
 806      * <p>
 807      * For example this code returns a date on the last day of July:
 808      * <pre>
 809      *  import static java.time.Month.*;
 810      *  import static java.time.temporal.Adjusters.*;
 811      *
 812      *  result = offsetDateTime.with(JULY).with(lastDayOfMonth());
 813      * </pre>
 814      * <p>
 815      * The classes {@link LocalDate}, {@link LocalTime} and {@link ZoneOffset} implement
 816      * {@code TemporalAdjuster}, thus this method can be used to change the date, time or offset:
 817      * <pre>
 818      *  result = offsetDateTime.with(date);
 819      *  result = offsetDateTime.with(time);
 820      *  result = offsetDateTime.with(offset);


 857      * <p>
 858      * In some cases, changing the specified field can cause the resulting date-time to become invalid,
 859      * such as changing the month from 31st January to February would make the day-of-month invalid.
 860      * In cases like this, the field is responsible for resolving the date. Typically it will choose
 861      * the previous valid date, which would be the last valid day of February in this example.
 862      * <p>
 863      * If the field is a {@link ChronoField} then the adjustment is implemented here.
 864      * <p>
 865      * The {@code INSTANT_SECONDS} field will return a date-time with the specified instant.
 866      * The offset and nano-of-second are unchanged.
 867      * If the new instant value is outside the valid range then a {@code DateTimeException} will be thrown.
 868      * <p>
 869      * The {@code OFFSET_SECONDS} field will return a date-time with the specified offset.
 870      * The local date-time is unaltered. If the new offset value is outside the valid range
 871      * then a {@code DateTimeException} will be thrown.
 872      * <p>
 873      * The other {@link #isSupported(TemporalField) supported fields} will behave as per
 874      * the matching method on {@link LocalDateTime#with(TemporalField, long) LocalDateTime}.
 875      * In this case, the offset is not part of the calculation and will be unchanged.
 876      * <p>
 877      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
 878      * <p>
 879      * If the field is not a {@code ChronoField}, then the result of this method
 880      * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
 881      * passing {@code this} as the argument. In this case, the field determines
 882      * whether and how to adjust the instant.
 883      * <p>
 884      * This instance is immutable and unaffected by this method call.
 885      *
 886      * @param field  the field to set in the result, not null
 887      * @param newValue  the new value of the field in the result
 888      * @return an {@code OffsetDateTime} based on {@code this} with the specified field set, not null
 889      * @throws DateTimeException if the field cannot be set
 890      * @throws UnsupportedTemporalTypeException if the field is not supported
 891      * @throws ArithmeticException if numeric overflow occurs
 892      */
 893     @Override
 894     public OffsetDateTime with(TemporalField field, long newValue) {
 895         if (field instanceof ChronoField) {
 896             ChronoField f = (ChronoField) field;
 897             switch (f) {
 898                 case INSTANT_SECONDS: return ofInstant(Instant.ofEpochSecond(newValue, getNano()), offset);
 899                 case OFFSET_SECONDS: {
 900                     return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
 901                 }
 902             }
 903             return with(dateTime.with(field, newValue), offset);
 904         }
 905         return field.adjustInto(this, newValue);
 906     }
 907 
 908     //-----------------------------------------------------------------------
 909     /**
 910      * Returns a copy of this {@code OffsetDateTime} with the year altered.


1032     /**
1033      * Returns a copy of this {@code OffsetDateTime} with the time truncated.
1034      * <p>
1035      * Truncation returns a copy of the original date-time with fields
1036      * smaller than the specified unit set to zero.
1037      * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
1038      * will set the second-of-minute and nano-of-second field to zero.
1039      * <p>
1040      * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
1041      * that divides into the length of a standard day without remainder.
1042      * This includes all supplied time units on {@link ChronoUnit} and
1043      * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
1044      * <p>
1045      * The offset does not affect the calculation and will be the same in the result.
1046      * <p>
1047      * This instance is immutable and unaffected by this method call.
1048      *
1049      * @param unit  the unit to truncate to, not null
1050      * @return an {@code OffsetDateTime} based on this date-time with the time truncated, not null
1051      * @throws DateTimeException if unable to truncate
1052      * @throws UnsupportedTemporalTypeException if the unit is not supported
1053      */
1054     public OffsetDateTime truncatedTo(TemporalUnit unit) {
1055         return with(dateTime.truncatedTo(unit), offset);
1056     }
1057 
1058     //-----------------------------------------------------------------------
1059     /**
1060      * Returns a copy of this date-time with the specified amount added.
1061      * <p>
1062      * This returns an {@code OffsetDateTime}, based on this one, with the specified amount added.
1063      * The amount is typically {@link Period} or {@link Duration} but may be
1064      * any other type implementing the {@link TemporalAmount} interface.
1065      * <p>
1066      * The calculation is delegated to the amount object by calling
1067      * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
1068      * to implement the addition in any way it wishes, however it typically
1069      * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
1070      * of the amount implementation to determine if it can be successfully added.
1071      * <p>
1072      * This instance is immutable and unaffected by this method call.


1086      * <p>
1087      * This returns an {@code OffsetDateTime}, based on this one, with the amount
1088      * in terms of the unit added. If it is not possible to add the amount, because the
1089      * unit is not supported or for some other reason, an exception is thrown.
1090      * <p>
1091      * If the field is a {@link ChronoUnit} then the addition is implemented by
1092      * {@link LocalDateTime#plus(long, TemporalUnit)}.
1093      * The offset is not part of the calculation and will be unchanged in the result.
1094      * <p>
1095      * If the field is not a {@code ChronoUnit}, then the result of this method
1096      * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
1097      * passing {@code this} as the argument. In this case, the unit determines
1098      * whether and how to perform the addition.
1099      * <p>
1100      * This instance is immutable and unaffected by this method call.
1101      *
1102      * @param amountToAdd  the amount of the unit to add to the result, may be negative
1103      * @param unit  the unit of the amount to add, not null
1104      * @return an {@code OffsetDateTime} based on this date-time with the specified amount added, not null
1105      * @throws DateTimeException if the addition cannot be made
1106      * @throws UnsupportedTemporalTypeException if the unit is not supported
1107      * @throws ArithmeticException if numeric overflow occurs
1108      */
1109     @Override
1110     public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) {
1111         if (unit instanceof ChronoUnit) {
1112             return with(dateTime.plus(amountToAdd, unit), offset);
1113         }
1114         return unit.addTo(this, amountToAdd);
1115     }
1116 
1117     //-----------------------------------------------------------------------
1118     /**
1119      * Returns a copy of this {@code OffsetDateTime} with the specified period in years added.
1120      * <p>
1121      * This method adds the specified amount to the years field in three steps:
1122      * <ol>
1123      * <li>Add the input years to the year field</li>
1124      * <li>Check if the resulting date would be invalid</li>
1125      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1126      * </ol>


1278     public OffsetDateTime minus(TemporalAmount amountToSubtract) {
1279         return (OffsetDateTime) amountToSubtract.subtractFrom(this);
1280     }
1281 
1282     /**
1283      * Returns a copy of this date-time with the specified amount subtracted.
1284      * <p>
1285      * This returns an {@code OffsetDateTime}, based on this one, with the amount
1286      * in terms of the unit subtracted. If it is not possible to subtract the amount,
1287      * because the unit is not supported or for some other reason, an exception is thrown.
1288      * <p>
1289      * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
1290      * See that method for a full description of how addition, and thus subtraction, works.
1291      * <p>
1292      * This instance is immutable and unaffected by this method call.
1293      *
1294      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
1295      * @param unit  the unit of the amount to subtract, not null
1296      * @return an {@code OffsetDateTime} based on this date-time with the specified amount subtracted, not null
1297      * @throws DateTimeException if the subtraction cannot be made
1298      * @throws UnsupportedTemporalTypeException if the unit is not supported
1299      * @throws ArithmeticException if numeric overflow occurs
1300      */
1301     @Override
1302     public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) {
1303         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1304     }
1305 
1306     //-----------------------------------------------------------------------
1307     /**
1308      * Returns a copy of this {@code OffsetDateTime} with the specified period in years subtracted.
1309      * <p>
1310      * This method subtracts the specified amount from the years field in three steps:
1311      * <ol>
1312      * <li>Subtract the input years to the year field</li>
1313      * <li>Check if the resulting date would be invalid</li>
1314      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1315      * </ol>
1316      * <p>
1317      * For example, 2008-02-29 (leap year) minus one year would result in the
1318      * invalid date 2009-02-29 (standard year). Instead of returning an invalid


1447      * Queries this date-time using the specified query.
1448      * <p>
1449      * This queries this date-time using the specified query strategy object.
1450      * The {@code TemporalQuery} object defines the logic to be used to
1451      * obtain the result. Read the documentation of the query to understand
1452      * what the result of this method will be.
1453      * <p>
1454      * The result of this method is obtained by invoking the
1455      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1456      * specified query passing {@code this} as the argument.
1457      *
1458      * @param <R> the type of the result
1459      * @param query  the query to invoke, not null
1460      * @return the query result, null may be returned (defined by the query)
1461      * @throws DateTimeException if unable to query (defined by the query)
1462      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1463      */
1464     @SuppressWarnings("unchecked")
1465     @Override
1466     public <R> R query(TemporalQuery<R> query) {
1467         if (query == TemporalQuery.offset() || query == TemporalQuery.zone()) {
1468             return (R) getOffset();
1469         } else if (query == TemporalQuery.zoneId()) {
1470             return null;
1471         } else if (query == TemporalQuery.localDate()) {
1472             return (R) toLocalDate();
1473         } else if (query == TemporalQuery.localTime()) {
1474             return (R) toLocalTime();
1475         } else if (query == TemporalQuery.chronology()) {
1476             return (R) IsoChronology.INSTANCE;
1477         } else if (query == TemporalQuery.precision()) {
1478             return (R) NANOS;
1479         }
1480         // inline TemporalAccessor.super.query(query) as an optimization
1481         // non-JDK classes are not permitted to make this optimization
1482         return query.queryFrom(this);
1483     }
1484 
1485     /**
1486      * Adjusts the specified temporal object to have the same offset, date
1487      * and time as this object.
1488      * <p>
1489      * This returns a temporal object of the same observable type as the input
1490      * with the offset, date and time changed to be the same as this.
1491      * <p>
1492      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1493      * three times, passing {@link ChronoField#EPOCH_DAY},
1494      * {@link ChronoField#NANO_OF_DAY} and {@link ChronoField#OFFSET_SECONDS} as the fields.
1495      * <p>
1496      * In most cases, it is clearer to reverse the calling pattern by using
1497      * {@link Temporal#with(TemporalAdjuster)}:
1498      * <pre>
1499      *   // these two lines are equivalent, but the second approach is recommended
1500      *   temporal = thisOffsetDateTime.adjustInto(temporal);
1501      *   temporal = temporal.with(thisOffsetDateTime);
1502      * </pre>
1503      * <p>
1504      * This instance is immutable and unaffected by this method call.
1505      *
1506      * @param temporal  the target object to be adjusted, not null
1507      * @return the adjusted object, not null
1508      * @throws DateTimeException if unable to make the adjustment
1509      * @throws ArithmeticException if numeric overflow occurs
1510      */
1511     @Override
1512     public Temporal adjustInto(Temporal temporal) {
1513         // OffsetDateTime is treated as three separate fields, not an instant
1514         // this produces the most consistent set of results overall
1515         // the offset is set after the date and time, as it is typically a small
1516         // tweak to the result, with ZonedDateTime frequently ignoring the offset
1517         return temporal

1518                 .with(EPOCH_DAY, toLocalDate().toEpochDay())
1519                 .with(NANO_OF_DAY, toLocalTime().toNanoOfDay())
1520                 .with(OFFSET_SECONDS, getOffset().getTotalSeconds());
1521     }
1522 
1523     /**
1524      * Calculates the period between this date-time and another date-time in
1525      * terms of the specified unit.
1526      * <p>
1527      * This calculates the period between two date-times in terms of a single unit.
1528      * The start and end points are {@code this} and the specified date-time.
1529      * The result will be negative if the end is before the start.
1530      * For example, the period in days between two date-times can be calculated
1531      * using {@code startDateTime.periodUntil(endDateTime, DAYS)}.
1532      * <p>
1533      * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}.
1534      * If the offset differs between the two date-times, the specified
1535      * end date-time is normalized to have the same offset as this date-time.
1536      * <p>
1537      * The calculation returns a whole number, representing the number of
1538      * complete units between the two date-times.
1539      * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z
1540      * will only be one month as it is one minute short of two months.


1550      * The choice should be made based on which makes the code more readable.
1551      * <p>
1552      * The calculation is implemented in this method for {@link ChronoUnit}.
1553      * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
1554      * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS},
1555      * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},
1556      * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.
1557      * Other {@code ChronoUnit} values will throw an exception.
1558      * <p>
1559      * If the unit is not a {@code ChronoUnit}, then the result of this method
1560      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1561      * passing {@code this} as the first argument and the input temporal as
1562      * the second argument.
1563      * <p>
1564      * This instance is immutable and unaffected by this method call.
1565      *
1566      * @param endDateTime  the end date-time, which must be an {@code OffsetDateTime}, not null
1567      * @param unit  the unit to measure the period in, not null
1568      * @return the amount of the period between this date-time and the end date-time
1569      * @throws DateTimeException if the period cannot be calculated
1570      * @throws UnsupportedTemporalTypeException if the unit is not supported
1571      * @throws ArithmeticException if numeric overflow occurs
1572      */
1573     @Override
1574     public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
1575         if (endDateTime instanceof OffsetDateTime == false) {
1576             Objects.requireNonNull(endDateTime, "endDateTime");
1577             throw new DateTimeException("Unable to calculate period between objects of two different types");
1578         }
1579         if (unit instanceof ChronoUnit) {
1580             OffsetDateTime end = (OffsetDateTime) endDateTime;
1581             end = end.withOffsetSameInstant(offset);
1582             return dateTime.periodUntil(end.dateTime, unit);
1583         }
1584         return unit.between(this, endDateTime);
1585     }
1586 
1587     /**
1588      * Formats this date-time using the specified formatter.
1589      * <p>
1590      * This date-time will be passed to the formatter to produce a string.
1591      *
1592      * @param formatter  the formatter to use, not null
1593      * @return the formatted date-time string, not null
1594      * @throws DateTimeException if an error occurs during printing
1595      */
1596     public String format(DateTimeFormatter formatter) {
1597         Objects.requireNonNull(formatter, "formatter");
1598         return formatter.format(this);
1599     }
1600 
1601     //-----------------------------------------------------------------------
1602     /**
1603      * Combines this date-time with a time-zone to create a {@code ZonedDateTime}
1604      * ensuring that the result has the same instant.
1605      * <p>
1606      * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone.
1607      * This conversion will ignore the visible local date-time and use the underlying instant instead.
1608      * This avoids any problems with local time-line gaps or overlaps.
1609      * The result might have different values for fields such as hour, minute an even day.
1610      * <p>
1611      * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}.
1612      * To use the offset as the zone ID, use {@link #toZonedDateTime()}.
1613      *
1614      * @param zone  the time-zone to use, not null
1615      * @return the zoned date-time formed from this date-time, not null
1616      */
1617     public ZonedDateTime atZoneSameInstant(ZoneId zone) {
1618         return ZonedDateTime.ofInstant(dateTime, offset, zone);
1619     }
1620 


1809         }
1810         return false;
1811     }
1812 
1813     /**
1814      * A hash code for this date-time.
1815      *
1816      * @return a suitable hash code
1817      */
1818     @Override
1819     public int hashCode() {
1820         return dateTime.hashCode() ^ offset.hashCode();
1821     }
1822 
1823     //-----------------------------------------------------------------------
1824     /**
1825      * Outputs this date-time as a {@code String}, such as {@code 2007-12-03T10:15:30+01:00}.
1826      * <p>
1827      * The output will be one of the following ISO-8601 formats:
1828      * <p><ul>
1829      * <li>{@code uuuu-MM-dd'T'HH:mmXXXXX}</li>
1830      * <li>{@code uuuu-MM-dd'T'HH:mm:ssXXXXX}</li>
1831      * <li>{@code uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX}</li>
1832      * <li>{@code uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXXXX}</li>
1833      * <li>{@code uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX}</li>
1834      * </ul><p>
1835      * The format used will be the shortest that outputs the full value of
1836      * the time where the omitted parts are implied to be zero.
1837      *
1838      * @return a string representation of this date-time, not null
1839      */
1840     @Override
1841     public String toString() {
1842         return dateTime.toString() + offset.toString();
1843     }
1844 















1845     //-----------------------------------------------------------------------
1846     /**
1847      * Writes the object using a
1848      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
1849      * <pre>
1850      *  out.writeByte(10);  // identifies this as a OffsetDateTime
1851      *  out.writeObject(dateTime);
1852      *  out.writeObject(offset);
1853      * </pre>
1854      *
1855      * @return the instance of {@code Ser}, not null
1856      */
1857     private Object writeReplace() {
1858         return new Ser(Ser.OFFSET_DATE_TIME_TYPE, this);
1859     }
1860 
1861     /**
1862      * Defend against malicious streams.
1863      * @return never
1864      * @throws InvalidObjectException always