126 * This class is immutable and thread-safe.
127 *
128 * @since 1.8
129 */
130 public final class ZoneOffset
131 extends ZoneId
132 implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable {
133
134 /** Cache of time-zone offset by offset in seconds. */
135 private static final ConcurrentMap<Integer, ZoneOffset> SECONDS_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
136 /** Cache of time-zone offset by ID. */
137 private static final ConcurrentMap<String, ZoneOffset> ID_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
138
139 /**
140 * The abs maximum seconds.
141 */
142 private static final int MAX_SECONDS = 18 * SECONDS_PER_HOUR;
143 /**
144 * Serialization version.
145 */
146 private static final long serialVersionUID = 2357656521762053153L;
147
148 /**
149 * The time-zone offset for UTC, with an ID of 'Z'.
150 */
151 public static final ZoneOffset UTC = ZoneOffset.ofTotalSeconds(0);
152 /**
153 * Constant for the minimum supported offset.
154 */
155 public static final ZoneOffset MIN = ZoneOffset.ofTotalSeconds(-MAX_SECONDS);
156 /**
157 * Constant for the maximum supported offset.
158 */
159 public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS);
160
161 /**
162 * The total offset in seconds.
163 */
164 private final int totalSeconds;
165 /**
746 public String toString() {
747 return id;
748 }
749
750 // -----------------------------------------------------------------------
751 /**
752 * Writes the object using a
753 * <a href="{@docRoot}/serialized-form.html#java.time.Ser">dedicated serialized form</a>.
754 * @serialData
755 * <pre>
756 * out.writeByte(8); // identifies a ZoneOffset
757 * int offsetByte = totalSeconds % 900 == 0 ? totalSeconds / 900 : 127;
758 * out.writeByte(offsetByte);
759 * if (offsetByte == 127) {
760 * out.writeInt(totalSeconds);
761 * }
762 * </pre>
763 *
764 * @return the instance of {@code Ser}, not null
765 */
766 private Object writeReplace() {
767 return new Ser(Ser.ZONE_OFFSET_TYPE, this);
768 }
769
770 /**
771 * Defend against malicious streams.
772 *
773 * @param s the stream to read
774 * @throws InvalidObjectException always
775 */
776 private void readObject(ObjectInputStream s) throws InvalidObjectException {
777 throw new InvalidObjectException("Deserialization via serialization delegate");
778 }
779
780 @Override
781 void write(DataOutput out) throws IOException {
782 out.writeByte(Ser.ZONE_OFFSET_TYPE);
783 writeExternal(out);
784 }
785
786 void writeExternal(DataOutput out) throws IOException {
787 final int offsetSecs = totalSeconds;
788 int offsetByte = offsetSecs % 900 == 0 ? offsetSecs / 900 : 127; // compress to -72 to +72
789 out.writeByte(offsetByte);
790 if (offsetByte == 127) {
791 out.writeInt(offsetSecs);
792 }
793 }
794
795 static ZoneOffset readExternal(DataInput in) throws IOException {
|
126 * This class is immutable and thread-safe.
127 *
128 * @since 1.8
129 */
130 public final class ZoneOffset
131 extends ZoneId
132 implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable {
133
134 /** Cache of time-zone offset by offset in seconds. */
135 private static final ConcurrentMap<Integer, ZoneOffset> SECONDS_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
136 /** Cache of time-zone offset by ID. */
137 private static final ConcurrentMap<String, ZoneOffset> ID_CACHE = new ConcurrentHashMap<>(16, 0.75f, 4);
138
139 /**
140 * The abs maximum seconds.
141 */
142 private static final int MAX_SECONDS = 18 * SECONDS_PER_HOUR;
143 /**
144 * Serialization version.
145 */
146 @java.io.Serial
147 private static final long serialVersionUID = 2357656521762053153L;
148
149 /**
150 * The time-zone offset for UTC, with an ID of 'Z'.
151 */
152 public static final ZoneOffset UTC = ZoneOffset.ofTotalSeconds(0);
153 /**
154 * Constant for the minimum supported offset.
155 */
156 public static final ZoneOffset MIN = ZoneOffset.ofTotalSeconds(-MAX_SECONDS);
157 /**
158 * Constant for the maximum supported offset.
159 */
160 public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS);
161
162 /**
163 * The total offset in seconds.
164 */
165 private final int totalSeconds;
166 /**
747 public String toString() {
748 return id;
749 }
750
751 // -----------------------------------------------------------------------
752 /**
753 * Writes the object using a
754 * <a href="{@docRoot}/serialized-form.html#java.time.Ser">dedicated serialized form</a>.
755 * @serialData
756 * <pre>
757 * out.writeByte(8); // identifies a ZoneOffset
758 * int offsetByte = totalSeconds % 900 == 0 ? totalSeconds / 900 : 127;
759 * out.writeByte(offsetByte);
760 * if (offsetByte == 127) {
761 * out.writeInt(totalSeconds);
762 * }
763 * </pre>
764 *
765 * @return the instance of {@code Ser}, not null
766 */
767 @java.io.Serial
768 private Object writeReplace() {
769 return new Ser(Ser.ZONE_OFFSET_TYPE, this);
770 }
771
772 /**
773 * Defend against malicious streams.
774 *
775 * @param s the stream to read
776 * @throws InvalidObjectException always
777 */
778 @java.io.Serial
779 private void readObject(ObjectInputStream s) throws InvalidObjectException {
780 throw new InvalidObjectException("Deserialization via serialization delegate");
781 }
782
783 @Override
784 void write(DataOutput out) throws IOException {
785 out.writeByte(Ser.ZONE_OFFSET_TYPE);
786 writeExternal(out);
787 }
788
789 void writeExternal(DataOutput out) throws IOException {
790 final int offsetSecs = totalSeconds;
791 int offsetByte = offsetSecs % 900 == 0 ? offsetSecs / 900 : 127; // compress to -72 to +72
792 out.writeByte(offsetByte);
793 if (offsetByte == 127) {
794 out.writeInt(offsetSecs);
795 }
796 }
797
798 static ZoneOffset readExternal(DataInput in) throws IOException {
|