Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/TimeZone/TimeZoneBoundaryTest.java
38821 views
1
/*
2
* Copyright (c) 1997, 2016, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @library /java/text/testlib
27
* @summary test Time Zone Boundary
28
*/
29
30
import java.text.*;
31
import java.util.*;
32
33
/**
34
* A test which discovers the boundaries of DST programmatically and verifies
35
* that they are correct.
36
*/
37
public class TimeZoneBoundaryTest extends IntlTest
38
{
39
static final int ONE_SECOND = 1000;
40
static final int ONE_MINUTE = 60*ONE_SECOND;
41
static final int ONE_HOUR = 60*ONE_MINUTE;
42
static final long ONE_DAY = 24*ONE_HOUR;
43
static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
44
static final long SIX_MONTHS = ONE_YEAR / 2;
45
46
static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};
47
48
// These values are empirically determined to be correct
49
static final long PST_1997_BEG = 860320800000L;
50
static final long PST_1997_END = 877856400000L;
51
52
// Minimum interval for binary searches in ms; should be no larger
53
// than 1000.
54
static final long INTERVAL = 10; // Milliseconds
55
56
static final String AUSTRALIA = "Australia/Adelaide";
57
static final long AUSTRALIA_1997_BEG = 877797000000L;
58
static final long AUSTRALIA_1997_END = 859653000000L;
59
60
public static void main(String[] args) throws Exception {
61
new TimeZoneBoundaryTest().run(args);
62
}
63
64
/**
65
* Date.toString().substring() Boundary Test
66
* Look for a DST changeover to occur within 6 months of the given Date.
67
* The initial Date.toString() should yield a string containing the
68
* startMode as a SUBSTRING. The boundary will be tested to be
69
* at the expectedBoundary value.
70
*/
71
void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
72
{
73
// Given a date with a year start, find the Daylight onset
74
// and end. The given date should be 1/1/xx in some year.
75
76
if (d.toString().indexOf(startMode) == -1)
77
{
78
logln("Error: " + startMode + " not present in " + d);
79
}
80
81
// Use a binary search, assuming that we have a Standard
82
// time at the midpoint.
83
long min = d.getTime();
84
long max = min + SIX_MONTHS;
85
86
while ((max - min) > INTERVAL)
87
{
88
long mid = (min + max) >> 1;
89
String s = new Date(mid).toString();
90
// logln(s);
91
if (s.indexOf(startMode) != -1)
92
{
93
min = mid;
94
}
95
else
96
{
97
max = mid;
98
}
99
}
100
101
logln("Date Before: " + showDate(min));
102
logln("Date After: " + showDate(max));
103
long mindelta = expectedBoundary - min;
104
long maxdelta = max - expectedBoundary;
105
if (mindelta >= 0 && mindelta <= INTERVAL &&
106
mindelta >= 0 && mindelta <= INTERVAL)
107
logln("PASS: Expected boundary at " + expectedBoundary);
108
else
109
errln("FAIL: Expected boundary at " + expectedBoundary);
110
}
111
112
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
113
{
114
findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
115
TimeZone.getDefault());
116
}
117
118
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
119
long expectedBoundary, TimeZone tz)
120
{
121
// Given a date with a year start, find the Daylight onset
122
// and end. The given date should be 1/1/xx in some year.
123
124
// Use a binary search, assuming that we have a Standard
125
// time at the midpoint.
126
long min = d.getTime();
127
long max = min + SIX_MONTHS;
128
129
if (tz.inDaylightTime(d) != startsInDST)
130
{
131
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
132
d + ") != " + startsInDST);
133
startsInDST = !startsInDST; // Flip over; find the apparent value
134
}
135
136
if (tz.inDaylightTime(new Date(max)) == startsInDST)
137
{
138
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
139
(new Date(max)) + ") != " + (!startsInDST));
140
return;
141
}
142
143
while ((max - min) > INTERVAL)
144
{
145
long mid = (min + max) >> 1;
146
boolean isIn = tz.inDaylightTime(new Date(mid));
147
if (isIn == startsInDST)
148
{
149
min = mid;
150
}
151
else
152
{
153
max = mid;
154
}
155
}
156
157
logln(tz.getID() + " Before: " + showDate(min, tz));
158
logln(tz.getID() + " After: " + showDate(max, tz));
159
160
long mindelta = expectedBoundary - min;
161
long maxdelta = max - expectedBoundary;
162
if (mindelta >= 0 && mindelta <= INTERVAL &&
163
mindelta >= 0 && mindelta <= INTERVAL)
164
logln("PASS: Expected boundary at " + expectedBoundary);
165
else
166
errln("FAIL: Expected boundary at " + expectedBoundary);
167
}
168
169
private static String showDate(long l)
170
{
171
return showDate(new Date(l));
172
}
173
174
@SuppressWarnings("deprecation")
175
private static String showDate(Date d)
176
{
177
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
178
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
179
" \"" + d + "\" = " +
180
d.getTime();
181
}
182
183
private static String showDate(long l, TimeZone z)
184
{
185
return showDate(new Date(l), z);
186
}
187
188
@SuppressWarnings("deprecation")
189
private static String showDate(Date d, TimeZone zone)
190
{
191
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
192
fmt.setTimeZone(zone);
193
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
194
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
195
" \"" + d + "\" = " +
196
fmt.format(d);
197
}
198
199
private static String showNN(int n)
200
{
201
return ((n < 10) ? "0" : "") + n;
202
}
203
204
/**
205
* Given a date, a TimeZone, and expected values for inDaylightTime,
206
* useDaylightTime, zone and DST offset, verify that this is the case.
207
*/
208
void verifyDST(Date d, TimeZone time_zone,
209
boolean expUseDaylightTime, boolean expInDaylightTime,
210
int expZoneOffset, int expDSTOffset)
211
{
212
logln("-- Verifying time " + d +
213
" in zone " + time_zone.getID());
214
215
if (time_zone.inDaylightTime(d) == expInDaylightTime)
216
logln("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
217
else
218
errln("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));
219
220
if (time_zone.useDaylightTime() == expUseDaylightTime)
221
logln("PASS: useDaylightTime = " + time_zone.useDaylightTime());
222
else
223
errln("FAIL: useDaylightTime = " + time_zone.useDaylightTime());
224
225
if (time_zone.getRawOffset() == expZoneOffset)
226
logln("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
227
else
228
errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
229
"; expected " + expZoneOffset/(double)ONE_HOUR);
230
231
GregorianCalendar gc = new GregorianCalendar(time_zone);
232
gc.setTime(d);
233
int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
234
gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
235
((gc.get(gc.HOUR_OF_DAY) * 60 +
236
gc.get(gc.MINUTE)) * 60 +
237
gc.get(gc.SECOND)) * 1000 +
238
gc.get(gc.MILLISECOND));
239
if (offset == expDSTOffset)
240
logln("PASS: getOffset() = " + offset/(double)ONE_HOUR);
241
else
242
errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
243
"; expected " + expDSTOffset/(double)ONE_HOUR);
244
}
245
246
@SuppressWarnings("deprecation")
247
public void TestBoundaries()
248
{
249
TimeZone pst = TimeZone.getTimeZone("PST");
250
TimeZone save = TimeZone.getDefault();
251
try {
252
TimeZone.setDefault(pst);
253
254
// DST changeover for PST is 4/6/1997 at 2 hours past midnight
255
Date d = new Date(97,Calendar.APRIL,6);
256
257
// i is minutes past midnight standard time
258
for (int i=60; i<=180; i+=15)
259
{
260
boolean inDST = (i >= 120);
261
Date e = new Date(d.getTime() + i*60*1000);
262
verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
263
inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
264
}
265
266
logln("========================================");
267
findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
268
logln("========================================");
269
findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);
270
271
// Southern hemisphere test
272
logln("========================================");
273
TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
274
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);
275
276
logln("========================================");
277
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
278
logln("========================================");
279
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
280
} finally {
281
TimeZone.setDefault(save);
282
}
283
}
284
285
void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
286
{
287
// Given a date with a year start, find the Daylight onset
288
// and end. The given date should be 1/1/xx in some year.
289
290
// Use a binary search, assuming that we have a Standard
291
// time at the midpoint.
292
long min = d.getTime();
293
long max = min + (long)(365.25 / 2 * ONE_DAY);
294
295
// First check the boundaries
296
boolean startsInDST = tz.inDaylightTime(d);
297
298
if (tz.inDaylightTime(new Date(max)) == startsInDST)
299
{
300
logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
301
}
302
303
while ((max - min) > INTERVAL)
304
{
305
long mid = (min + max) >> 1;
306
if (tz.inDaylightTime(new Date(mid)) == startsInDST)
307
{
308
min = mid;
309
}
310
else
311
{
312
max = mid;
313
}
314
}
315
316
logln("Binary Search Before: " + showDate(min));
317
logln("Binary Search After: " + showDate(max));
318
319
long mindelta = expectedBoundary - min;
320
long maxdelta = max - expectedBoundary;
321
if (mindelta >= 0 && mindelta <= INTERVAL &&
322
mindelta >= 0 && mindelta <= INTERVAL)
323
logln("PASS: Expected boundary at " + expectedBoundary);
324
else
325
errln("FAIL: Expected boundary at " + expectedBoundary);
326
}
327
328
/*
329
static void testUsingMillis(Date d, boolean startsInDST)
330
{
331
long millis = d.getTime();
332
long max = millis + (long)(370 * ONE_DAY); // A year plus extra
333
334
boolean lastDST = startsInDST;
335
while (millis < max)
336
{
337
cal.setTime(new Date(millis));
338
boolean inDaylight = cal.inDaylightTime();
339
340
if (inDaylight != lastDST)
341
{
342
logln("Switch " + (inDaylight ? "into" : "out of")
343
+ " DST at " + (new Date(millis)));
344
lastDST = inDaylight;
345
}
346
347
millis += 15*ONE_MINUTE;
348
}
349
}
350
*/
351
352
/**
353
* Test new rule formats.
354
*/
355
@SuppressWarnings("deprecation")
356
public void TestNewRules()
357
{
358
//logln(Locale.getDefault().getDisplayName());
359
//logln(TimeZone.getDefault().getID());
360
//logln(new Date(0));
361
362
if (true)
363
{
364
// Doesn't matter what the default TimeZone is here, since we
365
// are creating our own TimeZone objects.
366
367
SimpleTimeZone tz;
368
369
logln("-----------------------------------------------------------------");
370
logln("Aug 2ndTues .. Mar 15");
371
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
372
Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
373
Calendar.MARCH, 15, 0, 2*ONE_HOUR);
374
//logln(tz.toString());
375
logln("========================================");
376
testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
377
logln("========================================");
378
testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);
379
380
logln("-----------------------------------------------------------------");
381
logln("Apr Wed>=14 .. Sep Sun<=20");
382
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
383
Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
384
Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
385
//logln(tz.toString());
386
logln("========================================");
387
testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
388
logln("========================================");
389
testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
390
}
391
392
/*
393
if (true)
394
{
395
logln("========================================");
396
logln("Stepping using millis");
397
testUsingMillis(new Date(97,0,1), false);
398
}
399
400
if (true)
401
{
402
logln("========================================");
403
logln("Stepping using fields");
404
testUsingFields(1997, false);
405
}
406
407
if (false)
408
{
409
cal.clear();
410
cal.set(1997, 3, 5, 10, 0);
411
// cal.inDaylightTime();
412
logln("Date = " + cal.getTime());
413
logln("Millis = " + cal.getTime().getTime()/3600000);
414
}
415
*/
416
}
417
418
//----------------------------------------------------------------------
419
//----------------------------------------------------------------------
420
//----------------------------------------------------------------------
421
// Long Bug
422
//----------------------------------------------------------------------
423
//----------------------------------------------------------------------
424
//----------------------------------------------------------------------
425
426
//public void Test3()
427
//{
428
// findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true);
429
//}
430
431
/**
432
* Find boundaries by stepping.
433
*/
434
@SuppressWarnings("deprecation")
435
void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
436
{
437
Date d = new Date(year - 1900, Calendar.JANUARY, 1);
438
long time = d.getTime(); // ms
439
long limit = time + ONE_YEAR + ONE_DAY;
440
boolean lastState = z.inDaylightTime(d);
441
int changes = 0;
442
logln("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
443
logln("useDaylightTime = " + z.useDaylightTime());
444
while (time < limit)
445
{
446
d.setTime(time);
447
boolean state = z.inDaylightTime(d);
448
if (state != lastState)
449
{
450
logln((state ? "Entry " : "Exit ") +
451
"at " + d);
452
lastState = state;
453
++changes;
454
}
455
time += interval;
456
}
457
if (changes == 0)
458
{
459
if (!lastState && !z.useDaylightTime()) logln("No DST");
460
else errln("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime");
461
}
462
else if (changes != 2)
463
{
464
errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2");
465
}
466
else if (!z.useDaylightTime())
467
{
468
errln("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen");
469
}
470
if (changes != expectedChanges)
471
{
472
errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges);
473
}
474
}
475
476
public void TestStepwise()
477
{
478
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0);
479
// "EST" is disabled because its behavior depends on the mapping property. (6466476).
480
//findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("EST"), 2);
481
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("HST"), 0);
482
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST"), 2);
483
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST8PDT"), 2);
484
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST"), 0);
485
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST8PDT"), 2);
486
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Japan"), 0);
487
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Europe/Paris"), 2);
488
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("America/Los_Angeles"), 2);
489
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
490
}
491
}
492
493