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.
   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) 2008-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 import static org.testng.Assert.assertFalse;
  64 import static org.testng.Assert.assertNotNull;
  65 import static org.testng.Assert.assertTrue;
  66 
  67 import java.io.ByteArrayInputStream;
  68 import java.io.ByteArrayOutputStream;
  69 import java.io.ObjectInputStream;
  70 import java.io.ObjectOutputStream;
  71 import java.time.DayOfWeek;
  72 import java.time.Duration;
  73 import java.time.Instant;
  74 import java.time.LocalDate;
  75 import java.time.LocalDateTime;
  76 import java.time.LocalTime;
  77 import java.time.Month;
  78 import java.time.OffsetDateTime;
  79 import java.time.Year;
  80 import java.time.ZoneId;
  81 import java.time.ZoneOffset;
  82 import java.time.ZonedDateTime;
  83 import java.time.zone.ZoneOffsetTransition;
  84 import java.time.zone.ZoneOffsetTransitionRule;
  85 import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
  86 import java.time.zone.ZoneRules;
  87 import java.util.ArrayList;
  88 import java.util.Iterator;
  89 import java.util.List;
  90 
  91 import org.testng.annotations.Test;
  92 
  93 /**
  94  * Test ZoneRules.
  95  */
  96 @Test
  97 public class TCKZoneRules {
  98 
  99     private static final ZoneOffset OFFSET_ZERO = ZoneOffset.ofHours(0);
 100     private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
 101     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
 102     public static final String LATEST_TZDB = "2009b";
 103     private static final int OVERLAP = 2;
 104     private static final int GAP = 0;
 105 
 106 
 107 
 108     //-----------------------------------------------------------------------
 109     // Europe/London
 110     //-----------------------------------------------------------------------
 111     private ZoneRules europeLondon() {
 112         return ZoneId.of("Europe/London").getRules();
 113     }
 114 
 115     public void test_London() {
 116         ZoneRules test = europeLondon();
 117         assertEquals(test.isFixedOffset(), false);
 118     }
 119 
 120     public void test_London_preTimeZones() {
 121         ZoneRules test = europeLondon();
 122         ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
 123         Instant instant = old.toInstant();
 124         ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, -1, -15);
 125         assertEquals(test.getOffset(instant), offset);
 126         checkOffset(test, old.toLocalDateTime(), offset, 1);
 127         assertEquals(test.getStandardOffset(instant), offset);
 128         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
 129         assertEquals(test.isDaylightSavings(instant), false);
 130     }
 131 
 132     public void test_London_getOffset() {
 133         ZoneRules test = europeLondon();
 134         assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_ZERO);
 135         assertEquals(test.getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), OFFSET_ZERO);
 136         assertEquals(test.getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), OFFSET_ZERO);
 137         assertEquals(test.getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), OFFSET_PONE);
 138         assertEquals(test.getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), OFFSET_PONE);
 139         assertEquals(test.getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), OFFSET_PONE);
 140         assertEquals(test.getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), OFFSET_PONE);
 141         assertEquals(test.getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), OFFSET_PONE);
 142         assertEquals(test.getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), OFFSET_PONE);
 143         assertEquals(test.getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), OFFSET_PONE);
 144         assertEquals(test.getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), OFFSET_ZERO);
 145         assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_ZERO);
 146     }
 147 
 148     public void test_London_getOffset_toDST() {
 149         ZoneRules test = europeLondon();
 150         assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_ZERO);
 151         assertEquals(test.getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), OFFSET_ZERO);
 152         assertEquals(test.getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), OFFSET_ZERO);
 153         assertEquals(test.getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), OFFSET_ZERO);
 154         assertEquals(test.getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), OFFSET_ZERO);
 155         assertEquals(test.getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), OFFSET_ZERO);
 156         assertEquals(test.getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), OFFSET_ZERO);
 157         assertEquals(test.getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), OFFSET_PONE);
 158         // cutover at 01:00Z
 159         assertEquals(test.getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_ZERO);
 160         assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE);
 161     }
 162 
 163     public void test_London_getOffset_fromDST() {
 164         ZoneRules test = europeLondon();
 165         assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PONE);
 166         assertEquals(test.getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), OFFSET_PONE);
 167         assertEquals(test.getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), OFFSET_PONE);
 168         assertEquals(test.getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), OFFSET_ZERO);
 169         assertEquals(test.getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), OFFSET_ZERO);
 170         assertEquals(test.getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), OFFSET_ZERO);
 171         assertEquals(test.getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), OFFSET_ZERO);
 172         assertEquals(test.getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), OFFSET_ZERO);
 173         // cutover at 01:00Z
 174         assertEquals(test.getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PONE);
 175         assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_ZERO);
 176     }
 177 
 178     public void test_London_getOffsetInfo() {
 179         ZoneRules test = europeLondon();
 180         checkOffset(test, createLDT(2008, 1, 1), OFFSET_ZERO, 1);
 181         checkOffset(test, createLDT(2008, 2, 1), OFFSET_ZERO, 1);
 182         checkOffset(test, createLDT(2008, 3, 1), OFFSET_ZERO, 1);
 183         checkOffset(test, createLDT(2008, 4, 1), OFFSET_PONE, 1);
 184         checkOffset(test, createLDT(2008, 5, 1), OFFSET_PONE, 1);
 185         checkOffset(test, createLDT(2008, 6, 1), OFFSET_PONE, 1);
 186         checkOffset(test, createLDT(2008, 7, 1), OFFSET_PONE, 1);
 187         checkOffset(test, createLDT(2008, 8, 1), OFFSET_PONE, 1);
 188         checkOffset(test, createLDT(2008, 9, 1), OFFSET_PONE, 1);
 189         checkOffset(test, createLDT(2008, 10, 1), OFFSET_PONE, 1);
 190         checkOffset(test, createLDT(2008, 11, 1), OFFSET_ZERO, 1);
 191         checkOffset(test, createLDT(2008, 12, 1), OFFSET_ZERO, 1);
 192     }
 193 
 194     public void test_London_getOffsetInfo_toDST() {
 195         ZoneRules test = europeLondon();
 196         checkOffset(test, createLDT(2008, 3, 24), OFFSET_ZERO, 1);
 197         checkOffset(test, createLDT(2008, 3, 25), OFFSET_ZERO, 1);
 198         checkOffset(test, createLDT(2008, 3, 26), OFFSET_ZERO, 1);
 199         checkOffset(test, createLDT(2008, 3, 27), OFFSET_ZERO, 1);
 200         checkOffset(test, createLDT(2008, 3, 28), OFFSET_ZERO, 1);
 201         checkOffset(test, createLDT(2008, 3, 29), OFFSET_ZERO, 1);
 202         checkOffset(test, createLDT(2008, 3, 30), OFFSET_ZERO, 1);
 203         checkOffset(test, createLDT(2008, 3, 31), OFFSET_PONE, 1);
 204         // cutover at 01:00Z
 205         checkOffset(test, LocalDateTime.of(2008, 3, 30, 0, 59, 59, 999999999), OFFSET_ZERO, 1);
 206         checkOffset(test, LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0), OFFSET_PONE, 1);
 207     }
 208 
 209     public void test_London_getOffsetInfo_fromDST() {
 210         ZoneRules test = europeLondon();
 211         checkOffset(test, createLDT(2008, 10, 24), OFFSET_PONE, 1);
 212         checkOffset(test, createLDT(2008, 10, 25), OFFSET_PONE, 1);
 213         checkOffset(test, createLDT(2008, 10, 26), OFFSET_PONE, 1);
 214         checkOffset(test, createLDT(2008, 10, 27), OFFSET_ZERO, 1);
 215         checkOffset(test, createLDT(2008, 10, 28), OFFSET_ZERO, 1);
 216         checkOffset(test, createLDT(2008, 10, 29), OFFSET_ZERO, 1);
 217         checkOffset(test, createLDT(2008, 10, 30), OFFSET_ZERO, 1);
 218         checkOffset(test, createLDT(2008, 10, 31), OFFSET_ZERO, 1);
 219         // cutover at 01:00Z
 220         checkOffset(test, LocalDateTime.of(2008, 10, 26, 0, 59, 59, 999999999), OFFSET_PONE, 1);
 221         checkOffset(test, LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0), OFFSET_ZERO, 1);
 222     }
 223 
 224     public void test_London_getOffsetInfo_gap() {
 225         ZoneRules test = europeLondon();
 226         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0);
 227         ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_ZERO, GAP);
 228         assertEquals(trans.isGap(), true);
 229         assertEquals(trans.isOverlap(), false);
 230         assertEquals(trans.getOffsetBefore(), OFFSET_ZERO);
 231         assertEquals(trans.getOffsetAfter(), OFFSET_PONE);
 232         assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC));
 233         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0));
 234         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0));
 235         assertEquals(trans.isValidOffset(OFFSET_ZERO), false);
 236         assertEquals(trans.isValidOffset(OFFSET_PONE), false);
 237         assertEquals(trans.isValidOffset(OFFSET_PTWO), false);
 238         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]");
 239 
 240         assertFalse(trans.equals(null));
 241         assertFalse(trans.equals(OFFSET_ZERO));
 242         assertTrue(trans.equals(trans));
 243 
 244         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 245         assertTrue(trans.equals(otherTrans));
 246         assertEquals(trans.hashCode(), otherTrans.hashCode());
 247     }
 248 
 249     public void test_London_getOffsetInfo_overlap() {
 250         ZoneRules test = europeLondon();
 251         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0);
 252         ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, OVERLAP);
 253         assertEquals(trans.isGap(), false);
 254         assertEquals(trans.isOverlap(), true);
 255         assertEquals(trans.getOffsetBefore(), OFFSET_PONE);
 256         assertEquals(trans.getOffsetAfter(), OFFSET_ZERO);
 257         assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC));
 258         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0));
 259         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0));
 260         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 261         assertEquals(trans.isValidOffset(OFFSET_ZERO), true);
 262         assertEquals(trans.isValidOffset(OFFSET_PONE), true);
 263         assertEquals(trans.isValidOffset(OFFSET_PTWO), false);
 264         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]");
 265 
 266         assertFalse(trans.equals(null));
 267         assertFalse(trans.equals(OFFSET_PONE));
 268         assertTrue(trans.equals(trans));
 269 
 270         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 271         assertTrue(trans.equals(otherTrans));
 272         assertEquals(trans.hashCode(), otherTrans.hashCode());
 273     }
 274 
 275     public void test_London_getStandardOffset() {
 276         ZoneRules test = europeLondon();
 277         ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC);
 278         while (zdt.getYear() < 2010) {
 279             Instant instant = zdt.toInstant();
 280             if (zdt.getYear() < 1848) {
 281                 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, -1, -15));
 282             } else if (zdt.getYear() >= 1969 && zdt.getYear() < 1972) {
 283                 assertEquals(test.getStandardOffset(instant), OFFSET_PONE);
 284             } else {
 285                 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO);
 286             }
 287             zdt = zdt.plusMonths(6);
 288         }
 289     }
 290 
 291     public void test_London_getTransitions() {
 292         ZoneRules test = europeLondon();
 293         List<ZoneOffsetTransition> trans = test.getTransitions();
 294 
 295         ZoneOffsetTransition first = trans.get(0);
 296         assertEquals(first.getDateTimeBefore(), LocalDateTime.of(1847, 12, 1, 0, 0));
 297         assertEquals(first.getOffsetBefore(), ZoneOffset.ofHoursMinutesSeconds(0, -1, -15));
 298         assertEquals(first.getOffsetAfter(), OFFSET_ZERO);
 299 
 300         ZoneOffsetTransition spring1916 = trans.get(1);
 301         assertEquals(spring1916.getDateTimeBefore(), LocalDateTime.of(1916, 5, 21, 2, 0));
 302         assertEquals(spring1916.getOffsetBefore(), OFFSET_ZERO);
 303         assertEquals(spring1916.getOffsetAfter(), OFFSET_PONE);
 304 
 305         ZoneOffsetTransition autumn1916 = trans.get(2);
 306         assertEquals(autumn1916.getDateTimeBefore(), LocalDateTime.of(1916, 10, 1, 3, 0));
 307         assertEquals(autumn1916.getOffsetBefore(), OFFSET_PONE);
 308         assertEquals(autumn1916.getOffsetAfter(), OFFSET_ZERO);
 309 
 310         ZoneOffsetTransition zot = null;
 311         Iterator<ZoneOffsetTransition> it = trans.iterator();
 312         while (it.hasNext()) {
 313             zot = it.next();
 314             if (zot.getDateTimeBefore().getYear() == 1990) {
 315                 break;
 316             }
 317         }
 318         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1990, 3, 25, 1, 0));
 319         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 320         zot = it.next();
 321         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1990, 10, 28, 2, 0));
 322         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 323         zot = it.next();
 324         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1991, 3, 31, 1, 0));
 325         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 326         zot = it.next();
 327         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1991, 10, 27, 2, 0));
 328         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 329         zot = it.next();
 330         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1992, 3, 29, 1, 0));
 331         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 332         zot = it.next();
 333         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1992, 10, 25, 2, 0));
 334         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 335         zot = it.next();
 336         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1993, 3, 28, 1, 0));
 337         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 338         zot = it.next();
 339         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1993, 10, 24, 2, 0));
 340         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 341         zot = it.next();
 342         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1994, 3, 27, 1, 0));
 343         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 344         zot = it.next();
 345         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1994, 10, 23, 2, 0));
 346         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 347         zot = it.next();
 348         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1995, 3, 26, 1, 0));
 349         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 350         zot = it.next();
 351         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1995, 10, 22, 2, 0));
 352         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 353         zot = it.next();
 354         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1996, 3, 31, 1, 0));
 355         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 356         zot = it.next();
 357         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1996, 10, 27, 2, 0));
 358         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 359         zot = it.next();
 360         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1997, 3, 30, 1, 0));
 361         assertEquals(zot.getOffsetBefore(), OFFSET_ZERO);
 362         zot = it.next();
 363         assertEquals(zot.getDateTimeBefore(), LocalDateTime.of(1997, 10, 26, 2, 0));
 364         assertEquals(zot.getOffsetBefore(), OFFSET_PONE);
 365         assertEquals(it.hasNext(), false);
 366     }
 367 
 368     public void test_London_getTransitionRules() {
 369         ZoneRules test = europeLondon();
 370         List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
 371         assertEquals(rules.size(), 2);
 372 
 373         ZoneOffsetTransitionRule in = rules.get(0);
 374         assertEquals(in.getMonth(), Month.MARCH);
 375         assertEquals(in.getDayOfMonthIndicator(), 25);  // optimized from -1
 376         assertEquals(in.getDayOfWeek(), DayOfWeek.SUNDAY);
 377         assertEquals(in.getLocalTime(), LocalTime.of(1, 0));
 378         assertEquals(in.getTimeDefinition(), TimeDefinition.UTC);
 379         assertEquals(in.getStandardOffset(), OFFSET_ZERO);
 380         assertEquals(in.getOffsetBefore(), OFFSET_ZERO);
 381         assertEquals(in.getOffsetAfter(), OFFSET_PONE);
 382 
 383         ZoneOffsetTransitionRule out = rules.get(1);
 384         assertEquals(out.getMonth(), Month.OCTOBER);
 385         assertEquals(out.getDayOfMonthIndicator(), 25);  // optimized from -1
 386         assertEquals(out.getDayOfWeek(), DayOfWeek.SUNDAY);
 387         assertEquals(out.getLocalTime(), LocalTime.of(1, 0));
 388         assertEquals(out.getTimeDefinition(), TimeDefinition.UTC);
 389         assertEquals(out.getStandardOffset(), OFFSET_ZERO);
 390         assertEquals(out.getOffsetBefore(), OFFSET_PONE);
 391         assertEquals(out.getOffsetAfter(), OFFSET_ZERO);
 392     }
 393 
 394     //-----------------------------------------------------------------------
 395     public void test_London_nextTransition_historic() {
 396         ZoneRules test = europeLondon();
 397         List<ZoneOffsetTransition> trans = test.getTransitions();
 398 
 399         ZoneOffsetTransition first = trans.get(0);
 400         assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first);
 401 
 402         for (int i = 0; i < trans.size() - 1; i++) {
 403             ZoneOffsetTransition cur = trans.get(i);
 404             ZoneOffsetTransition next = trans.get(i + 1);
 405 
 406             assertEquals(test.nextTransition(cur.getInstant()), next);
 407             assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next);
 408         }
 409     }
 410 
 411     public void test_London_nextTransition_rulesBased() {
 412         ZoneRules test = europeLondon();
 413         List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
 414         List<ZoneOffsetTransition> trans = test.getTransitions();
 415 
 416         ZoneOffsetTransition last = trans.get(trans.size() - 1);
 417         assertEquals(test.nextTransition(last.getInstant()), rules.get(0).createTransition(1998));
 418 
 419         for (int year = 1998; year < 2010; year++) {
 420             ZoneOffsetTransition a = rules.get(0).createTransition(year);
 421             ZoneOffsetTransition b = rules.get(1).createTransition(year);
 422             ZoneOffsetTransition c = rules.get(0).createTransition(year + 1);
 423 
 424             assertEquals(test.nextTransition(a.getInstant()), b);
 425             assertEquals(test.nextTransition(b.getInstant().minusNanos(1)), b);
 426 
 427             assertEquals(test.nextTransition(b.getInstant()), c);
 428             assertEquals(test.nextTransition(c.getInstant().minusNanos(1)), c);
 429         }
 430     }
 431 
 432     public void test_London_nextTransition_lastYear() {
 433         ZoneRules test = europeLondon();
 434         List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
 435         ZoneOffsetTransition zot = rules.get(1).createTransition(Year.MAX_VALUE);
 436         assertEquals(test.nextTransition(zot.getInstant()), null);
 437     }
 438 
 439     //-----------------------------------------------------------------------
 440     public void test_London_previousTransition_historic() {
 441         ZoneRules test = europeLondon();
 442         List<ZoneOffsetTransition> trans = test.getTransitions();
 443 
 444         ZoneOffsetTransition first = trans.get(0);
 445         assertEquals(test.previousTransition(first.getInstant()), null);
 446         assertEquals(test.previousTransition(first.getInstant().minusNanos(1)), null);
 447 
 448         for (int i = 0; i < trans.size() - 1; i++) {
 449             ZoneOffsetTransition prev = trans.get(i);
 450             ZoneOffsetTransition cur = trans.get(i + 1);
 451 
 452             assertEquals(test.previousTransition(cur.getInstant()), prev);
 453             assertEquals(test.previousTransition(prev.getInstant().plusSeconds(1)), prev);
 454             assertEquals(test.previousTransition(prev.getInstant().plusNanos(1)), prev);
 455         }
 456     }
 457 
 458     public void test_London_previousTransition_rulesBased() {
 459         ZoneRules test = europeLondon();
 460         List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
 461         List<ZoneOffsetTransition> trans = test.getTransitions();
 462 
 463         ZoneOffsetTransition last = trans.get(trans.size() - 1);
 464         assertEquals(test.previousTransition(last.getInstant().plusSeconds(1)), last);
 465         assertEquals(test.previousTransition(last.getInstant().plusNanos(1)), last);
 466 
 467         // Jan 1st of year between transitions and rules
 468         ZonedDateTime odt = ZonedDateTime.ofInstant(last.getInstant(), last.getOffsetAfter());
 469         odt = odt.withDayOfYear(1).plusYears(1).with(LocalTime.MIDNIGHT);
 470         assertEquals(test.previousTransition(odt.toInstant()), last);
 471 
 472         // later years
 473         for (int year = 1998; year < 2010; year++) {
 474             ZoneOffsetTransition a = rules.get(0).createTransition(year);
 475             ZoneOffsetTransition b = rules.get(1).createTransition(year);
 476             ZoneOffsetTransition c = rules.get(0).createTransition(year + 1);
 477 
 478             assertEquals(test.previousTransition(c.getInstant()), b);
 479             assertEquals(test.previousTransition(b.getInstant().plusSeconds(1)), b);
 480             assertEquals(test.previousTransition(b.getInstant().plusNanos(1)), b);
 481 
 482             assertEquals(test.previousTransition(b.getInstant()), a);
 483             assertEquals(test.previousTransition(a.getInstant().plusSeconds(1)), a);
 484             assertEquals(test.previousTransition(a.getInstant().plusNanos(1)), a);
 485         }
 486     }
 487 
 488     //-----------------------------------------------------------------------
 489     // Europe/Paris
 490     //-----------------------------------------------------------------------
 491     private ZoneRules europeParis() {
 492         return ZoneId.of("Europe/Paris").getRules();
 493     }
 494 
 495     public void test_Paris() {
 496         ZoneRules test = europeParis();
 497         assertEquals(test.isFixedOffset(), false);
 498     }
 499 
 500     public void test_Paris_preTimeZones() {
 501         ZoneRules test = europeParis();
 502         ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
 503         Instant instant = old.toInstant();
 504         ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(0, 9, 21);
 505         assertEquals(test.getOffset(instant), offset);
 506         checkOffset(test, old.toLocalDateTime(), offset, 1);
 507         assertEquals(test.getStandardOffset(instant), offset);
 508         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
 509         assertEquals(test.isDaylightSavings(instant), false);
 510     }
 511 
 512     public void test_Paris_getOffset() {
 513         ZoneRules test = europeParis();
 514         assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_PONE);
 515         assertEquals(test.getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), OFFSET_PONE);
 516         assertEquals(test.getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), OFFSET_PONE);
 517         assertEquals(test.getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 518         assertEquals(test.getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 519         assertEquals(test.getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 520         assertEquals(test.getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 521         assertEquals(test.getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 522         assertEquals(test.getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 523         assertEquals(test.getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), OFFSET_PTWO);
 524         assertEquals(test.getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), OFFSET_PONE);
 525         assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_PONE);
 526     }
 527 
 528     public void test_Paris_getOffset_toDST() {
 529         ZoneRules test = europeParis();
 530         assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_PONE);
 531         assertEquals(test.getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), OFFSET_PONE);
 532         assertEquals(test.getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), OFFSET_PONE);
 533         assertEquals(test.getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), OFFSET_PONE);
 534         assertEquals(test.getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), OFFSET_PONE);
 535         assertEquals(test.getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), OFFSET_PONE);
 536         assertEquals(test.getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), OFFSET_PONE);
 537         assertEquals(test.getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), OFFSET_PTWO);
 538         // cutover at 01:00Z
 539         assertEquals(test.getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PONE);
 540         assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PTWO);
 541     }
 542 
 543     public void test_Paris_getOffset_fromDST() {
 544         ZoneRules test = europeParis();
 545         assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PTWO);
 546         assertEquals(test.getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), OFFSET_PTWO);
 547         assertEquals(test.getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), OFFSET_PTWO);
 548         assertEquals(test.getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), OFFSET_PONE);
 549         assertEquals(test.getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), OFFSET_PONE);
 550         assertEquals(test.getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), OFFSET_PONE);
 551         assertEquals(test.getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), OFFSET_PONE);
 552         assertEquals(test.getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), OFFSET_PONE);
 553         // cutover at 01:00Z
 554         assertEquals(test.getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), OFFSET_PTWO);
 555         assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE);
 556     }
 557 
 558     public void test_Paris_getOffsetInfo() {
 559         ZoneRules test = europeParis();
 560         checkOffset(test, createLDT(2008, 1, 1), OFFSET_PONE, 1);
 561         checkOffset(test, createLDT(2008, 2, 1), OFFSET_PONE, 1);
 562         checkOffset(test, createLDT(2008, 3, 1), OFFSET_PONE, 1);
 563         checkOffset(test, createLDT(2008, 4, 1), OFFSET_PTWO, 1);
 564         checkOffset(test, createLDT(2008, 5, 1), OFFSET_PTWO, 1);
 565         checkOffset(test, createLDT(2008, 6, 1), OFFSET_PTWO, 1);
 566         checkOffset(test, createLDT(2008, 7, 1), OFFSET_PTWO, 1);
 567         checkOffset(test, createLDT(2008, 8, 1), OFFSET_PTWO, 1);
 568         checkOffset(test, createLDT(2008, 9, 1), OFFSET_PTWO, 1);
 569         checkOffset(test, createLDT(2008, 10, 1), OFFSET_PTWO, 1);
 570         checkOffset(test, createLDT(2008, 11, 1), OFFSET_PONE, 1);
 571         checkOffset(test, createLDT(2008, 12, 1), OFFSET_PONE, 1);
 572     }
 573 
 574     public void test_Paris_getOffsetInfo_toDST() {
 575         ZoneRules test = europeParis();
 576         checkOffset(test, createLDT(2008, 3, 24), OFFSET_PONE, 1);
 577         checkOffset(test, createLDT(2008, 3, 25), OFFSET_PONE, 1);
 578         checkOffset(test, createLDT(2008, 3, 26), OFFSET_PONE, 1);
 579         checkOffset(test, createLDT(2008, 3, 27), OFFSET_PONE, 1);
 580         checkOffset(test, createLDT(2008, 3, 28), OFFSET_PONE, 1);
 581         checkOffset(test, createLDT(2008, 3, 29), OFFSET_PONE, 1);
 582         checkOffset(test, createLDT(2008, 3, 30), OFFSET_PONE, 1);
 583         checkOffset(test, createLDT(2008, 3, 31), OFFSET_PTWO, 1);
 584         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 585         checkOffset(test, LocalDateTime.of(2008, 3, 30, 1, 59, 59, 999999999), OFFSET_PONE, 1);
 586         checkOffset(test, LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), OFFSET_PTWO, 1);
 587     }
 588 
 589     public void test_Paris_getOffsetInfo_fromDST() {
 590         ZoneRules test = europeParis();
 591         checkOffset(test, createLDT(2008, 10, 24), OFFSET_PTWO, 1);
 592         checkOffset(test, createLDT(2008, 10, 25), OFFSET_PTWO, 1);
 593         checkOffset(test, createLDT(2008, 10, 26), OFFSET_PTWO, 1);
 594         checkOffset(test, createLDT(2008, 10, 27), OFFSET_PONE, 1);
 595         checkOffset(test, createLDT(2008, 10, 28), OFFSET_PONE, 1);
 596         checkOffset(test, createLDT(2008, 10, 29), OFFSET_PONE, 1);
 597         checkOffset(test, createLDT(2008, 10, 30), OFFSET_PONE, 1);
 598         checkOffset(test, createLDT(2008, 10, 31), OFFSET_PONE, 1);
 599         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 600         checkOffset(test, LocalDateTime.of(2008, 10, 26, 1, 59, 59, 999999999), OFFSET_PTWO, 1);
 601         checkOffset(test, LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), OFFSET_PONE, 1);
 602     }
 603 
 604     public void test_Paris_getOffsetInfo_gap() {
 605         ZoneRules test = europeParis();
 606         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0);
 607         ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, GAP);
 608         assertEquals(trans.isGap(), true);
 609         assertEquals(trans.isOverlap(), false);
 610         assertEquals(trans.getOffsetBefore(), OFFSET_PONE);
 611         assertEquals(trans.getOffsetAfter(), OFFSET_PTWO);
 612         assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC));
 613         assertEquals(trans.isValidOffset(OFFSET_ZERO), false);
 614         assertEquals(trans.isValidOffset(OFFSET_PONE), false);
 615         assertEquals(trans.isValidOffset(OFFSET_PTWO), false);
 616         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]");
 617 
 618         assertFalse(trans.equals(null));
 619         assertFalse(trans.equals(OFFSET_PONE));
 620         assertTrue(trans.equals(trans));
 621 
 622         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 623         assertTrue(trans.equals(otherTrans));
 624         assertEquals(trans.hashCode(), otherTrans.hashCode());
 625     }
 626 
 627     public void test_Paris_getOffsetInfo_overlap() {
 628         ZoneRules test = europeParis();
 629         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0);
 630         ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PTWO, OVERLAP);
 631         assertEquals(trans.isGap(), false);
 632         assertEquals(trans.isOverlap(), true);
 633         assertEquals(trans.getOffsetBefore(), OFFSET_PTWO);
 634         assertEquals(trans.getOffsetAfter(), OFFSET_PONE);
 635         assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC));
 636         assertEquals(trans.isValidOffset(OFFSET_ZERO), false);
 637         assertEquals(trans.isValidOffset(OFFSET_PONE), true);
 638         assertEquals(trans.isValidOffset(OFFSET_PTWO), true);
 639         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false);
 640         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]");
 641 
 642         assertFalse(trans.equals(null));
 643         assertFalse(trans.equals(OFFSET_PTWO));
 644         assertTrue(trans.equals(trans));
 645 
 646         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 647         assertTrue(trans.equals(otherTrans));
 648         assertEquals(trans.hashCode(), otherTrans.hashCode());
 649     }
 650 
 651     public void test_Paris_getStandardOffset() {
 652         ZoneRules test = europeParis();
 653         ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC);
 654         while (zdt.getYear() < 2010) {
 655             Instant instant = zdt.toInstant();
 656             if (zdt.toLocalDate().isBefore(LocalDate.of(1911, 3, 11))) {
 657                 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHoursMinutesSeconds(0, 9, 21));
 658             } else if (zdt.toLocalDate().isBefore(LocalDate.of(1940, 6, 14))) {
 659                 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO);
 660             } else if (zdt.toLocalDate().isBefore(LocalDate.of(1944, 8, 25))) {
 661                 assertEquals(test.getStandardOffset(instant), OFFSET_PONE);
 662             } else if (zdt.toLocalDate().isBefore(LocalDate.of(1945, 9, 16))) {
 663                 assertEquals(test.getStandardOffset(instant), OFFSET_ZERO);
 664             } else {
 665                 assertEquals(test.getStandardOffset(instant), OFFSET_PONE);
 666             }
 667             zdt = zdt.plusMonths(6);
 668         }
 669     }
 670 
 671     //-----------------------------------------------------------------------
 672     // America/New_York
 673     //-----------------------------------------------------------------------
 674     private ZoneRules americaNewYork() {
 675         return ZoneId.of("America/New_York").getRules();
 676     }
 677 
 678     public void test_NewYork() {
 679         ZoneRules test = americaNewYork();
 680         assertEquals(test.isFixedOffset(), false);
 681     }
 682 
 683     public void test_NewYork_preTimeZones() {
 684         ZoneRules test = americaNewYork();
 685         ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
 686         Instant instant = old.toInstant();
 687         ZoneOffset offset = ZoneOffset.of("-04:56:02");
 688         assertEquals(test.getOffset(instant), offset);
 689         checkOffset(test, old.toLocalDateTime(), offset, 1);
 690         assertEquals(test.getStandardOffset(instant), offset);
 691         assertEquals(test.getDaylightSavings(instant), Duration.ZERO);
 692         assertEquals(test.isDaylightSavings(instant), false);
 693     }
 694 
 695     public void test_NewYork_getOffset() {
 696         ZoneRules test = americaNewYork();
 697         ZoneOffset offset = ZoneOffset.ofHours(-5);
 698         assertEquals(test.getOffset(createInstant(2008, 1, 1, offset)), ZoneOffset.ofHours(-5));
 699         assertEquals(test.getOffset(createInstant(2008, 2, 1, offset)), ZoneOffset.ofHours(-5));
 700         assertEquals(test.getOffset(createInstant(2008, 3, 1, offset)), ZoneOffset.ofHours(-5));
 701         assertEquals(test.getOffset(createInstant(2008, 4, 1, offset)), ZoneOffset.ofHours(-4));
 702         assertEquals(test.getOffset(createInstant(2008, 5, 1, offset)), ZoneOffset.ofHours(-4));
 703         assertEquals(test.getOffset(createInstant(2008, 6, 1, offset)), ZoneOffset.ofHours(-4));
 704         assertEquals(test.getOffset(createInstant(2008, 7, 1, offset)), ZoneOffset.ofHours(-4));
 705         assertEquals(test.getOffset(createInstant(2008, 8, 1, offset)), ZoneOffset.ofHours(-4));
 706         assertEquals(test.getOffset(createInstant(2008, 9, 1, offset)), ZoneOffset.ofHours(-4));
 707         assertEquals(test.getOffset(createInstant(2008, 10, 1, offset)), ZoneOffset.ofHours(-4));
 708         assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 709         assertEquals(test.getOffset(createInstant(2008, 12, 1, offset)), ZoneOffset.ofHours(-5));
 710         assertEquals(test.getOffset(createInstant(2008, 1, 28, offset)), ZoneOffset.ofHours(-5));
 711         assertEquals(test.getOffset(createInstant(2008, 2, 28, offset)), ZoneOffset.ofHours(-5));
 712         assertEquals(test.getOffset(createInstant(2008, 3, 28, offset)), ZoneOffset.ofHours(-4));
 713         assertEquals(test.getOffset(createInstant(2008, 4, 28, offset)), ZoneOffset.ofHours(-4));
 714         assertEquals(test.getOffset(createInstant(2008, 5, 28, offset)), ZoneOffset.ofHours(-4));
 715         assertEquals(test.getOffset(createInstant(2008, 6, 28, offset)), ZoneOffset.ofHours(-4));
 716         assertEquals(test.getOffset(createInstant(2008, 7, 28, offset)), ZoneOffset.ofHours(-4));
 717         assertEquals(test.getOffset(createInstant(2008, 8, 28, offset)), ZoneOffset.ofHours(-4));
 718         assertEquals(test.getOffset(createInstant(2008, 9, 28, offset)), ZoneOffset.ofHours(-4));
 719         assertEquals(test.getOffset(createInstant(2008, 10, 28, offset)), ZoneOffset.ofHours(-4));
 720         assertEquals(test.getOffset(createInstant(2008, 11, 28, offset)), ZoneOffset.ofHours(-5));
 721         assertEquals(test.getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5));
 722     }
 723 
 724     public void test_NewYork_getOffset_toDST() {
 725         ZoneRules test = americaNewYork();
 726         ZoneOffset offset = ZoneOffset.ofHours(-5);
 727         assertEquals(test.getOffset(createInstant(2008, 3, 8, offset)), ZoneOffset.ofHours(-5));
 728         assertEquals(test.getOffset(createInstant(2008, 3, 9, offset)), ZoneOffset.ofHours(-5));
 729         assertEquals(test.getOffset(createInstant(2008, 3, 10, offset)), ZoneOffset.ofHours(-4));
 730         assertEquals(test.getOffset(createInstant(2008, 3, 11, offset)), ZoneOffset.ofHours(-4));
 731         assertEquals(test.getOffset(createInstant(2008, 3, 12, offset)), ZoneOffset.ofHours(-4));
 732         assertEquals(test.getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4));
 733         assertEquals(test.getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4));
 734         // cutover at 02:00 local
 735         assertEquals(test.getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5));
 736         assertEquals(test.getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4));
 737     }
 738 
 739     public void test_NewYork_getOffset_fromDST() {
 740         ZoneRules test = americaNewYork();
 741         ZoneOffset offset = ZoneOffset.ofHours(-4);
 742         assertEquals(test.getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 743         assertEquals(test.getOffset(createInstant(2008, 11, 2, offset)), ZoneOffset.ofHours(-4));
 744         assertEquals(test.getOffset(createInstant(2008, 11, 3, offset)), ZoneOffset.ofHours(-5));
 745         assertEquals(test.getOffset(createInstant(2008, 11, 4, offset)), ZoneOffset.ofHours(-5));
 746         assertEquals(test.getOffset(createInstant(2008, 11, 5, offset)), ZoneOffset.ofHours(-5));
 747         assertEquals(test.getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5));
 748         assertEquals(test.getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5));
 749         // cutover at 02:00 local
 750         assertEquals(test.getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4));
 751         assertEquals(test.getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5));
 752     }
 753 
 754     public void test_NewYork_getOffsetInfo() {
 755         ZoneRules test = americaNewYork();
 756         checkOffset(test, createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1);
 757         checkOffset(test, createLDT(2008, 2, 1), ZoneOffset.ofHours(-5), 1);
 758         checkOffset(test, createLDT(2008, 3, 1), ZoneOffset.ofHours(-5), 1);
 759         checkOffset(test, createLDT(2008, 4, 1), ZoneOffset.ofHours(-4), 1);
 760         checkOffset(test, createLDT(2008, 5, 1), ZoneOffset.ofHours(-4), 1);
 761         checkOffset(test, createLDT(2008, 6, 1), ZoneOffset.ofHours(-4), 1);
 762         checkOffset(test, createLDT(2008, 7, 1), ZoneOffset.ofHours(-4), 1);
 763         checkOffset(test, createLDT(2008, 8, 1), ZoneOffset.ofHours(-4), 1);
 764         checkOffset(test, createLDT(2008, 9, 1), ZoneOffset.ofHours(-4), 1);
 765         checkOffset(test, createLDT(2008, 10, 1), ZoneOffset.ofHours(-4), 1);
 766         checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 767         checkOffset(test, createLDT(2008, 12, 1), ZoneOffset.ofHours(-5), 1);
 768         checkOffset(test, createLDT(2008, 1, 28), ZoneOffset.ofHours(-5), 1);
 769         checkOffset(test, createLDT(2008, 2, 28), ZoneOffset.ofHours(-5), 1);
 770         checkOffset(test, createLDT(2008, 3, 28), ZoneOffset.ofHours(-4), 1);
 771         checkOffset(test, createLDT(2008, 4, 28), ZoneOffset.ofHours(-4), 1);
 772         checkOffset(test, createLDT(2008, 5, 28), ZoneOffset.ofHours(-4), 1);
 773         checkOffset(test, createLDT(2008, 6, 28), ZoneOffset.ofHours(-4), 1);
 774         checkOffset(test, createLDT(2008, 7, 28), ZoneOffset.ofHours(-4), 1);
 775         checkOffset(test, createLDT(2008, 8, 28), ZoneOffset.ofHours(-4), 1);
 776         checkOffset(test, createLDT(2008, 9, 28), ZoneOffset.ofHours(-4), 1);
 777         checkOffset(test, createLDT(2008, 10, 28), ZoneOffset.ofHours(-4), 1);
 778         checkOffset(test, createLDT(2008, 11, 28), ZoneOffset.ofHours(-5), 1);
 779         checkOffset(test, createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1);
 780     }
 781 
 782     public void test_NewYork_getOffsetInfo_toDST() {
 783         ZoneRules test = americaNewYork();
 784         checkOffset(test, createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1);
 785         checkOffset(test, createLDT(2008, 3, 9), ZoneOffset.ofHours(-5), 1);
 786         checkOffset(test, createLDT(2008, 3, 10), ZoneOffset.ofHours(-4), 1);
 787         checkOffset(test, createLDT(2008, 3, 11), ZoneOffset.ofHours(-4), 1);
 788         checkOffset(test, createLDT(2008, 3, 12), ZoneOffset.ofHours(-4), 1);
 789         checkOffset(test, createLDT(2008, 3, 13), ZoneOffset.ofHours(-4), 1);
 790         checkOffset(test, createLDT(2008, 3, 14), ZoneOffset.ofHours(-4), 1);
 791         // cutover at 02:00 local
 792         checkOffset(test, LocalDateTime.of(2008, 3, 9, 1, 59, 59, 999999999), ZoneOffset.ofHours(-5), 1);
 793         checkOffset(test, LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1);
 794     }
 795 
 796     public void test_NewYork_getOffsetInfo_fromDST() {
 797         ZoneRules test = americaNewYork();
 798         checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 799         checkOffset(test, createLDT(2008, 11, 2), ZoneOffset.ofHours(-4), 1);
 800         checkOffset(test, createLDT(2008, 11, 3), ZoneOffset.ofHours(-5), 1);
 801         checkOffset(test, createLDT(2008, 11, 4), ZoneOffset.ofHours(-5), 1);
 802         checkOffset(test, createLDT(2008, 11, 5), ZoneOffset.ofHours(-5), 1);
 803         checkOffset(test, createLDT(2008, 11, 6), ZoneOffset.ofHours(-5), 1);
 804         checkOffset(test, createLDT(2008, 11, 7), ZoneOffset.ofHours(-5), 1);
 805         // cutover at 02:00 local
 806         checkOffset(test, LocalDateTime.of(2008, 11, 2, 0, 59, 59, 999999999), ZoneOffset.ofHours(-4), 1);
 807         checkOffset(test, LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1);
 808     }
 809 
 810     public void test_NewYork_getOffsetInfo_gap() {
 811         ZoneRules test = americaNewYork();
 812         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0);
 813         ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-5), GAP);
 814         assertEquals(trans.isGap(), true);
 815         assertEquals(trans.isOverlap(), false);
 816         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5));
 817         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4));
 818         assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, ZoneOffset.ofHours(-5)));
 819         assertEquals(trans.isValidOffset(OFFSET_PTWO), false);
 820         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false);
 821         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false);
 822         assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]");
 823 
 824         assertFalse(trans.equals(null));
 825         assertFalse(trans.equals(ZoneOffset.ofHours(-5)));
 826         assertTrue(trans.equals(trans));
 827 
 828         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 829         assertTrue(trans.equals(otherTrans));
 830         assertEquals(trans.hashCode(), otherTrans.hashCode());
 831     }
 832 
 833     public void test_NewYork_getOffsetInfo_overlap() {
 834         ZoneRules test = americaNewYork();
 835         final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0);
 836         ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-4), OVERLAP);
 837         assertEquals(trans.isGap(), false);
 838         assertEquals(trans.isOverlap(), true);
 839         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4));
 840         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5));
 841         assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, ZoneOffset.ofHours(-4)));
 842         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 843         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true);
 844         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true);
 845         assertEquals(trans.isValidOffset(OFFSET_PTWO), false);
 846         assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]");
 847 
 848         assertFalse(trans.equals(null));
 849         assertFalse(trans.equals(ZoneOffset.ofHours(-4)));
 850         assertTrue(trans.equals(trans));
 851 
 852         final ZoneOffsetTransition otherTrans = test.getTransition(dateTime);
 853         assertTrue(trans.equals(otherTrans));
 854         assertEquals(trans.hashCode(), otherTrans.hashCode());
 855     }
 856 
 857     public void test_NewYork_getStandardOffset() {
 858         ZoneRules test = americaNewYork();
 859         ZonedDateTime dateTime = createZDT(1860, 1, 1, ZoneOffset.UTC);
 860         while (dateTime.getYear() < 2010) {
 861             Instant instant = dateTime.toInstant();
 862             if (dateTime.toLocalDate().isBefore(LocalDate.of(1883, 11, 18))) {
 863                 assertEquals(test.getStandardOffset(instant), ZoneOffset.of("-04:56:02"));
 864             } else {
 865                 assertEquals(test.getStandardOffset(instant), ZoneOffset.ofHours(-5));
 866             }
 867             dateTime = dateTime.plusMonths(6);
 868         }
 869     }
 870 
 871     //-----------------------------------------------------------------------
 872     // Kathmandu
 873     //-----------------------------------------------------------------------
 874     private ZoneRules asiaKathmandu() {
 875         return ZoneId.of("Asia/Kathmandu").getRules();
 876     }
 877 
 878     public void test_Kathmandu_nextTransition_historic() {
 879         ZoneRules test = asiaKathmandu();
 880         List<ZoneOffsetTransition> trans = test.getTransitions();
 881 
 882         ZoneOffsetTransition first = trans.get(0);
 883         assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first);
 884 
 885         for (int i = 0; i < trans.size() - 1; i++) {
 886             ZoneOffsetTransition cur = trans.get(i);
 887             ZoneOffsetTransition next = trans.get(i + 1);
 888 
 889             assertEquals(test.nextTransition(cur.getInstant()), next);
 890             assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next);
 891         }
 892     }
 893 
 894     public void test_Kathmandu_nextTransition_noRules() {
 895         ZoneRules test = asiaKathmandu();
 896         List<ZoneOffsetTransition> trans = test.getTransitions();
 897 
 898         ZoneOffsetTransition last = trans.get(trans.size() - 1);
 899         assertEquals(test.nextTransition(last.getInstant()), null);
 900     }
 901 
 902     //-----------------------------------------------------------------------
 903     // Apia
 904     //-----------------------------------------------------------------------
 905     private ZoneRules pacificApia() {
 906         return ZoneId.of("Pacific/Apia").getRules();
 907     }
 908 
 909     public void test_Apia_nextTransition_historic() {
 910         ZoneRules test = pacificApia();
 911         List<ZoneOffsetTransition> trans = test.getTransitions();
 912 
 913         ZoneOffsetTransition first = trans.get(0);
 914         assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first);
 915 
 916         for (int i = 0; i < trans.size() - 1; i++) {
 917             ZoneOffsetTransition cur = trans.get(i);
 918             ZoneOffsetTransition next = trans.get(i + 1);
 919 
 920             assertEquals(test.nextTransition(cur.getInstant()), next);
 921             assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next);
 922         }
 923     }
 924 
 925     public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() {
 926         // transition occurred at 2011-12-30T00:00-10:00
 927         ZoneRules test = pacificApia();
 928         Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant();
 929         ZoneOffsetTransition trans = test.nextTransition(instantBefore);
 930         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0));
 931         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0));
 932         assertEquals(trans.isGap(), true);
 933         assertEquals(trans.isOverlap(), false);
 934         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false);
 935         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false);
 936         assertEquals(trans.getDuration(), Duration.ofHours(24));
 937         assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14)));
 938 
 939         ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia"));
 940         assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0));
 941     }
 942 
 943     public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() {
 944         // transition occurred at 1879-07-04T00:00+12:33:04
 945         ZoneRules test = pacificApia();
 946         Instant instantBefore = LocalDate.of(1879, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant();
 947         ZoneOffsetTransition trans = test.nextTransition(instantBefore);
 948         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1879, 7, 5, 0, 0));
 949         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1879, 7, 4, 0, 0));
 950         assertEquals(trans.isGap(), false);
 951         assertEquals(trans.isOverlap(), true);
 952         assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true);
 953         assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true);
 954         assertEquals(trans.getDuration(), Duration.ofHours(-24));
 955         assertEquals(trans.getInstant(), LocalDateTime.of(1879, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)));
 956 
 957         ZonedDateTime zdt = ZonedDateTime.of(1879, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia"));
 958         assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1879, 7, 4, 1, 0, 0));
 959     }
 960 
 961     //-------------------------------------------------------------------------
 962     @Test(expectedExceptions=UnsupportedOperationException.class)
 963     public void test_getTransitions_immutable() {
 964         ZoneRules test = europeParis();
 965         test.getTransitions().clear();
 966     }
 967 
 968     @Test(expectedExceptions=UnsupportedOperationException.class)
 969     public void test_getTransitionRules_immutable() {
 970         ZoneRules test = europeParis();
 971         test.getTransitionRules().clear();
 972     }
 973 
 974     //-----------------------------------------------------------------------
 975     // of()
 976     //-----------------------------------------------------------------------
 977     public void test_of(){
 978         //used for standard offset
 979         ZoneOffset stdOffset1 = ZoneOffset.UTC;
 980         ZoneOffset stdOffset2 = ZoneOffset.ofHours(1);
 981         LocalDateTime time_of_stdOffsetTransition1 = LocalDateTime.of(2013, 1, 5, 1, 0);
 982         ZoneOffsetTransition  stdOffsetTransition1 = ZoneOffsetTransition.of(time_of_stdOffsetTransition1, stdOffset1, stdOffset2);
 983         List<ZoneOffsetTransition> stdOffsetTransition_list = new ArrayList<ZoneOffsetTransition>();
 984         stdOffsetTransition_list.add(stdOffsetTransition1);
 985 
 986         //used for wall offset
 987         ZoneOffset wallOffset1 = ZoneOffset.ofHours(2);
 988         ZoneOffset wallOffset2 = ZoneOffset.ofHours(4);
 989         ZoneOffset wallOffset3 = ZoneOffset.ofHours(7);
 990 
 991         LocalDateTime time_of_wallOffsetTransition1 = LocalDateTime.of(2013, 2, 5, 1, 0);
 992         LocalDateTime time_of_wallOffsetTransition2 = LocalDateTime.of(2013, 3, 5, 1, 0);
 993         LocalDateTime time_of_wallOffsetTransition3 = LocalDateTime.of(2013, 10, 5, 1, 0);
 994 
 995         ZoneOffsetTransition  wallOffsetTransition1 = ZoneOffsetTransition.of(time_of_wallOffsetTransition1, wallOffset1, wallOffset2);
 996         ZoneOffsetTransition  wallOffsetTransition2 = ZoneOffsetTransition.of(time_of_wallOffsetTransition2, wallOffset2, wallOffset3);
 997         ZoneOffsetTransition  wallOffsetTransition3 = ZoneOffsetTransition.of(time_of_wallOffsetTransition3, wallOffset3, wallOffset1);
 998 
 999         List<ZoneOffsetTransition> wallOffsetTransition_list = new ArrayList<ZoneOffsetTransition>();
1000         wallOffsetTransition_list.add(wallOffsetTransition1);
1001         wallOffsetTransition_list.add(wallOffsetTransition2);
1002         wallOffsetTransition_list.add(wallOffsetTransition3);
1003 
1004         //used for ZoneOffsetTransitionRule
1005         ZoneOffset ruleOffset = ZoneOffset.ofHours(3);
1006         ZoneOffsetTransitionRule.TimeDefinition timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.valueOf("WALL");
1007         ZoneOffsetTransitionRule rule1 = ZoneOffsetTransitionRule.of(Month.FEBRUARY,
1008                                                                      2,
1009                                                                      DayOfWeek.MONDAY,
1010                                                                      LocalTime.of(1, 0),
1011                                                                      false,
1012                                                                      timeDefinition,
1013                                                                      ZoneOffset.UTC,
1014                                                                      ZoneOffset.UTC,
1015                                                                      ruleOffset
1016                                                                      );
1017          List<ZoneOffsetTransitionRule> rule_list = new ArrayList<ZoneOffsetTransitionRule>();
1018          rule_list.add(rule1);
1019 
1020          //Begin verification
1021          ZoneRules zoneRule = ZoneRules.of(stdOffset1,
1022                                            wallOffset1,
1023                                            stdOffsetTransition_list,
1024                                            wallOffsetTransition_list,
1025                                            rule_list
1026                                            );
1027 
1028          OffsetDateTime before_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).minusSeconds(1);
1029          OffsetDateTime after_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).plusSeconds(1);;
1030          assertEquals(zoneRule.getStandardOffset(before_time_of_stdOffsetTransition1.toInstant()), stdOffset1);
1031          assertEquals(zoneRule.getStandardOffset(after_time_of_stdOffsetTransition1.toInstant()), stdOffset2);
1032 
1033          OffsetDateTime  before_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).minusSeconds(1);
1034          OffsetDateTime  after_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).plusSeconds(1);
1035          assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition1);
1036          assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition2);
1037 
1038          OffsetDateTime  before_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).minusSeconds(1);
1039          OffsetDateTime  after_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).plusSeconds(1);
1040          assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition2);
1041          assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition3);
1042 
1043          OffsetDateTime  before_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).minusSeconds(1);
1044          OffsetDateTime  after_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).plusSeconds(1);
1045          assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition3.toInstant()), wallOffsetTransition3);
1046          assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition3.toInstant()), rule1.createTransition(2014));
1047     }
1048 
1049     //-----------------------------------------------------------------------
1050     // equals() / hashCode()
1051     //-----------------------------------------------------------------------
1052     public void test_equals() {
1053         ZoneRules test1 = europeLondon();
1054         ZoneRules test2 = europeParis();
1055         ZoneRules test2b = europeParis();
1056         assertEquals(test1.equals(test2), false);
1057         assertEquals(test2.equals(test1), false);
1058 
1059         assertEquals(test1.equals(test1), true);
1060         assertEquals(test2.equals(test2), true);
1061         assertEquals(test2.equals(test2b), true);
1062 
1063         assertEquals(test1.hashCode() == test1.hashCode(), true);
1064         assertEquals(test2.hashCode() == test2.hashCode(), true);
1065         assertEquals(test2.hashCode() == test2b.hashCode(), true);
1066     }
1067 
1068     public void test_equals_null() {
1069         assertEquals(europeLondon().equals(null), false);
1070     }
1071 
1072     public void test_equals_notZoneRules() {
1073         assertEquals(europeLondon().equals("Europe/London"), false);
1074     }
1075 
1076     public void test_toString() {
1077         assertEquals(europeLondon().toString().contains("ZoneRules"), true);
1078     }
1079 
1080     //-----------------------------------------------------------------------
1081     //-----------------------------------------------------------------------
1082     //-----------------------------------------------------------------------
1083     private Instant createInstant(int year, int month, int day, ZoneOffset offset) {
1084         return LocalDateTime.of(year, month, day, 0, 0).toInstant(offset);
1085     }
1086 
1087     private Instant createInstant(int year, int month, int day, int hour, int min, ZoneOffset offset) {
1088         return LocalDateTime.of(year, month, day, hour, min).toInstant(offset);
1089     }
1090 
1091     private Instant createInstant(int year, int month, int day, int hour, int min, int sec, int nano, ZoneOffset offset) {
1092         return LocalDateTime.of(year, month, day, hour, min, sec, nano).toInstant(offset);
1093     }
1094 
1095     private ZonedDateTime createZDT(int year, int month, int day, ZoneId zone) {
1096         return LocalDateTime.of(year, month, day, 0, 0).atZone(zone);
1097     }
1098 
1099     private LocalDateTime createLDT(int year, int month, int day) {
1100         return LocalDateTime.of(year, month, day, 0, 0);
1101     }
1102 
1103     private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) {
1104         List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime);
1105         assertEquals(validOffsets.size(), type);
1106         assertEquals(rules.getOffset(dateTime), offset);
1107         if (type == 1) {
1108             assertEquals(validOffsets.get(0), offset);
1109             return null;
1110         } else {
1111             ZoneOffsetTransition zot = rules.getTransition(dateTime);
1112             assertNotNull(zot);
1113             assertEquals(zot.isOverlap(), type == 2);
1114             assertEquals(zot.isGap(), type == 0);
1115             assertEquals(zot.isValidOffset(offset), type == 2);
1116             return zot;
1117         }
1118     }
1119 
1120 }