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
|