1 /*
2  * Copyright (c) 2012, 2015, 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  * This file is available under and governed by the GNU General Public
26  * License version 2 only, as published by the Free Software Foundation.
27  * However, the following notice accompanied the original version of this
28  * file:
29  *
30  * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos
31  *
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions are met:
36  *
37  *  * Redistributions of source code must retain the above copyright notice,
38  *    this list of conditions and the following disclaimer.
39  *
40  *  * Redistributions in binary form must reproduce the above copyright notice,
41  *    this list of conditions and the following disclaimer in the documentation
42  *    and/or other materials provided with the distribution.
43  *
44  *  * Neither the name of JSR-310 nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  */
60 package tck.java.time.zone;
61 
62 import static org.testng.Assert.assertEquals;
63 
64 import java.time.DayOfWeek;
65 import java.time.LocalDateTime;
66 import java.time.LocalTime;
67 import java.time.Month;
68 import java.time.ZoneOffset;
69 import java.time.zone.ZoneOffsetTransition;
70 import java.time.zone.ZoneOffsetTransitionRule;
71 import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
72 
73 import org.testng.annotations.Test;
74 import tck.java.time.AbstractTCKTest;
75 
76 /**
77  * Test ZoneOffsetTransitionRule.
78  */
79 @Test
80 public class TCKZoneOffsetTransitionRule extends AbstractTCKTest {
81 
82     private static final LocalTime TIME_0100 = LocalTime.of(1, 0);
83     private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2);
84     private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3);
85 
86     //-----------------------------------------------------------------------
87     // factory
88     //-----------------------------------------------------------------------
89     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullMonth()90     public void test_factory_nullMonth() {
91         ZoneOffsetTransitionRule.of(
92                 null, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
93                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
94     }
95 
96     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullTime()97     public void test_factory_nullTime() {
98         ZoneOffsetTransitionRule.of(
99                 Month.MARCH, 20, DayOfWeek.SUNDAY, null, false, TimeDefinition.WALL,
100                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
101     }
102 
103     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullTimeDefinition()104     public void test_factory_nullTimeDefinition() {
105         ZoneOffsetTransitionRule.of(
106                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, null,
107                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
108     }
109 
110     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullStandardOffset()111     public void test_factory_nullStandardOffset() {
112         ZoneOffsetTransitionRule.of(
113                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
114                 null, OFFSET_0200, OFFSET_0300);
115     }
116 
117     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullOffsetBefore()118     public void test_factory_nullOffsetBefore() {
119         ZoneOffsetTransitionRule.of(
120                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
121                 OFFSET_0200, null, OFFSET_0300);
122     }
123 
124     @Test(expectedExceptions=NullPointerException.class)
test_factory_nullOffsetAfter()125     public void test_factory_nullOffsetAfter() {
126         ZoneOffsetTransitionRule.of(
127                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
128                 OFFSET_0200, OFFSET_0200, null);
129     }
130 
131     @Test(expectedExceptions=IllegalArgumentException.class)
test_factory_invalidDayOfMonthIndicator_tooSmall()132     public void test_factory_invalidDayOfMonthIndicator_tooSmall() {
133         ZoneOffsetTransitionRule.of(
134                 Month.MARCH, -29, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
135                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
136     }
137 
138     @Test(expectedExceptions=IllegalArgumentException.class)
test_factory_invalidDayOfMonthIndicator_zero()139     public void test_factory_invalidDayOfMonthIndicator_zero() {
140         ZoneOffsetTransitionRule.of(
141                 Month.MARCH, 0, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
142                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
143     }
144 
145     @Test(expectedExceptions=IllegalArgumentException.class)
test_factory_invalidDayOfMonthIndicator_tooLarge()146     public void test_factory_invalidDayOfMonthIndicator_tooLarge() {
147         ZoneOffsetTransitionRule.of(
148                 Month.MARCH, 32, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
149                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
150     }
151 
152     @Test(expectedExceptions=IllegalArgumentException.class)
test_factory_invalidMidnightFlag()153     public void test_factory_invalidMidnightFlag() {
154         ZoneOffsetTransitionRule.of(
155                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, true, TimeDefinition.WALL,
156                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
157     }
158 
159     @Test(expectedExceptions=IllegalArgumentException.class)
test_factory_nonZeroTimeNanos()160     public void test_factory_nonZeroTimeNanos() {
161         ZoneOffsetTransitionRule.of(
162             Month.MARCH, 20, DayOfWeek.SUNDAY, LocalTime.of(1, 2, 3, 400_000_000),
163             false, TimeDefinition.WALL, OFFSET_0200, OFFSET_0200, OFFSET_0300);
164     }
165 
166     //-----------------------------------------------------------------------
167     // getters
168     //-----------------------------------------------------------------------
169     @Test
test_getters_floatingWeek()170     public void test_getters_floatingWeek() throws Exception {
171         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
172                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
173                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
174         assertEquals(test.getMonth(), Month.MARCH);
175         assertEquals(test.getDayOfMonthIndicator(), 20);
176         assertEquals(test.getDayOfWeek(), DayOfWeek.SUNDAY);
177         assertEquals(test.getLocalTime(), TIME_0100);
178         assertEquals(test.isMidnightEndOfDay(), false);
179         assertEquals(test.getTimeDefinition(), TimeDefinition.WALL);
180         assertEquals(test.getStandardOffset(), OFFSET_0200);
181         assertEquals(test.getOffsetBefore(), OFFSET_0200);
182         assertEquals(test.getOffsetAfter(), OFFSET_0300);
183     }
184 
185     @Test
test_getters_floatingWeekBackwards()186     public void test_getters_floatingWeekBackwards() throws Exception {
187         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
188                 Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
189                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
190         assertEquals(test.getMonth(), Month.MARCH);
191         assertEquals(test.getDayOfMonthIndicator(), -1);
192         assertEquals(test.getDayOfWeek(), DayOfWeek.SUNDAY);
193         assertEquals(test.getLocalTime(), TIME_0100);
194         assertEquals(test.isMidnightEndOfDay(), false);
195         assertEquals(test.getTimeDefinition(), TimeDefinition.WALL);
196         assertEquals(test.getStandardOffset(), OFFSET_0200);
197         assertEquals(test.getOffsetBefore(), OFFSET_0200);
198         assertEquals(test.getOffsetAfter(), OFFSET_0300);
199     }
200 
201     @Test
test_getters_fixedDate()202     public void test_getters_fixedDate() throws Exception {
203         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
204                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.WALL,
205                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
206         assertEquals(test.getMonth(), Month.MARCH);
207         assertEquals(test.getDayOfMonthIndicator(), 20);
208         assertEquals(test.getDayOfWeek(), null);
209         assertEquals(test.getLocalTime(), TIME_0100);
210         assertEquals(test.isMidnightEndOfDay(), false);
211         assertEquals(test.getTimeDefinition(), TimeDefinition.WALL);
212         assertEquals(test.getStandardOffset(), OFFSET_0200);
213         assertEquals(test.getOffsetBefore(), OFFSET_0200);
214         assertEquals(test.getOffsetAfter(), OFFSET_0300);
215     }
216 
217 
218     //-----------------------------------------------------------------------
219     // createTransition()
220     //-----------------------------------------------------------------------
221     @Test
test_createTransition_floatingWeek_gap_notEndOfDay()222     public void test_createTransition_floatingWeek_gap_notEndOfDay() {
223         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
224                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
225                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
226         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
227                 LocalDateTime.of(2000, Month.MARCH, 26, 1, 0), OFFSET_0200, OFFSET_0300);
228         assertEquals(test.createTransition(2000), trans);
229     }
230 
231     @Test
test_createTransition_floatingWeek_overlap_endOfDay()232     public void test_createTransition_floatingWeek_overlap_endOfDay() {
233         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
234                 Month.MARCH, 20, DayOfWeek.SUNDAY, LocalTime.MIDNIGHT, true, TimeDefinition.WALL,
235                 OFFSET_0200, OFFSET_0300, OFFSET_0200);
236         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
237                 LocalDateTime.of(2000, Month.MARCH, 27, 0, 0), OFFSET_0300, OFFSET_0200);
238         assertEquals(test.createTransition(2000), trans);
239     }
240 
241     @Test
test_createTransition_floatingWeekBackwards_last()242     public void test_createTransition_floatingWeekBackwards_last() {
243         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
244                 Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
245                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
246         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
247                 LocalDateTime.of(2000, Month.MARCH, 26, 1, 0), OFFSET_0200, OFFSET_0300);
248         assertEquals(test.createTransition(2000), trans);
249     }
250 
251     @Test
test_createTransition_floatingWeekBackwards_seventhLast()252     public void test_createTransition_floatingWeekBackwards_seventhLast() {
253         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
254                 Month.MARCH, -7, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
255                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
256         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
257                 LocalDateTime.of(2000, Month.MARCH, 19, 1, 0), OFFSET_0200, OFFSET_0300);
258         assertEquals(test.createTransition(2000), trans);
259     }
260 
261     @Test
test_createTransition_floatingWeekBackwards_secondLast()262     public void test_createTransition_floatingWeekBackwards_secondLast() {
263         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
264                 Month.MARCH, -2, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
265                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
266         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
267                 LocalDateTime.of(2000, Month.MARCH, 26, 1, 0), OFFSET_0200, OFFSET_0300);
268         assertEquals(test.createTransition(2000), trans);
269     }
270 
271     @Test
test_createTransition_fixedDate()272     public void test_createTransition_fixedDate() {
273         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
274                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
275                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
276         ZoneOffsetTransition trans = ZoneOffsetTransition.of(
277                 LocalDateTime.of(2000, Month.MARCH, 20, 1, 0), OFFSET_0200, OFFSET_0300);
278         assertEquals(test.createTransition(2000), trans);
279     }
280 
281     //-----------------------------------------------------------------------
282     // equals()
283     //-----------------------------------------------------------------------
284     @Test
test_equals_monthDifferent()285     public void test_equals_monthDifferent() {
286         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
287                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
288                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
289         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
290                 Month.APRIL, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
291                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
292         assertEquals(a.equals(a), true);
293         assertEquals(a.equals(b), false);
294         assertEquals(b.equals(a), false);
295         assertEquals(b.equals(b), true);
296     }
297 
298     @Test
test_equals_dayOfMonthDifferent()299     public void test_equals_dayOfMonthDifferent() {
300         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
301                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
302                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
303         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
304                 Month.MARCH, 21, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
305                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
306         assertEquals(a.equals(a), true);
307         assertEquals(a.equals(b), false);
308         assertEquals(b.equals(a), false);
309         assertEquals(b.equals(b), true);
310     }
311 
312     @Test
test_equals_dayOfWeekDifferent()313     public void test_equals_dayOfWeekDifferent() {
314         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
315                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
316                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
317         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
318                 Month.MARCH, 20, DayOfWeek.SATURDAY, TIME_0100, false, TimeDefinition.WALL,
319                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
320         assertEquals(a.equals(a), true);
321         assertEquals(a.equals(b), false);
322         assertEquals(b.equals(a), false);
323         assertEquals(b.equals(b), true);
324     }
325 
326     @Test
test_equals_dayOfWeekDifferentNull()327     public void test_equals_dayOfWeekDifferentNull() {
328         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
329                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
330                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
331         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
332                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.WALL,
333                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
334         assertEquals(a.equals(a), true);
335         assertEquals(a.equals(b), false);
336         assertEquals(b.equals(a), false);
337         assertEquals(b.equals(b), true);
338     }
339 
340     @Test
test_equals_localTimeDifferent()341     public void test_equals_localTimeDifferent() {
342         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
343                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
344                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
345         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
346                 Month.MARCH, 20, DayOfWeek.SUNDAY, LocalTime.MIDNIGHT, false, TimeDefinition.WALL,
347                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
348         assertEquals(a.equals(a), true);
349         assertEquals(a.equals(b), false);
350         assertEquals(b.equals(a), false);
351         assertEquals(b.equals(b), true);
352     }
353 
354     @Test
test_equals_endOfDayDifferent()355     public void test_equals_endOfDayDifferent() {
356         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
357                 Month.MARCH, 20, DayOfWeek.SUNDAY, LocalTime.MIDNIGHT, false, TimeDefinition.WALL,
358                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
359         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
360                 Month.MARCH, 20, DayOfWeek.SUNDAY, LocalTime.MIDNIGHT, true, TimeDefinition.WALL,
361                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
362         assertEquals(a.equals(a), true);
363         assertEquals(a.equals(b), false);
364         assertEquals(b.equals(a), false);
365         assertEquals(b.equals(b), true);
366     }
367 
368     @Test
test_equals_timeDefinitionDifferent()369     public void test_equals_timeDefinitionDifferent() {
370         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
371                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
372                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
373         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
374                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.STANDARD,
375                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
376         assertEquals(a.equals(a), true);
377         assertEquals(a.equals(b), false);
378         assertEquals(b.equals(a), false);
379         assertEquals(b.equals(b), true);
380     }
381 
382     @Test
test_equals_standardOffsetDifferent()383     public void test_equals_standardOffsetDifferent() {
384         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
385                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
386                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
387         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
388                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
389                 OFFSET_0300, OFFSET_0200, OFFSET_0300);
390         assertEquals(a.equals(a), true);
391         assertEquals(a.equals(b), false);
392         assertEquals(b.equals(a), false);
393         assertEquals(b.equals(b), true);
394     }
395 
396     @Test
test_equals_offsetBeforeDifferent()397     public void test_equals_offsetBeforeDifferent() {
398         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
399                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
400                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
401         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
402                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
403                 OFFSET_0200, OFFSET_0300, OFFSET_0300);
404         assertEquals(a.equals(a), true);
405         assertEquals(a.equals(b), false);
406         assertEquals(b.equals(a), false);
407         assertEquals(b.equals(b), true);
408     }
409 
410     @Test
test_equals_offsetAfterDifferent()411     public void test_equals_offsetAfterDifferent() {
412         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
413                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
414                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
415         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
416                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
417                 OFFSET_0200, OFFSET_0200, OFFSET_0200);
418         assertEquals(a.equals(a), true);
419         assertEquals(a.equals(b), false);
420         assertEquals(b.equals(a), false);
421         assertEquals(b.equals(b), true);
422     }
423 
424     @Test
test_equals_string_false()425     public void test_equals_string_false() {
426         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
427                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
428                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
429         assertEquals(a.equals("TZDB"), false);
430     }
431 
432     @Test
test_equals_null_false()433     public void test_equals_null_false() {
434         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
435                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
436                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
437         assertEquals(a.equals(null), false);
438     }
439 
440     //-----------------------------------------------------------------------
441     // hashCode()
442     //-----------------------------------------------------------------------
443     @Test
test_hashCode_floatingWeek_gap_notEndOfDay()444     public void test_hashCode_floatingWeek_gap_notEndOfDay() {
445         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
446                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
447                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
448         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
449                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
450                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
451         assertEquals(a.hashCode(), b.hashCode());
452     }
453 
454     @Test
test_hashCode_floatingWeek_overlap_endOfDay_nullDayOfWeek()455     public void test_hashCode_floatingWeek_overlap_endOfDay_nullDayOfWeek() {
456         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
457                 Month.OCTOBER, 20, null, LocalTime.MIDNIGHT, true, TimeDefinition.WALL,
458                 OFFSET_0200, OFFSET_0300, OFFSET_0200);
459         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
460                 Month.OCTOBER, 20, null, LocalTime.MIDNIGHT, true, TimeDefinition.WALL,
461                 OFFSET_0200, OFFSET_0300, OFFSET_0200);
462         assertEquals(a.hashCode(), b.hashCode());
463     }
464 
465     @Test
test_hashCode_floatingWeekBackwards()466     public void test_hashCode_floatingWeekBackwards() {
467         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
468                 Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
469                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
470         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
471                 Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
472                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
473         assertEquals(a.hashCode(), b.hashCode());
474     }
475 
476     @Test
test_hashCode_fixedDate()477     public void test_hashCode_fixedDate() {
478         ZoneOffsetTransitionRule a = ZoneOffsetTransitionRule.of(
479                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
480                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
481         ZoneOffsetTransitionRule b = ZoneOffsetTransitionRule.of(
482                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
483                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
484         assertEquals(a.hashCode(), b.hashCode());
485     }
486 
487     //-----------------------------------------------------------------------
488     // toString()
489     //-----------------------------------------------------------------------
490     @Test
test_toString_floatingWeek_gap_notEndOfDay()491     public void test_toString_floatingWeek_gap_notEndOfDay() {
492         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
493                 Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
494                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
495         assertEquals(test.toString(), "TransitionRule[Gap +02:00 to +03:00, SUNDAY on or after MARCH 20 at 01:00 WALL, standard offset +02:00]");
496     }
497 
498     @Test
test_toString_floatingWeek_overlap_endOfDay()499     public void test_toString_floatingWeek_overlap_endOfDay() {
500         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
501                 Month.OCTOBER, 20, DayOfWeek.SUNDAY, LocalTime.MIDNIGHT, true, TimeDefinition.WALL,
502                 OFFSET_0200, OFFSET_0300, OFFSET_0200);
503         assertEquals(test.toString(), "TransitionRule[Overlap +03:00 to +02:00, SUNDAY on or after OCTOBER 20 at 24:00 WALL, standard offset +02:00]");
504     }
505 
506     @Test
test_toString_floatingWeekBackwards_last()507     public void test_toString_floatingWeekBackwards_last() {
508         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
509                 Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
510                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
511         assertEquals(test.toString(), "TransitionRule[Gap +02:00 to +03:00, SUNDAY on or before last day of MARCH at 01:00 WALL, standard offset +02:00]");
512     }
513 
514     @Test
test_toString_floatingWeekBackwards_secondLast()515     public void test_toString_floatingWeekBackwards_secondLast() {
516         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
517                 Month.MARCH, -2, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
518                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
519         assertEquals(test.toString(), "TransitionRule[Gap +02:00 to +03:00, SUNDAY on or before last day minus 1 of MARCH at 01:00 WALL, standard offset +02:00]");
520     }
521 
522     @Test
test_toString_fixedDate()523     public void test_toString_fixedDate() {
524         ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
525                 Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
526                 OFFSET_0200, OFFSET_0200, OFFSET_0300);
527         assertEquals(test.toString(), "TransitionRule[Gap +02:00 to +03:00, MARCH 20 at 01:00 STANDARD, standard offset +02:00]");
528     }
529 
530 }
531