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

Print this page

        

*** 57,67 **** * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time.temporal; import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS; --- 57,67 ---- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time; import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS;
*** 71,94 **** import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; ! import java.time.Clock; ! import java.time.DateTimeException; ! import java.time.DayOfWeek; ! import java.time.Instant; ! import java.time.LocalDate; ! import java.time.LocalDateTime; ! import java.time.LocalTime; ! import java.time.Month; ! import java.time.ZoneId; ! import java.time.ZoneOffset; ! import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; - import java.time.format.DateTimeFormatters; import java.time.format.DateTimeParseException; import java.time.zone.ZoneRules; import java.util.Comparator; import java.util.Objects; /** --- 71,94 ---- import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; ! import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; + import java.time.temporal.ChronoField; + import java.time.temporal.ChronoUnit; + import java.time.temporal.Queries; + import java.time.temporal.Temporal; + import java.time.temporal.TemporalAccessor; + import java.time.temporal.TemporalAdjuster; + import java.time.temporal.TemporalAmount; + import java.time.temporal.TemporalField; + import java.time.temporal.TemporalQuery; + import java.time.temporal.TemporalUnit; + import java.time.temporal.ValueRange; import java.time.zone.ZoneRules; import java.util.Comparator; import java.util.Objects; /**
*** 149,159 **** public static final Comparator<OffsetDateTime> INSTANT_COMPARATOR = new Comparator<OffsetDateTime>() { @Override public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) { int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); if (cmp == 0) { ! cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay()); } return cmp; } }; --- 149,159 ---- public static final Comparator<OffsetDateTime> INSTANT_COMPARATOR = new Comparator<OffsetDateTime>() { @Override public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) { int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); if (cmp == 0) { ! cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay()); } return cmp; } };
*** 251,272 **** public static OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset) { return new OffsetDateTime(dateTime, offset); } /** ! * Obtains an instance of {@code OffsetDateTime} from a {@code ZonedDateTime}. * <p> ! * This creates an offset date-time with the same local date-time and offset as ! * the zoned date-time. The result will have the same instant as the input. ! * ! * @param zonedDateTime the zoned date-time to convert from, not null * @return the offset date-time, not null ! * @throws DateTimeException if the result exceeds the supported range */ ! public static OffsetDateTime of(ZonedDateTime zonedDateTime) { ! Objects.requireNonNull(zonedDateTime, "zonedDateTime"); ! return new OffsetDateTime(zonedDateTime.getDateTime(), zonedDateTime.getOffset()); } //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID. --- 251,288 ---- public static OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset) { return new OffsetDateTime(dateTime, offset); } /** ! * Obtains an instance of {@code OffsetDateTime} from a year, month, day, ! * hour, minute, second, nanosecond and offset. * <p> ! * This creates an offset date-time with the seven specified fields. ! * <p> ! * This method exists primarily for writing test cases. ! * Non test-code will typically use other methods to create an offset time. ! * {@code LocalDateTime} has five additional convenience variants of the ! * equivalent factory method taking fewer arguments. ! * They are not provided here to reduce the footprint of the API. ! * ! * @param year the year to represent, from MIN_YEAR to MAX_YEAR ! * @param month the month-of-year to represent, from 1 (January) to 12 (December) ! * @param dayOfMonth the day-of-month to represent, from 1 to 31 ! * @param hour the hour-of-day to represent, from 0 to 23 ! * @param minute the minute-of-hour to represent, from 0 to 59 ! * @param second the second-of-minute to represent, from 0 to 59 ! * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999 ! * @param offset the zone offset, not null * @return the offset date-time, not null ! * @throws DateTimeException if the value of any field is out of range, or ! * if the day-of-month is invalid for the month-year */ ! public static OffsetDateTime of( ! int year, int month, int dayOfMonth, ! int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) { ! LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond); ! return new OffsetDateTime(dt, offset); } //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID.
*** 291,305 **** //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetDateTime} from a temporal object. * <p> ! * A {@code TemporalAccessor} represents some form of date and time information. ! * This factory converts the arbitrary temporal object to an instance of {@code OffsetDateTime}. ! * <p> ! * The conversion extracts and combines {@code LocalDateTime} and {@code ZoneOffset}. ! * If that fails it will try to extract and combine {@code Instant} and {@code ZoneOffset}. * <p> * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code OffsetDateTime::from}. * * @param temporal the temporal object to convert, not null --- 307,326 ---- //----------------------------------------------------------------------- /** * Obtains an instance of {@code OffsetDateTime} from a temporal object. * <p> ! * This obtains an offset date-time based on the specified temporal. ! * A {@code TemporalAccessor} represents an arbitrary set of date and time information, ! * which this factory converts to an instance of {@code OffsetDateTime}. ! * <p> ! * The conversion will first obtain a {@code ZoneOffset} from the temporal object. ! * It will then try to obtain a {@code LocalDateTime}, falling back to an {@code Instant} if necessary. ! * The result will be the combination of {@code ZoneOffset} with either ! * with {@code LocalDateTime} or {@code Instant}. ! * Implementations are permitted to perform optimizations such as accessing ! * those fields that are equivalent to the relevant objects. * <p> * This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code OffsetDateTime::from}. * * @param temporal the temporal object to convert, not null
*** 328,345 **** /** * Obtains an instance of {@code OffsetDateTime} from a text string * such as {@code 2007-12-03T10:15:30+01:00}. * <p> * The string must represent a valid date-time and is parsed using ! * {@link java.time.format.DateTimeFormatters#isoOffsetDateTime()}. * * @param text the text to parse such as "2007-12-03T10:15:30+01:00", not null * @return the parsed offset date-time, not null * @throws DateTimeParseException if the text cannot be parsed */ public static OffsetDateTime parse(CharSequence text) { ! return parse(text, DateTimeFormatters.isoOffsetDateTime()); } /** * Obtains an instance of {@code OffsetDateTime} from a text string using a specific formatter. * <p> --- 349,366 ---- /** * Obtains an instance of {@code OffsetDateTime} from a text string * such as {@code 2007-12-03T10:15:30+01:00}. * <p> * The string must represent a valid date-time and is parsed using ! * {@link java.time.format.DateTimeFormatter#ISO_OFFSET_DATE_TIME}. * * @param text the text to parse such as "2007-12-03T10:15:30+01:00", not null * @return the parsed offset date-time, not null * @throws DateTimeParseException if the text cannot be parsed */ public static OffsetDateTime parse(CharSequence text) { ! return parse(text, DateTimeFormatter.ISO_OFFSET_DATE_TIME); } /** * Obtains an instance of {@code OffsetDateTime} from a text string using a specific formatter. * <p>
*** 423,442 **** * <li>{@code OFFSET_SECONDS} * </ul> * All other {@code ChronoField} instances will return false. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)} * passing {@code this} as the argument. * Whether the field is supported is determined by the field. * * @param field the field to check, null returns false * @return true if the field is supported on this date-time, false if not */ @Override public boolean isSupported(TemporalField field) { ! return field instanceof ChronoField || (field != null && field.doIsSupported(this)); } /** * Gets the range of valid values for the specified field. * <p> --- 444,463 ---- * <li>{@code OFFSET_SECONDS} * </ul> * All other {@code ChronoField} instances will return false. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} * passing {@code this} as the argument. * Whether the field is supported is determined by the field. * * @param field the field to check, null returns false * @return true if the field is supported on this date-time, false if not */ @Override public boolean isSupported(TemporalField field) { ! return field instanceof ChronoField || (field != null && field.isSupportedBy(this)); } /** * Gets the range of valid values for the specified field. * <p>
*** 449,459 **** * The {@link #isSupported(TemporalField) supported fields} will return * appropriate range instances. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)} * passing {@code this} as the argument. * Whether the range can be obtained is determined by the field. * * @param field the field to query the range for, not null * @return the range of valid values for the field, not null --- 470,480 ---- * The {@link #isSupported(TemporalField) supported fields} will return * appropriate range instances. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)} * passing {@code this} as the argument. * Whether the range can be obtained is determined by the field. * * @param field the field to query the range for, not null * @return the range of valid values for the field, not null
*** 465,475 **** if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) { return field.range(); } return dateTime.range(field); } ! return field.doRange(this); } /** * Gets the value of the specified field from this date-time as an {@code int}. * <p> --- 486,496 ---- if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) { return field.range(); } return dateTime.range(field); } ! return field.rangeRefinedBy(this); } /** * Gets the value of the specified field from this date-time as an {@code int}. * <p>
*** 484,494 **** * {@code EPOCH_DAY}, {@code EPOCH_MONTH} and {@code INSTANT_SECONDS} which are too * large to fit in an {@code int} and throw a {@code DateTimeException}. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} * passing {@code this} as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param field the field to get, not null * @return the value for the field --- 505,515 ---- * {@code EPOCH_DAY}, {@code EPOCH_MONTH} and {@code INSTANT_SECONDS} which are too * large to fit in an {@code int} and throw a {@code DateTimeException}. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} * passing {@code this} as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param field the field to get, not null * @return the value for the field
*** 518,528 **** * The {@link #isSupported(TemporalField) supported fields} will return valid * values based on this date-time. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)} * passing {@code this} as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param field the field to get, not null * @return the value for the field --- 539,549 ---- * The {@link #isSupported(TemporalField) supported fields} will return valid * values based on this date-time. * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} * passing {@code this} as the argument. Whether the value can be obtained, * and what the value represents, is determined by the field. * * @param field the field to get, not null * @return the value for the field
*** 536,546 **** case INSTANT_SECONDS: return toEpochSecond(); case OFFSET_SECONDS: return getOffset().getTotalSeconds(); } return dateTime.getLong(field); } ! return field.doGet(this); } //----------------------------------------------------------------------- /** * Gets the zone offset, such as '+01:00'. --- 557,567 ---- case INSTANT_SECONDS: return toEpochSecond(); case OFFSET_SECONDS: return getOffset().getTotalSeconds(); } return dateTime.getLong(field); } ! return field.getFrom(this); } //----------------------------------------------------------------------- /** * Gets the zone offset, such as '+01:00'.
*** 609,619 **** * This returns a {@code LocalDateTime} with the same year, month, day and time * as this date-time. * * @return the local date-time part of this date-time, not null */ ! public LocalDateTime getDateTime() { return dateTime; } //----------------------------------------------------------------------- /** --- 630,640 ---- * This returns a {@code LocalDateTime} with the same year, month, day and time * as this date-time. * * @return the local date-time part of this date-time, not null */ ! public LocalDateTime toLocalDateTime() { return dateTime; } //----------------------------------------------------------------------- /**
*** 622,642 **** * This returns a {@code LocalDate} with the same year, month and day * as this date-time. * * @return the date part of this date-time, not null */ ! public LocalDate getDate() { ! return dateTime.getDate(); } /** * Gets the year field. * <p> * This method returns the primitive {@code int} value for the year. * <p> * The year returned by this method is proleptic as per {@code get(YEAR)}. ! * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}. * * @return the year, from MIN_YEAR to MAX_YEAR */ public int getYear() { return dateTime.getYear(); --- 643,663 ---- * This returns a {@code LocalDate} with the same year, month and day * as this date-time. * * @return the date part of this date-time, not null */ ! public LocalDate toLocalDate() { ! return dateTime.toLocalDate(); } /** * Gets the year field. * <p> * This method returns the primitive {@code int} value for the year. * <p> * The year returned by this method is proleptic as per {@code get(YEAR)}. ! * To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}. * * @return the year, from MIN_YEAR to MAX_YEAR */ public int getYear() { return dateTime.getYear();
*** 717,728 **** * This returns a {@code LocalTime} with the same hour, minute, second and * nanosecond as this date-time. * * @return the time part of this date-time, not null */ ! public LocalTime getTime() { ! return dateTime.getTime(); } /** * Gets the hour-of-day field. * --- 738,749 ---- * This returns a {@code LocalTime} with the same hour, minute, second and * nanosecond as this date-time. * * @return the time part of this date-time, not null */ ! public LocalTime toLocalTime() { ! return dateTime.toLocalTime(); } /** * Gets the hour-of-day field. *
*** 761,780 **** //----------------------------------------------------------------------- /** * Returns an adjusted copy of this date-time. * <p> ! * This returns a new {@code OffsetDateTime}, based on this one, with the date-time adjusted. * The adjustment takes place using the specified adjuster strategy object. * Read the documentation of the adjuster to understand what adjustment will be made. * <p> * A simple adjuster might simply set the one of the fields, such as the year field. * A more complex adjuster might set the date to the last day of the month. * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}. * These include finding the "last day of the month" and "next Wednesday". * Key date-time classes also implement the {@code TemporalAdjuster} interface, ! * such as {@link Month} and {@link java.time.temporal.MonthDay MonthDay}. * The adjuster is responsible for handling special cases, such as the varying * lengths of month and leap years. * <p> * For example this code returns a date on the last day of July: * <pre> --- 782,801 ---- //----------------------------------------------------------------------- /** * Returns an adjusted copy of this date-time. * <p> ! * This returns an {@code OffsetDateTime}, based on this one, with the date-time adjusted. * The adjustment takes place using the specified adjuster strategy object. * Read the documentation of the adjuster to understand what adjustment will be made. * <p> * A simple adjuster might simply set the one of the fields, such as the year field. * A more complex adjuster might set the date to the last day of the month. * A selection of common adjustments is provided in {@link java.time.temporal.Adjusters}. * These include finding the "last day of the month" and "next Wednesday". * Key date-time classes also implement the {@code TemporalAdjuster} interface, ! * such as {@link Month} and {@link java.time.MonthDay MonthDay}. * The adjuster is responsible for handling special cases, such as the varying * lengths of month and leap years. * <p> * For example this code returns a date on the last day of July: * <pre>
*** 819,829 **** } /** * Returns a copy of this date-time with the specified field set to a new value. * <p> ! * This returns a new {@code OffsetDateTime}, based on this one, with the value * for the specified field changed. * This can be used to change any supported field, such as the year, month or day-of-month. * If it is not possible to set the value, because the field is not supported or for * some other reason, an exception is thrown. * <p> --- 840,850 ---- } /** * Returns a copy of this date-time with the specified field set to a new value. * <p> ! * TThis returns an {@code OffsetDateTime}, based on this one, with the value * for the specified field changed. * This can be used to change any supported field, such as the year, month or day-of-month. * If it is not possible to set the value, because the field is not supported or for * some other reason, an exception is thrown. * <p>
*** 847,857 **** * In this case, the offset is not part of the calculation and will be unchanged. * <p> * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.doWith(Temporal, long)} * passing {@code this} as the argument. In this case, the field determines * whether and how to adjust the instant. * <p> * This instance is immutable and unaffected by this method call. * --- 868,878 ---- * In this case, the offset is not part of the calculation and will be unchanged. * <p> * All other {@code ChronoField} instances will throw a {@code DateTimeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method ! * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} * passing {@code this} as the argument. In this case, the field determines * whether and how to adjust the instant. * <p> * This instance is immutable and unaffected by this method call. *
*** 871,881 **** return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue))); } } return with(dateTime.with(field, newValue), offset); } ! return field.doWith(this, newValue); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetDateTime} with the year altered. --- 892,902 ---- return with(dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue))); } } return with(dateTime.with(field, newValue), offset); } ! return field.adjustInto(this, newValue); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetDateTime} with the year altered.
*** 914,925 **** * <p> * This instance is immutable and unaffected by this method call. * * @param dayOfMonth the day-of-month to set in the result, from 1 to 28-31 * @return an {@code OffsetDateTime} based on this date-time with the requested day, not null ! * @throws DateTimeException if the day-of-month value is invalid ! * @throws DateTimeException if the day-of-month is invalid for the month-year */ public OffsetDateTime withDayOfMonth(int dayOfMonth) { return with(dateTime.withDayOfMonth(dayOfMonth), offset); } --- 935,946 ---- * <p> * This instance is immutable and unaffected by this method call. * * @param dayOfMonth the day-of-month to set in the result, from 1 to 28-31 * @return an {@code OffsetDateTime} based on this date-time with the requested day, not null ! * @throws DateTimeException if the day-of-month value is invalid, ! * or if the day-of-month is invalid for the month-year */ public OffsetDateTime withDayOfMonth(int dayOfMonth) { return with(dateTime.withDayOfMonth(dayOfMonth), offset); }
*** 929,940 **** * <p> * This instance is immutable and unaffected by this method call. * * @param dayOfYear the day-of-year to set in the result, from 1 to 365-366 * @return an {@code OffsetDateTime} based on this date with the requested day, not null ! * @throws DateTimeException if the day-of-year value is invalid ! * @throws DateTimeException if the day-of-year is invalid for the year */ public OffsetDateTime withDayOfYear(int dayOfYear) { return with(dateTime.withDayOfYear(dayOfYear), offset); } --- 950,961 ---- * <p> * This instance is immutable and unaffected by this method call. * * @param dayOfYear the day-of-year to set in the result, from 1 to 365-366 * @return an {@code OffsetDateTime} based on this date with the requested day, not null ! * @throws DateTimeException if the day-of-year value is invalid, ! * or if the day-of-year is invalid for the year */ public OffsetDateTime withDayOfYear(int dayOfYear) { return with(dateTime.withDayOfYear(dayOfYear), offset); }
*** 1006,1017 **** * Truncation returns a copy of the original date-time with fields * smaller than the specified unit set to zero. * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit * will set the second-of-minute and nano-of-second field to zero. * <p> ! * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time ! * units with an exact duration can be used, other units throw an exception. * <p> * The offset does not affect the calculation and will be the same in the result. * <p> * This instance is immutable and unaffected by this method call. * --- 1027,1040 ---- * Truncation returns a copy of the original date-time with fields * smaller than the specified unit set to zero. * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit * will set the second-of-minute and nano-of-second field to zero. * <p> ! * The unit must have a {@linkplain TemporalUnit#getDuration() duration} ! * that divides into the length of a standard day without remainder. ! * This includes all supplied time units on {@link ChronoUnit} and ! * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception. * <p> * The offset does not affect the calculation and will be the same in the result. * <p> * This instance is immutable and unaffected by this method call. *
*** 1023,1075 **** return with(dateTime.truncatedTo(unit), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this date-time with the specified period added. * <p> ! * This method returns a new date-time based on this time with the specified period added. ! * The adder is typically {@link java.time.Period} but may be any other type implementing ! * the {@link TemporalAdder} interface. ! * The calculation is delegated to the specified adjuster, which typically calls ! * back to {@link #plus(long, TemporalUnit)}. ! * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * ! * @param adder the adder to use, not null * @return an {@code OffsetDateTime} based on this date-time with the addition made, not null * @throws DateTimeException if the addition cannot be made * @throws ArithmeticException if numeric overflow occurs */ @Override ! public OffsetDateTime plus(TemporalAdder adder) { ! return (OffsetDateTime) adder.addTo(this); } /** ! * Returns a copy of this date-time with the specified period added. * <p> ! * This method returns a new date-time based on this date-time with the specified period added. ! * This can be used to add any period that is defined by a unit, for example to add years, months or days. ! * The unit is responsible for the details of the calculation, including the resolution ! * of any edge cases in the calculation. * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * * @param amountToAdd the amount of the unit to add to the result, may be negative ! * @param unit the unit of the period to add, not null ! * @return an {@code OffsetDateTime} based on this date-time with the specified period added, not null ! * @throws DateTimeException if the unit cannot be added to this type */ @Override public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit), offset); } ! return unit.doPlus(this, amountToAdd); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetDateTime} with the specified period in years added. --- 1046,1109 ---- return with(dateTime.truncatedTo(unit), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this date-time with the specified amount added. * <p> ! * This returns an {@code OffsetDateTime}, based on this one, with the specified amount added. ! * The amount is typically {@link Period} or {@link Duration} but may be ! * any other type implementing the {@link TemporalAmount} interface. ! * <p> ! * The calculation is delegated to the amount object by calling ! * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free ! * to implement the addition in any way it wishes, however it typically ! * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation ! * of the amount implementation to determine if it can be successfully added. * <p> * This instance is immutable and unaffected by this method call. * ! * @param amountToAdd the amount to add, not null * @return an {@code OffsetDateTime} based on this date-time with the addition made, not null * @throws DateTimeException if the addition cannot be made * @throws ArithmeticException if numeric overflow occurs */ @Override ! public OffsetDateTime plus(TemporalAmount amountToAdd) { ! return (OffsetDateTime) amountToAdd.addTo(this); } /** ! * Returns a copy of this date-time with the specified amount added. ! * <p> ! * This returns an {@code OffsetDateTime}, based on this one, with the amount ! * in terms of the unit added. If it is not possible to add the amount, because the ! * unit is not supported or for some other reason, an exception is thrown. * <p> ! * If the field is a {@link ChronoUnit} then the addition is implemented by ! * {@link LocalDateTime#plus(long, TemporalUnit)}. * The offset is not part of the calculation and will be unchanged in the result. * <p> + * If the field is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)} + * passing {@code this} as the argument. In this case, the unit determines + * whether and how to perform the addition. + * <p> * This instance is immutable and unaffected by this method call. * * @param amountToAdd the amount of the unit to add to the result, may be negative ! * @param unit the unit of the amount to add, not null ! * @return an {@code OffsetDateTime} based on this date-time with the specified amount added, not null ! * @throws DateTimeException if the addition cannot be made ! * @throws ArithmeticException if numeric overflow occurs */ @Override public OffsetDateTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit), offset); } ! return unit.addTo(this, amountToAdd); } //----------------------------------------------------------------------- /** * Returns a copy of this {@code OffsetDateTime} with the specified period in years added.
*** 1209,1253 **** return with(dateTime.plusNanos(nanos), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this date-time with the specified period subtracted. * <p> ! * This method returns a new date-time based on this time with the specified period subtracted. ! * The subtractor is typically {@link java.time.Period} but may be any other type implementing ! * the {@link TemporalSubtractor} interface. ! * The calculation is delegated to the specified adjuster, which typically calls ! * back to {@link #minus(long, TemporalUnit)}. ! * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * ! * @param subtractor the subtractor to use, not null * @return an {@code OffsetDateTime} based on this date-time with the subtraction made, not null * @throws DateTimeException if the subtraction cannot be made * @throws ArithmeticException if numeric overflow occurs */ @Override ! public OffsetDateTime minus(TemporalSubtractor subtractor) { ! return (OffsetDateTime) subtractor.subtractFrom(this); } /** ! * Returns a copy of this date-time with the specified period subtracted. * <p> ! * This method returns a new date-time based on this date-time with the specified period subtracted. ! * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days. ! * The unit is responsible for the details of the calculation, including the resolution ! * of any edge cases in the calculation. ! * The offset is not part of the calculation and will be unchanged in the result. * <p> * This instance is immutable and unaffected by this method call. * * @param amountToSubtract the amount of the unit to subtract from the result, may be negative ! * @param unit the unit of the period to subtract, not null ! * @return an {@code OffsetDateTime} based on this date-time with the specified period subtracted, not null */ @Override public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) { return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); } --- 1243,1293 ---- return with(dateTime.plusNanos(nanos), offset); } //----------------------------------------------------------------------- /** ! * Returns a copy of this date-time with the specified amount subtracted. * <p> ! * This returns an {@code OffsetDateTime}, based on this one, with the specified amount subtracted. ! * The amount is typically {@link Period} or {@link Duration} but may be ! * any other type implementing the {@link TemporalAmount} interface. ! * <p> ! * The calculation is delegated to the amount object by calling ! * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free ! * to implement the subtraction in any way it wishes, however it typically ! * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation ! * of the amount implementation to determine if it can be successfully subtracted. * <p> * This instance is immutable and unaffected by this method call. * ! * @param amountToSubtract the amount to subtract, not null * @return an {@code OffsetDateTime} based on this date-time with the subtraction made, not null * @throws DateTimeException if the subtraction cannot be made * @throws ArithmeticException if numeric overflow occurs */ @Override ! public OffsetDateTime minus(TemporalAmount amountToSubtract) { ! return (OffsetDateTime) amountToSubtract.subtractFrom(this); } /** ! * Returns a copy of this date-time with the specified amount subtracted. * <p> ! * This returns an {@code OffsetDateTime}, based on this one, with the amount ! * in terms of the unit subtracted. If it is not possible to subtract the amount, ! * because the unit is not supported or for some other reason, an exception is thrown. ! * <p> ! * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated. ! * See that method for a full description of how addition, and thus subtraction, works. * <p> * This instance is immutable and unaffected by this method call. * * @param amountToSubtract the amount of the unit to subtract from the result, may be negative ! * @param unit the unit of the amount to subtract, not null ! * @return an {@code OffsetDateTime} based on this date-time with the specified amount subtracted, not null ! * @throws DateTimeException if the subtraction cannot be made ! * @throws ArithmeticException if numeric overflow occurs */ @Override public OffsetDateTime minus(long amountToSubtract, TemporalUnit unit) { return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); }
*** 1411,1428 **** * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public <R> R query(TemporalQuery<R> query) { ! if (query == Queries.chrono()) { ! return (R) getDate().getChrono(); } else if (query == Queries.precision()) { return (R) NANOS; - } else if (query == Queries.offset() || query == Queries.zone()) { - return (R) getOffset(); } ! return Temporal.super.query(query); } /** * Adjusts the specified temporal object to have the same offset, date * and time as this object. --- 1451,1476 ---- * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public <R> R query(TemporalQuery<R> query) { ! if (query == Queries.offset() || query == Queries.zone()) { ! return (R) getOffset(); ! } else if (query == Queries.zoneId()) { ! return null; ! } else if (query == Queries.localDate()) { ! return (R) toLocalDate(); ! } else if (query == Queries.localTime()) { ! return (R) toLocalTime(); ! } else if (query == Queries.chronology()) { ! return (R) IsoChronology.INSTANCE; } else if (query == Queries.precision()) { return (R) NANOS; } ! // inline TemporalAccessor.super.query(query) as an optimization ! // non-JDK classes are not permitted to make this optimization ! return query.queryFrom(this); } /** * Adjusts the specified temporal object to have the same offset, date * and time as this object.
*** 1451,1462 **** */ @Override public Temporal adjustInto(Temporal temporal) { return temporal .with(OFFSET_SECONDS, getOffset().getTotalSeconds()) ! .with(EPOCH_DAY, getDate().toEpochDay()) ! .with(NANO_OF_DAY, getTime().toNanoOfDay()); } /** * Calculates the period between this date-time and another date-time in * terms of the specified unit. --- 1499,1510 ---- */ @Override public Temporal adjustInto(Temporal temporal) { return temporal .with(OFFSET_SECONDS, getOffset().getTotalSeconds()) ! .with(EPOCH_DAY, toLocalDate().toEpochDay()) ! .with(NANO_OF_DAY, toLocalTime().toNanoOfDay()); } /** * Calculates the period between this date-time and another date-time in * terms of the specified unit.
*** 1474,1491 **** * The calculation returns a whole number, representing the number of * complete units between the two date-times. * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z * will only be one month as it is one minute short of two months. * <p> ! * This method operates in association with {@link TemporalUnit#between}. ! * The result of this method is a {@code long} representing the amount of ! * the specified unit. By contrast, the result of {@code between} is an ! * object that can be used directly in addition/subtraction: * <pre> ! * long period = start.periodUntil(end, MONTHS); // this method ! * dateTime.plus(MONTHS.between(start, end)); // use in plus/minus * </pre> * <p> * The calculation is implemented in this method for {@link ChronoUnit}. * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS}, * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS}, * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES}, --- 1522,1540 ---- * The calculation returns a whole number, representing the number of * complete units between the two date-times. * For example, the period in months between 2012-06-15T00:00Z and 2012-08-14T23:59Z * will only be one month as it is one minute short of two months. * <p> ! * There are two equivalent ways of using this method. ! * The first is to invoke this method. ! * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> ! * // these two lines are equivalent ! * amount = start.periodUntil(end, MONTHS); ! * amount = MONTHS.between(start, end); * </pre> + * The choice should be made based on which makes the code more readable. * <p> * The calculation is implemented in this method for {@link ChronoUnit}. * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS}, * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS}, * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},
*** 1514,1549 **** if (unit instanceof ChronoUnit) { OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); return dateTime.periodUntil(end.dateTime, unit); } ! return unit.between(this, endDateTime).getAmount(); } //----------------------------------------------------------------------- /** ! * Returns a zoned date-time formed from the instant represented by this ! * date-time and the specified zone ID. * <p> * This conversion will ignore the visible local date-time and use the underlying instant instead. * This avoids any problems with local time-line gaps or overlaps. * The result might have different values for fields such as hour, minute an even day. * <p> * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}. * To use the offset as the zone ID, use {@link #toZonedDateTime()}. - * <p> - * This instance is immutable and unaffected by this method call. * * @param zone the time-zone to use, not null * @return the zoned date-time formed from this date-time, not null */ public ZonedDateTime atZoneSameInstant(ZoneId zone) { return ZonedDateTime.ofInstant(dateTime, offset, zone); } /** ! * Returns a zoned date-time formed from this date-time and the specified zone ID. * <p> * Time-zone rules, such as daylight savings, mean that not every time on the * local time-line exists. If the local date-time is in a gap or overlap according to * the rules then a resolver is used to determine the resultant local time and offset. * This method uses {@link ZonedDateTime#ofLocal(LocalDateTime, ZoneId, ZoneOffset)} --- 1563,1601 ---- if (unit instanceof ChronoUnit) { OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); return dateTime.periodUntil(end.dateTime, unit); } ! return unit.between(this, endDateTime); } //----------------------------------------------------------------------- /** ! * Combines this date-time with a time-zone to create a {@code ZonedDateTime} ! * ensuring that the result has the same instant. * <p> + * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone. * This conversion will ignore the visible local date-time and use the underlying instant instead. * This avoids any problems with local time-line gaps or overlaps. * The result might have different values for fields such as hour, minute an even day. * <p> * To attempt to retain the values of the fields, use {@link #atZoneSimilarLocal(ZoneId)}. * To use the offset as the zone ID, use {@link #toZonedDateTime()}. * * @param zone the time-zone to use, not null * @return the zoned date-time formed from this date-time, not null */ public ZonedDateTime atZoneSameInstant(ZoneId zone) { return ZonedDateTime.ofInstant(dateTime, offset, zone); } /** ! * Combines this date-time with a time-zone to create a {@code ZonedDateTime} ! * trying to keep the same local date and time. ! * <p> ! * This returns a {@code ZonedDateTime} formed from this date-time and the specified time-zone. ! * Where possible, the result will have the same local date-time as this object. * <p> * Time-zone rules, such as daylight savings, mean that not every time on the * local time-line exists. If the local date-time is in a gap or overlap according to * the rules then a resolver is used to determine the resultant local time and offset. * This method uses {@link ZonedDateTime#ofLocal(LocalDateTime, ZoneId, ZoneOffset)}
*** 1554,1594 **** * {@link ZonedDateTime#withLaterOffsetAtOverlap()} immediately after this method. * <p> * To create a zoned date-time at the same instant irrespective of the local time-line, * use {@link #atZoneSameInstant(ZoneId)}. * To use the offset as the zone ID, use {@link #toZonedDateTime()}. - * <p> - * This instance is immutable and unaffected by this method call. * * @param zone the time-zone to use, not null * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null */ public ZonedDateTime atZoneSimilarLocal(ZoneId zone) { return ZonedDateTime.ofLocal(dateTime, zone, offset); } //----------------------------------------------------------------------- /** - * Converts this date-time to an {@code OffsetDate}. - * <p> - * This returns an offset date with the same local date and offset. - * - * @return an OffsetDate representing the date and offset, not null - */ - public OffsetDate toOffsetDate() { - return OffsetDate.of(dateTime.getDate(), offset); - } - - /** * Converts this date-time to an {@code OffsetTime}. * <p> * This returns an offset time with the same local time and offset. * * @return an OffsetTime representing the time and offset, not null */ public OffsetTime toOffsetTime() { ! return OffsetTime.of(dateTime.getTime(), offset); } /** * Converts this date-time to a {@code ZonedDateTime} using the offset as the zone ID. * <p> --- 1606,1633 ---- * {@link ZonedDateTime#withLaterOffsetAtOverlap()} immediately after this method. * <p> * To create a zoned date-time at the same instant irrespective of the local time-line, * use {@link #atZoneSameInstant(ZoneId)}. * To use the offset as the zone ID, use {@link #toZonedDateTime()}. * * @param zone the time-zone to use, not null * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null */ public ZonedDateTime atZoneSimilarLocal(ZoneId zone) { return ZonedDateTime.ofLocal(dateTime, zone, offset); } //----------------------------------------------------------------------- /** * Converts this date-time to an {@code OffsetTime}. * <p> * This returns an offset time with the same local time and offset. * * @return an OffsetTime representing the time and offset, not null */ public OffsetTime toOffsetTime() { ! return OffsetTime.of(dateTime.toLocalTime(), offset); } /** * Converts this date-time to a {@code ZonedDateTime} using the offset as the zone ID. * <p>
*** 1604,1613 **** --- 1643,1655 ---- return ZonedDateTime.of(dateTime, offset); } /** * Converts this date-time to an {@code Instant}. + * <p> + * This returns an {@code Instant} representing the same point on the + * time-line as this date-time. * * @return an {@code Instant} representing the same instant, not null */ public Instant toInstant() { return dateTime.toInstant(offset);
*** 1651,1667 **** * @return the comparator value, negative if less, positive if greater */ @Override public int compareTo(OffsetDateTime other) { if (getOffset().equals(other.getOffset())) { ! return getDateTime().compareTo(other.getDateTime()); } int cmp = Long.compare(toEpochSecond(), other.toEpochSecond()); if (cmp == 0) { ! cmp = getTime().getNano() - other.getTime().getNano(); if (cmp == 0) { ! cmp = getDateTime().compareTo(other.getDateTime()); } } return cmp; } --- 1693,1709 ---- * @return the comparator value, negative if less, positive if greater */ @Override public int compareTo(OffsetDateTime other) { if (getOffset().equals(other.getOffset())) { ! return toLocalDateTime().compareTo(other.toLocalDateTime()); } int cmp = Long.compare(toEpochSecond(), other.toEpochSecond()); if (cmp == 0) { ! cmp = toLocalTime().getNano() - other.toLocalTime().getNano(); if (cmp == 0) { ! cmp = toLocalDateTime().compareTo(other.toLocalDateTime()); } } return cmp; }
*** 1678,1688 **** */ public boolean isAfter(OffsetDateTime other) { long thisEpochSec = toEpochSecond(); long otherEpochSec = other.toEpochSecond(); return thisEpochSec > otherEpochSec || ! (thisEpochSec == otherEpochSec && getTime().getNano() > other.getTime().getNano()); } /** * Checks if the instant of this date-time is before that of the specified date-time. * <p> --- 1720,1730 ---- */ public boolean isAfter(OffsetDateTime other) { long thisEpochSec = toEpochSecond(); long otherEpochSec = other.toEpochSecond(); return thisEpochSec > otherEpochSec || ! (thisEpochSec == otherEpochSec && toLocalTime().getNano() > other.toLocalTime().getNano()); } /** * Checks if the instant of this date-time is before that of the specified date-time. * <p>
*** 1695,1705 **** */ public boolean isBefore(OffsetDateTime other) { long thisEpochSec = toEpochSecond(); long otherEpochSec = other.toEpochSecond(); return thisEpochSec < otherEpochSec || ! (thisEpochSec == otherEpochSec && getTime().getNano() < other.getTime().getNano()); } /** * Checks if the instant of this date-time is equal to that of the specified date-time. * <p> --- 1737,1747 ---- */ public boolean isBefore(OffsetDateTime other) { long thisEpochSec = toEpochSecond(); long otherEpochSec = other.toEpochSecond(); return thisEpochSec < otherEpochSec || ! (thisEpochSec == otherEpochSec && toLocalTime().getNano() < other.toLocalTime().getNano()); } /** * Checks if the instant of this date-time is equal to that of the specified date-time. * <p>
*** 1710,1720 **** * @param other the other date-time to compare to, not null * @return true if the instant equals the instant of the specified date-time */ public boolean isEqual(OffsetDateTime other) { return toEpochSecond() == other.toEpochSecond() && ! getTime().getNano() == other.getTime().getNano(); } //----------------------------------------------------------------------- /** * Checks if this date-time is equal to another date-time. --- 1752,1762 ---- * @param other the other date-time to compare to, not null * @return true if the instant equals the instant of the specified date-time */ public boolean isEqual(OffsetDateTime other) { return toEpochSecond() == other.toEpochSecond() && ! toLocalTime().getNano() == other.toLocalTime().getNano(); } //----------------------------------------------------------------------- /** * Checks if this date-time is equal to another date-time.
*** 1772,1798 **** /** * Outputs this date-time as a {@code String} using the formatter. * <p> * This date-time will be passed to the formatter ! * {@link DateTimeFormatter#print(TemporalAccessor) print method}. * * @param formatter the formatter to use, not null * @return the formatted date-time string, not null * @throws DateTimeException if an error occurs during printing */ public String toString(DateTimeFormatter formatter) { Objects.requireNonNull(formatter, "formatter"); ! return formatter.print(this); } //----------------------------------------------------------------------- /** * Writes the object using a * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>. * <pre> ! * out.writeByte(3); // identifies this as a OffsetDateTime * out.writeObject(dateTime); * out.writeObject(offset); * </pre> * * @return the instance of {@code Ser}, not null --- 1814,1840 ---- /** * Outputs this date-time as a {@code String} using the formatter. * <p> * This date-time will be passed to the formatter ! * {@link DateTimeFormatter#format(TemporalAccessor) format method}. * * @param formatter the formatter to use, not null * @return the formatted date-time string, not null * @throws DateTimeException if an error occurs during printing */ public String toString(DateTimeFormatter formatter) { Objects.requireNonNull(formatter, "formatter"); ! return formatter.format(this); } //----------------------------------------------------------------------- /** * Writes the object using a * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>. * <pre> ! * out.writeByte(10); // identifies this as a OffsetDateTime * out.writeObject(dateTime); * out.writeObject(offset); * </pre> * * @return the instance of {@code Ser}, not null