src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.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.ChronoUnit.SECONDS; import java.io.IOException; import java.io.InvalidObjectException; --- 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.chrono; import static java.time.temporal.ChronoUnit.SECONDS; import java.io.IOException; import java.io.InvalidObjectException;
*** 72,81 **** --- 72,86 ---- import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; + import java.time.temporal.ChronoField; + import java.time.temporal.ChronoUnit; + import java.time.temporal.Temporal; + import java.time.temporal.TemporalField; + import java.time.temporal.TemporalUnit; import java.time.zone.ZoneOffsetTransition; import java.time.zone.ZoneRules; import java.util.List; import java.util.Objects;
*** 91,115 **** * Information about the local-time can be obtained using methods on the time-zone. * * <h3>Specification for implementors</h3> * This class is immutable and thread-safe. * ! * @param <C> the chronology of this date * @since 1.8 */ ! final class ChronoZonedDateTimeImpl<C extends Chrono<C>> ! implements ChronoZonedDateTime<C>, Serializable { /** * Serialization version. */ private static final long serialVersionUID = -5261813987200935591L; /** * The local date-time. */ ! private final ChronoLocalDateTimeImpl<C> dateTime; /** * The zone offset. */ private final ZoneOffset offset; /** --- 96,120 ---- * Information about the local-time can be obtained using methods on the time-zone. * * <h3>Specification for implementors</h3> * This class is immutable and thread-safe. * ! * @param <D> the concrete type for the date of this date-time * @since 1.8 */ ! final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate<D>> ! implements ChronoZonedDateTime<D>, Serializable { /** * Serialization version. */ private static final long serialVersionUID = -5261813987200935591L; /** * The local date-time. */ ! private final ChronoLocalDateTimeImpl<D> dateTime; /** * The zone offset. */ private final ZoneOffset offset; /**
*** 124,139 **** * @param localDateTime the local date-time, not null * @param zone the zone identifier, not null * @param preferredOffset the zone offset, null if no preference * @return the zoned date-time, not null */ ! static <R extends Chrono<R>> ChronoZonedDateTime<R> ofBest( ChronoLocalDateTimeImpl<R> localDateTime, ZoneId zone, ZoneOffset preferredOffset) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zone, "zone"); if (zone instanceof ZoneOffset) { ! return new ChronoZonedDateTimeImpl<R>(localDateTime, (ZoneOffset) zone, zone); } ZoneRules rules = zone.getRules(); LocalDateTime isoLDT = LocalDateTime.from(localDateTime); List<ZoneOffset> validOffsets = rules.getValidOffsets(isoLDT); ZoneOffset offset; --- 129,144 ---- * @param localDateTime the local date-time, not null * @param zone the zone identifier, not null * @param preferredOffset the zone offset, null if no preference * @return the zoned date-time, not null */ ! static <R extends ChronoLocalDate<R>> ChronoZonedDateTime<R> ofBest( ChronoLocalDateTimeImpl<R> localDateTime, ZoneId zone, ZoneOffset preferredOffset) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zone, "zone"); if (zone instanceof ZoneOffset) { ! return new ChronoZonedDateTimeImpl<>(localDateTime, (ZoneOffset) zone, zone); } ZoneRules rules = zone.getRules(); LocalDateTime isoLDT = LocalDateTime.from(localDateTime); List<ZoneOffset> validOffsets = rules.getValidOffsets(isoLDT); ZoneOffset offset;
*** 149,198 **** } else { offset = validOffsets.get(0); } } Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules ! return new ChronoZonedDateTimeImpl<R>(localDateTime, offset, zone); } /** * Obtains an instance from an instant using the specified time-zone. * * @param chrono the chronology, not null * @param instant the instant, not null * @param zone the zone identifier, not null * @return the zoned date-time, not null */ ! static <R extends Chrono<R>> ChronoZonedDateTimeImpl<R> ofInstant(Chrono<R> chrono, Instant instant, ZoneId zone) { ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset); ! ChronoLocalDateTimeImpl<R> cldt = (ChronoLocalDateTimeImpl<R>) chrono.localDateTime(ldt); ! return new ChronoZonedDateTimeImpl<R>(cldt, offset, zone); } /** * Obtains an instance from an {@code Instant}. * * @param instant the instant to create the date-time from, not null * @param zone the time-zone to use, validated not null * @return the zoned date-time, validated not null */ ! private ChronoZonedDateTimeImpl<C> create(Instant instant, ZoneId zone) { ! return ofInstant(getDate().getChrono(), instant, zone); } //----------------------------------------------------------------------- /** * Constructor. * * @param dateTime the date-time, not null * @param offset the zone offset, not null * @param zone the zone ID, not null */ ! private ChronoZonedDateTimeImpl(ChronoLocalDateTimeImpl<C> dateTime, ZoneOffset offset, ZoneId zone) { this.dateTime = Objects.requireNonNull(dateTime, "dateTime"); this.offset = Objects.requireNonNull(offset, "offset"); this.zone = Objects.requireNonNull(zone, "zone"); } --- 154,203 ---- } else { offset = validOffsets.get(0); } } Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules ! return new ChronoZonedDateTimeImpl<>(localDateTime, offset, zone); } /** * Obtains an instance from an instant using the specified time-zone. * * @param chrono the chronology, not null * @param instant the instant, not null * @param zone the zone identifier, not null * @return the zoned date-time, not null */ ! static ChronoZonedDateTimeImpl<?> ofInstant(Chronology chrono, Instant instant, ZoneId zone) { ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset); ! ChronoLocalDateTimeImpl<?> cldt = (ChronoLocalDateTimeImpl<?>) chrono.localDateTime(ldt); ! return new ChronoZonedDateTimeImpl(cldt, offset, zone); } /** * Obtains an instance from an {@code Instant}. * * @param instant the instant to create the date-time from, not null * @param zone the time-zone to use, validated not null * @return the zoned date-time, validated not null */ ! private ChronoZonedDateTimeImpl<D> create(Instant instant, ZoneId zone) { ! return (ChronoZonedDateTimeImpl<D>)ofInstant(toLocalDate().getChronology(), instant, zone); } //----------------------------------------------------------------------- /** * Constructor. * * @param dateTime the date-time, not null * @param offset the zone offset, not null * @param zone the zone ID, not null */ ! private ChronoZonedDateTimeImpl(ChronoLocalDateTimeImpl<D> dateTime, ZoneOffset offset, ZoneId zone) { this.dateTime = Objects.requireNonNull(dateTime, "dateTime"); this.offset = Objects.requireNonNull(offset, "offset"); this.zone = Objects.requireNonNull(zone, "zone"); }
*** 200,261 **** public ZoneOffset getOffset() { return offset; } @Override ! public ChronoZonedDateTime<C> withEarlierOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null && trans.isOverlap()) { ZoneOffset earlierOffset = trans.getOffsetBefore(); if (earlierOffset.equals(offset) == false) { ! return new ChronoZonedDateTimeImpl<C>(dateTime, earlierOffset, zone); } } return this; } @Override ! public ChronoZonedDateTime<C> withLaterOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null) { ZoneOffset offset = trans.getOffsetAfter(); if (offset.equals(getOffset()) == false) { ! return new ChronoZonedDateTimeImpl<C>(dateTime, offset, zone); } } return this; } //----------------------------------------------------------------------- @Override ! public ChronoLocalDateTime<C> getDateTime() { return dateTime; } public ZoneId getZone() { return zone; } ! public ChronoZonedDateTime<C> withZoneSameLocal(ZoneId zone) { return ofBest(dateTime, zone, offset); } @Override ! public ChronoZonedDateTime<C> withZoneSameInstant(ZoneId zone) { Objects.requireNonNull(zone, "zone"); return this.zone.equals(zone) ? this : create(dateTime.toInstant(offset), zone); } //----------------------------------------------------------------------- @Override public boolean isSupported(TemporalField field) { ! return field instanceof ChronoField || (field != null && field.doIsSupported(this)); } //----------------------------------------------------------------------- @Override ! public ChronoZonedDateTime<C> with(TemporalField field, long newValue) { if (field instanceof ChronoField) { ChronoField f = (ChronoField) field; switch (f) { case INSTANT_SECONDS: return plus(newValue - toEpochSecond(), SECONDS); case OFFSET_SECONDS: { --- 205,266 ---- public ZoneOffset getOffset() { return offset; } @Override ! public ChronoZonedDateTime<D> withEarlierOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null && trans.isOverlap()) { ZoneOffset earlierOffset = trans.getOffsetBefore(); if (earlierOffset.equals(offset) == false) { ! return new ChronoZonedDateTimeImpl<D>(dateTime, earlierOffset, zone); } } return this; } @Override ! public ChronoZonedDateTime<D> withLaterOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null) { ZoneOffset offset = trans.getOffsetAfter(); if (offset.equals(getOffset()) == false) { ! return new ChronoZonedDateTimeImpl<D>(dateTime, offset, zone); } } return this; } //----------------------------------------------------------------------- @Override ! public ChronoLocalDateTime<D> toLocalDateTime() { return dateTime; } public ZoneId getZone() { return zone; } ! public ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone) { return ofBest(dateTime, zone, offset); } @Override ! public ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone) { Objects.requireNonNull(zone, "zone"); return this.zone.equals(zone) ? this : create(dateTime.toInstant(offset), zone); } //----------------------------------------------------------------------- @Override public boolean isSupported(TemporalField field) { ! return field instanceof ChronoField || (field != null && field.isSupportedBy(this)); } //----------------------------------------------------------------------- @Override ! public ChronoZonedDateTime<D> with(TemporalField field, long newValue) { if (field instanceof ChronoField) { ChronoField f = (ChronoField) field; switch (f) { case INSTANT_SECONDS: return plus(newValue - toEpochSecond(), SECONDS); case OFFSET_SECONDS: {
*** 263,300 **** return create(dateTime.toInstant(offset), zone); } } return ofBest(dateTime.with(field, newValue), zone, offset); } ! return getDate().getChrono().ensureChronoZonedDateTime(field.doWith(this, newValue)); } //----------------------------------------------------------------------- @Override ! public ChronoZonedDateTime<C> plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } ! return getDate().getChrono().ensureChronoZonedDateTime(unit.doPlus(this, amountToAdd)); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @Override public long periodUntil(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoZonedDateTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } @SuppressWarnings("unchecked") ! ChronoZonedDateTime<C> end = (ChronoZonedDateTime<C>) endDateTime; ! if (getDate().getChrono().equals(end.getDate().getChrono()) == false) { throw new DateTimeException("Unable to calculate period between two different chronologies"); } if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); ! return dateTime.periodUntil(end.getDateTime(), unit); } ! return unit.between(this, endDateTime).getAmount(); } //----------------------------------------------------------------------- private Object writeReplace() { return new Ser(Ser.CHRONO_ZONE_DATE_TIME_TYPE, this); --- 268,305 ---- return create(dateTime.toInstant(offset), zone); } } return ofBest(dateTime.with(field, newValue), zone, offset); } ! return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(field.adjustInto(this, newValue))); } //----------------------------------------------------------------------- @Override ! public ChronoZonedDateTime<D> plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } ! return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd))); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @Override public long periodUntil(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoZonedDateTime == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } @SuppressWarnings("unchecked") ! ChronoZonedDateTime<D> end = (ChronoZonedDateTime<D>) endDateTime; ! if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) { throw new DateTimeException("Unable to calculate period between two different chronologies"); } if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); ! return dateTime.periodUntil(end.toLocalDateTime(), unit); } ! return unit.between(this, endDateTime); } //----------------------------------------------------------------------- private Object writeReplace() { return new Ser(Ser.CHRONO_ZONE_DATE_TIME_TYPE, this);
*** 335,350 **** return false; } @Override public int hashCode() { ! return getDateTime().hashCode() ^ getOffset().hashCode() ^ Integer.rotateLeft(getZone().hashCode(), 3); } @Override public String toString() { ! String str = getDateTime().toString() + getOffset().toString(); if (getOffset() != getZone()) { str += '[' + getZone().toString() + ']'; } return str; } --- 340,355 ---- return false; } @Override public int hashCode() { ! return toLocalDateTime().hashCode() ^ getOffset().hashCode() ^ Integer.rotateLeft(getZone().hashCode(), 3); } @Override public String toString() { ! String str = toLocalDateTime().toString() + getOffset().toString(); if (getOffset() != getZone()) { str += '[' + getZone().toString() + ']'; } return str; }