Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/make/src/classes/build/tools/tzdb/ZoneOffsetTransition.java
32287 views
1
/*
2
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file:
31
*
32
* Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
33
*
34
* All rights reserved.
35
*
36
* Redistribution and use in source and binary forms, with or without
37
* modification, are permitted provided that the following conditions are met:
38
*
39
* * Redistributions of source code must retain the above copyright notice,
40
* this list of conditions and the following disclaimer.
41
*
42
* * Redistributions in binary form must reproduce the above copyright notice,
43
* this list of conditions and the following disclaimer in the documentation
44
* and/or other materials provided with the distribution.
45
*
46
* * Neither the name of JSR-310 nor the names of its contributors
47
* may be used to endorse or promote products derived from this software
48
* without specific prior written permission.
49
*
50
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61
*/
62
package build.tools.tzdb;
63
64
import java.util.Arrays;
65
import java.util.Collections;
66
import java.util.List;
67
import java.util.Objects;
68
69
/**
70
* A transition between two offsets caused by a discontinuity in the local time-line.
71
*
72
* @since 1.8
73
*/
74
final class ZoneOffsetTransition implements Comparable<ZoneOffsetTransition> {
75
76
/**
77
* The local transition date-time at the transition.
78
*/
79
private final LocalDateTime transition;
80
/**
81
* The offset before transition.
82
*/
83
private final ZoneOffset offsetBefore;
84
/**
85
* The offset after transition.
86
*/
87
private final ZoneOffset offsetAfter;
88
89
/**
90
* Creates an instance defining a transition between two offsets.
91
*
92
* @param transition the transition date-time with the offset before the transition, not null
93
* @param offsetBefore the offset before the transition, not null
94
* @param offsetAfter the offset at and after the transition, not null
95
*/
96
ZoneOffsetTransition(LocalDateTime transition, ZoneOffset offsetBefore, ZoneOffset offsetAfter) {
97
Objects.requireNonNull(transition, "transition");
98
Objects.requireNonNull(offsetBefore, "offsetBefore");
99
Objects.requireNonNull(offsetAfter, "offsetAfter");
100
if (offsetBefore.equals(offsetAfter)) {
101
throw new IllegalArgumentException("Offsets must not be equal");
102
}
103
this.transition = transition;
104
this.offsetBefore = offsetBefore;
105
this.offsetAfter = offsetAfter;
106
}
107
108
/**
109
* Creates an instance from epoch-second and offsets.
110
*
111
* @param epochSecond the transition epoch-second
112
* @param offsetBefore the offset before the transition, not null
113
* @param offsetAfter the offset at and after the transition, not null
114
*/
115
ZoneOffsetTransition(long epochSecond, ZoneOffset offsetBefore, ZoneOffset offsetAfter) {
116
this.transition = LocalDateTime.ofEpochSecond(epochSecond, 0, offsetBefore);
117
this.offsetBefore = offsetBefore;
118
this.offsetAfter = offsetAfter;
119
}
120
121
/**
122
* Gets the transition instant as an epoch second.
123
*
124
* @return the transition epoch second
125
*/
126
public long toEpochSecond() {
127
return transition.toEpochSecond(offsetBefore);
128
}
129
130
/**
131
* Gets the local transition date-time, as would be expressed with the 'before' offset.
132
* <p>
133
* This is the date-time where the discontinuity begins expressed with the 'before' offset.
134
* At this instant, the 'after' offset is actually used, therefore the combination of this
135
* date-time and the 'before' offset will never occur.
136
* <p>
137
* The combination of the 'before' date-time and offset represents the same instant
138
* as the 'after' date-time and offset.
139
*
140
* @return the transition date-time expressed with the before offset, not null
141
*/
142
public LocalDateTime getDateTimeBefore() {
143
return transition;
144
}
145
146
/**
147
* Gets the local transition date-time, as would be expressed with the 'after' offset.
148
* <p>
149
* This is the first date-time after the discontinuity, when the new offset applies.
150
* <p>
151
* The combination of the 'before' date-time and offset represents the same instant
152
* as the 'after' date-time and offset.
153
*
154
* @return the transition date-time expressed with the after offset, not null
155
*/
156
public LocalDateTime getDateTimeAfter() {
157
return transition.plusSeconds(getDurationSeconds());
158
}
159
160
/**
161
* Gets the offset before the transition.
162
* <p>
163
* This is the offset in use before the instant of the transition.
164
*
165
* @return the offset before the transition, not null
166
*/
167
public ZoneOffset getOffsetBefore() {
168
return offsetBefore;
169
}
170
171
/**
172
* Gets the offset after the transition.
173
* <p>
174
* This is the offset in use on and after the instant of the transition.
175
*
176
* @return the offset after the transition, not null
177
*/
178
public ZoneOffset getOffsetAfter() {
179
return offsetAfter;
180
}
181
182
/**
183
* Gets the duration of the transition in seconds.
184
*
185
* @return the duration in seconds
186
*/
187
private int getDurationSeconds() {
188
return getOffsetAfter().getTotalSeconds() - getOffsetBefore().getTotalSeconds();
189
}
190
191
/**
192
* Does this transition represent a gap in the local time-line.
193
* <p>
194
* Gaps occur where there are local date-times that simply do not not exist.
195
* An example would be when the offset changes from {@code +01:00} to {@code +02:00}.
196
* This might be described as 'the clocks will move forward one hour tonight at 1am'.
197
*
198
* @return true if this transition is a gap, false if it is an overlap
199
*/
200
public boolean isGap() {
201
return getOffsetAfter().getTotalSeconds() > getOffsetBefore().getTotalSeconds();
202
}
203
204
/**
205
* Does this transition represent a gap in the local time-line.
206
* <p>
207
* Overlaps occur where there are local date-times that exist twice.
208
* An example would be when the offset changes from {@code +02:00} to {@code +01:00}.
209
* This might be described as 'the clocks will move back one hour tonight at 2am'.
210
*
211
* @return true if this transition is an overlap, false if it is a gap
212
*/
213
public boolean isOverlap() {
214
return getOffsetAfter().getTotalSeconds() < getOffsetBefore().getTotalSeconds();
215
}
216
217
/**
218
* Checks if the specified offset is valid during this transition.
219
* <p>
220
* This checks to see if the given offset will be valid at some point in the transition.
221
* A gap will always return false.
222
* An overlap will return true if the offset is either the before or after offset.
223
*
224
* @param offset the offset to check, null returns false
225
* @return true if the offset is valid during the transition
226
*/
227
public boolean isValidOffset(ZoneOffset offset) {
228
return isGap() ? false : (getOffsetBefore().equals(offset) || getOffsetAfter().equals(offset));
229
}
230
231
/**
232
* Gets the valid offsets during this transition.
233
* <p>
234
* A gap will return an empty list, while an overlap will return both offsets.
235
*
236
* @return the list of valid offsets
237
*/
238
List<ZoneOffset> getValidOffsets() {
239
if (isGap()) {
240
return Collections.emptyList();
241
}
242
return Arrays.asList(getOffsetBefore(), getOffsetAfter());
243
}
244
245
/**
246
* Compares this transition to another based on the transition instant.
247
* <p>
248
* This compares the instants of each transition.
249
* The offsets are ignored, making this order inconsistent with equals.
250
*
251
* @param transition the transition to compare to, not null
252
* @return the comparator value, negative if less, positive if greater
253
*/
254
@Override
255
public int compareTo(ZoneOffsetTransition transition) {
256
return Long.compare(this.toEpochSecond(), transition.toEpochSecond());
257
}
258
259
/**
260
* Checks if this object equals another.
261
* <p>
262
* The entire state of the object is compared.
263
*
264
* @param other the other object to compare to, null returns false
265
* @return true if equal
266
*/
267
@Override
268
public boolean equals(Object other) {
269
if (other == this) {
270
return true;
271
}
272
if (other instanceof ZoneOffsetTransition) {
273
ZoneOffsetTransition d = (ZoneOffsetTransition) other;
274
return transition.equals(d.transition) &&
275
offsetBefore.equals(d.offsetBefore) && offsetAfter.equals(d.offsetAfter);
276
}
277
return false;
278
}
279
280
/**
281
* Returns a suitable hash code.
282
*
283
* @return the hash code
284
*/
285
@Override
286
public int hashCode() {
287
return transition.hashCode() ^ offsetBefore.hashCode() ^ Integer.rotateLeft(offsetAfter.hashCode(), 16);
288
}
289
290
}
291
292