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 test.java.time;
  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.assertSame;
  66 import static org.testng.Assert.assertTrue;
  67 
  68 import java.lang.reflect.Field;
  69 import java.lang.reflect.Modifier;
  70 import java.time.DateTimeException;
  71 import java.time.Instant;
  72 import java.time.LocalDateTime;
  73 import java.time.ZoneId;
  74 import java.time.ZoneOffset;
  75 import java.time.ZonedDateTime;
  76 import java.time.format.TextStyle;
  77 import java.time.zone.ZoneOffsetTransition;
  78 import java.time.zone.ZoneRules;
  79 import java.time.zone.ZoneRulesException;
  80 import java.util.List;
  81 import java.util.Locale;
  82 import java.util.SimpleTimeZone;
  83 import java.util.TimeZone;
  84 
  85 import org.testng.annotations.DataProvider;
  86 import org.testng.annotations.Test;
  87 
  88 /**
  89  * Test ZoneId.
  90  */
  91 @Test
  92 public class TestZoneId extends AbstractTest {
  93 
  94     private static final int OVERLAP = 2;
  95     private static final int GAP = 0;
  96 
  97     //-----------------------------------------------------------------------
  98     // Basics
  99     //-----------------------------------------------------------------------
 100     public void test_immutable() {
 101         // cannot use standard test as ZoneId is abstract
 102         Class<ZoneId> cls = ZoneId.class;
 103         assertTrue(Modifier.isPublic(cls.getModifiers()));
 104         Field[] fields = cls.getDeclaredFields();
 105         for (Field field : fields) {
 106             if (Modifier.isStatic(field.getModifiers()) == false) {
 107                 assertTrue(Modifier.isPrivate(field.getModifiers()));
 108                 assertTrue(Modifier.isFinal(field.getModifiers()) ||
 109                         (Modifier.isVolatile(field.getModifiers()) && Modifier.isTransient(field.getModifiers())));
 110             }
 111         }
 112     }
 113 
 114     //-----------------------------------------------------------------------
 115     // UTC
 116     //-----------------------------------------------------------------------
 117     public void test_constant_UTC() {
 118         ZoneId test = ZoneOffset.UTC;
 119         assertEquals(test.getId(), "Z");
 120         assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), "Z");
 121         assertEquals(test.getRules().isFixedOffset(), true);
 122         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), ZoneOffset.UTC);
 123         checkOffset(test.getRules(), createLDT(2008, 6, 30), ZoneOffset.UTC, 1);
 124         assertSame(test, ZoneId.of("UTC+00"));
 125     }
 126 
 127     //-----------------------------------------------------------------------
 128     // system default
 129     //-----------------------------------------------------------------------
 130     public void test_systemDefault() {
 131         ZoneId test = ZoneId.systemDefault();
 132         assertEquals(test.getId(), TimeZone.getDefault()
 133                                            .getID()
 134                                            .replaceAll("GMT|UTC|UT", "Z"));
 135     }
 136 
 137     @Test(expectedExceptions = DateTimeException.class)
 138     public void test_systemDefault_unableToConvert_badFormat() {
 139         TimeZone current = TimeZone.getDefault();
 140         try {
 141             TimeZone.setDefault(new SimpleTimeZone(127, "Something Weird"));
 142             ZoneId.systemDefault();
 143         } finally {
 144             TimeZone.setDefault(current);
 145         }
 146     }
 147 
 148     @Test(expectedExceptions = ZoneRulesException.class)
 149     public void test_systemDefault_unableToConvert_unknownId() {
 150         TimeZone current = TimeZone.getDefault();
 151         try {
 152             TimeZone.setDefault(new SimpleTimeZone(127, "SomethingWeird"));
 153             ZoneId.systemDefault();
 154         } finally {
 155             TimeZone.setDefault(current);
 156         }
 157     }
 158 
 159     //-----------------------------------------------------------------------
 160     @DataProvider(name="String_Fixed")
 161     Object[][] data_of_string_Fixed() {
 162         return new Object[][] {
 163             {"+0", "Z"},
 164             {"+5", "+05:00"},
 165             {"+01", "+01:00"},
 166             {"+0100", "+01:00"},{"+01:00", "+01:00"},
 167             {"+010000", "+01:00"},{"+01:00:00", "+01:00"},
 168             {"+12", "+12:00"},
 169             {"+1234", "+12:34"},{"+12:34", "+12:34"},
 170             {"+123456", "+12:34:56"},{"+12:34:56", "+12:34:56"},
 171             {"-02", "-02:00"},
 172             {"-5", "-05:00"},
 173             {"-0200", "-02:00"},{"-02:00", "-02:00"},
 174             {"-020000", "-02:00"},{"-02:00:00", "-02:00"},
 175         };
 176     }
 177 
 178     @Test(dataProvider="String_Fixed")
 179     public void test_of_string_offset(String input, String id) {
 180         ZoneId test = ZoneId.of(input);
 181         assertEquals(test.getId(), id);
 182         assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
 183         assertEquals(test.getRules().isFixedOffset(), true);
 184         ZoneOffset offset = ZoneOffset.of(id);
 185         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 186         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 187     }
 188 
 189     @Test(dataProvider="String_Fixed")
 190     public void test_of_string_FixedUTC(String input, String id) {
 191         ZoneId test = ZoneId.of("UTC" + input);
 192         assertEquals(test.getId(), id);
 193         assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
 194         assertEquals(test.getRules().isFixedOffset(), true);
 195         ZoneOffset offset = ZoneOffset.of(id);
 196         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 197         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 198     }
 199 
 200     @Test(dataProvider="String_Fixed")
 201     public void test_of_string_FixedGMT(String input, String id) {
 202         ZoneId test = ZoneId.of("GMT" + input);
 203         assertEquals(test.getId(), id);
 204         assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id);
 205         assertEquals(test.getRules().isFixedOffset(), true);
 206         ZoneOffset offset = ZoneOffset.of(id);
 207         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 208         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 209     }
 210 
 211     //-----------------------------------------------------------------------
 212     // Europe/London
 213     //-----------------------------------------------------------------------
 214     public void test_London() {
 215         ZoneId test = ZoneId.of("Europe/London");
 216         assertEquals(test.getId(), "Europe/London");
 217         assertEquals(test.getRules().isFixedOffset(), false);
 218     }
 219 
 220     public void test_London_getOffset() {
 221         ZoneId test = ZoneId.of("Europe/London");
 222         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 223         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 224         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 225         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 226         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 227         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 228         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 229         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 230         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 231         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 232         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 233         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 234     }
 235 
 236     public void test_London_getOffset_toDST() {
 237         ZoneId test = ZoneId.of("Europe/London");
 238         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 239         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 240         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 241         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 242         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 243         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 244         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 245         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 246         // cutover at 01:00Z
 247         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 248         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 249     }
 250 
 251     public void test_London_getOffset_fromDST() {
 252         ZoneId test = ZoneId.of("Europe/London");
 253         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 254         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 255         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 256         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 257         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 258         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 259         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 260         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 261         // cutover at 01:00Z
 262         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 263         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 264     }
 265 
 266     public void test_London_getOffsetInfo() {
 267         ZoneId test = ZoneId.of("Europe/London");
 268         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(0), 1);
 269         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(0), 1);
 270         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(0), 1);
 271         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(1), 1);
 272         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(1), 1);
 273         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(1), 1);
 274         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(1), 1);
 275         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(1), 1);
 276         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(1), 1);
 277         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(1), 1);
 278         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(0), 1);
 279         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(0), 1);
 280     }
 281 
 282     public void test_London_getOffsetInfo_toDST() {
 283         ZoneId test = ZoneId.of("Europe/London");
 284         checkOffset(test.getRules(), createLDT(2008, 3, 24), ZoneOffset.ofHours(0), 1);
 285         checkOffset(test.getRules(), createLDT(2008, 3, 25), ZoneOffset.ofHours(0), 1);
 286         checkOffset(test.getRules(), createLDT(2008, 3, 26), ZoneOffset.ofHours(0), 1);
 287         checkOffset(test.getRules(), createLDT(2008, 3, 27), ZoneOffset.ofHours(0), 1);
 288         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(0), 1);
 289         checkOffset(test.getRules(), createLDT(2008, 3, 29), ZoneOffset.ofHours(0), 1);
 290         checkOffset(test.getRules(), createLDT(2008, 3, 30), ZoneOffset.ofHours(0), 1);
 291         checkOffset(test.getRules(), createLDT(2008, 3, 31), ZoneOffset.ofHours(1), 1);
 292         // cutover at 01:00Z
 293         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 0, 59, 59, 999999999), ZoneOffset.ofHours(0), 1);
 294         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 1, 30, 0, 0), ZoneOffset.ofHours(0), GAP);
 295         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0), ZoneOffset.ofHours(1), 1);
 296     }
 297 
 298     public void test_London_getOffsetInfo_fromDST() {
 299         ZoneId test = ZoneId.of("Europe/London");
 300         checkOffset(test.getRules(), createLDT(2008, 10, 24), ZoneOffset.ofHours(1), 1);
 301         checkOffset(test.getRules(), createLDT(2008, 10, 25), ZoneOffset.ofHours(1), 1);
 302         checkOffset(test.getRules(), createLDT(2008, 10, 26), ZoneOffset.ofHours(1), 1);
 303         checkOffset(test.getRules(), createLDT(2008, 10, 27), ZoneOffset.ofHours(0), 1);
 304         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(0), 1);
 305         checkOffset(test.getRules(), createLDT(2008, 10, 29), ZoneOffset.ofHours(0), 1);
 306         checkOffset(test.getRules(), createLDT(2008, 10, 30), ZoneOffset.ofHours(0), 1);
 307         checkOffset(test.getRules(), createLDT(2008, 10, 31), ZoneOffset.ofHours(0), 1);
 308         // cutover at 01:00Z
 309         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 0, 59, 59, 999999999), ZoneOffset.ofHours(1), 1);
 310         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 1, 30, 0, 0), ZoneOffset.ofHours(1), OVERLAP);
 311         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0), ZoneOffset.ofHours(0), 1);
 312     }
 313 
 314     public void test_London_getOffsetInfo_gap() {
 315         ZoneId test = ZoneId.of("Europe/London");
 316         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0);
 317         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(0), GAP);
 318         assertEquals(trans.isGap(), true);
 319         assertEquals(trans.isOverlap(), false);
 320         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(0));
 321         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1));
 322         assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC));
 323         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0));
 324         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0));
 325         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 326         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 327         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false);
 328         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 329         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]");
 330 
 331         assertFalse(trans.equals(null));
 332         assertFalse(trans.equals(ZoneOffset.ofHours(0)));
 333         assertTrue(trans.equals(trans));
 334 
 335         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 336         assertTrue(trans.equals(otherTrans));
 337         assertEquals(trans.hashCode(), otherTrans.hashCode());
 338     }
 339 
 340     public void test_London_getOffsetInfo_overlap() {
 341         ZoneId test = ZoneId.of("Europe/London");
 342         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0);
 343         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), OVERLAP);
 344         assertEquals(trans.isGap(), false);
 345         assertEquals(trans.isOverlap(), true);
 346         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1));
 347         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(0));
 348         assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC));
 349         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0));
 350         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0));
 351         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 352         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), true);
 353         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true);
 354         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 355         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]");
 356 
 357         assertFalse(trans.equals(null));
 358         assertFalse(trans.equals(ZoneOffset.ofHours(1)));
 359         assertTrue(trans.equals(trans));
 360 
 361         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 362         assertTrue(trans.equals(otherTrans));
 363         assertEquals(trans.hashCode(), otherTrans.hashCode());
 364     }
 365 
 366     //-----------------------------------------------------------------------
 367     // Europe/Paris
 368     //-----------------------------------------------------------------------
 369     public void test_Paris() {
 370         ZoneId test = ZoneId.of("Europe/Paris");
 371         assertEquals(test.getId(), "Europe/Paris");
 372         assertEquals(test.getRules().isFixedOffset(), false);
 373     }
 374 
 375     public void test_Paris_getOffset() {
 376         ZoneId test = ZoneId.of("Europe/Paris");
 377         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 378         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 379         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 380         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 381         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 382         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 383         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 384         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 385         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 386         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 387         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 388         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 389     }
 390 
 391     public void test_Paris_getOffset_toDST() {
 392         ZoneId test = ZoneId.of("Europe/Paris");
 393         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 394         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 395         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 396         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 397         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 398         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 399         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 400         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 401         // cutover at 01:00Z
 402         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 403         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 404     }
 405 
 406     public void test_Paris_getOffset_fromDST() {
 407         ZoneId test = ZoneId.of("Europe/Paris");
 408         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 409         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 410         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 411         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 412         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 413         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 414         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 415         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 416         // cutover at 01:00Z
 417         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 418         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 419     }
 420 
 421     public void test_Paris_getOffsetInfo() {
 422         ZoneId test = ZoneId.of("Europe/Paris");
 423         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(1), 1);
 424         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(1), 1);
 425         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(1), 1);
 426         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(2), 1);
 427         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(2), 1);
 428         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(2), 1);
 429         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(2), 1);
 430         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(2), 1);
 431         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(2), 1);
 432         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(2), 1);
 433         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(1), 1);
 434         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(1), 1);
 435     }
 436 
 437     public void test_Paris_getOffsetInfo_toDST() {
 438         ZoneId test = ZoneId.of("Europe/Paris");
 439         checkOffset(test.getRules(), createLDT(2008, 3, 24), ZoneOffset.ofHours(1), 1);
 440         checkOffset(test.getRules(), createLDT(2008, 3, 25), ZoneOffset.ofHours(1), 1);
 441         checkOffset(test.getRules(), createLDT(2008, 3, 26), ZoneOffset.ofHours(1), 1);
 442         checkOffset(test.getRules(), createLDT(2008, 3, 27), ZoneOffset.ofHours(1), 1);
 443         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(1), 1);
 444         checkOffset(test.getRules(), createLDT(2008, 3, 29), ZoneOffset.ofHours(1), 1);
 445         checkOffset(test.getRules(), createLDT(2008, 3, 30), ZoneOffset.ofHours(1), 1);
 446         checkOffset(test.getRules(), createLDT(2008, 3, 31), ZoneOffset.ofHours(2), 1);
 447         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 448         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 1, 59, 59, 999999999), ZoneOffset.ofHours(1), 1);
 449         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 2, 30, 0, 0), ZoneOffset.ofHours(1), GAP);
 450         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), ZoneOffset.ofHours(2), 1);
 451     }
 452 
 453     public void test_Paris_getOffsetInfo_fromDST() {
 454         ZoneId test = ZoneId.of("Europe/Paris");
 455         checkOffset(test.getRules(), createLDT(2008, 10, 24), ZoneOffset.ofHours(2), 1);
 456         checkOffset(test.getRules(), createLDT(2008, 10, 25), ZoneOffset.ofHours(2), 1);
 457         checkOffset(test.getRules(), createLDT(2008, 10, 26), ZoneOffset.ofHours(2), 1);
 458         checkOffset(test.getRules(), createLDT(2008, 10, 27), ZoneOffset.ofHours(1), 1);
 459         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(1), 1);
 460         checkOffset(test.getRules(), createLDT(2008, 10, 29), ZoneOffset.ofHours(1), 1);
 461         checkOffset(test.getRules(), createLDT(2008, 10, 30), ZoneOffset.ofHours(1), 1);
 462         checkOffset(test.getRules(), createLDT(2008, 10, 31), ZoneOffset.ofHours(1), 1);
 463         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 464         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 1, 59, 59, 999999999), ZoneOffset.ofHours(2), 1);
 465         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 2, 30, 0, 0), ZoneOffset.ofHours(2), OVERLAP);
 466         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), ZoneOffset.ofHours(1), 1);
 467     }
 468 
 469     public void test_Paris_getOffsetInfo_gap() {
 470         ZoneId test = ZoneId.of("Europe/Paris");
 471         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0);
 472         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), GAP);
 473         assertEquals(trans.isGap(), true);
 474         assertEquals(trans.isOverlap(), false);
 475         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1));
 476         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(2));
 477         assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC));
 478         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 479         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false);
 480         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 481         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false);
 482         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]");
 483 
 484         assertFalse(trans.equals(null));
 485         assertFalse(trans.equals(ZoneOffset.ofHours(1)));
 486         assertTrue(trans.equals(trans));
 487 
 488         final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime);
 489         assertTrue(trans.equals(otherDis));
 490         assertEquals(trans.hashCode(), otherDis.hashCode());
 491     }
 492 
 493     public void test_Paris_getOffsetInfo_overlap() {
 494         ZoneId test = ZoneId.of("Europe/Paris");
 495         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0);
 496         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(2), OVERLAP);
 497         assertEquals(trans.isGap(), false);
 498         assertEquals(trans.isOverlap(), true);
 499         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(2));
 500         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1));
 501         assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC));
 502         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 503         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true);
 504         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), true);
 505         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false);
 506         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]");
 507 
 508         assertFalse(trans.equals(null));
 509         assertFalse(trans.equals(ZoneOffset.ofHours(2)));
 510         assertTrue(trans.equals(trans));
 511 
 512         final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime);
 513         assertTrue(trans.equals(otherDis));
 514         assertEquals(trans.hashCode(), otherDis.hashCode());
 515     }
 516 
 517     //-----------------------------------------------------------------------
 518     // America/New_York
 519     //-----------------------------------------------------------------------
 520     public void test_NewYork() {
 521         ZoneId test = ZoneId.of("America/New_York");
 522         assertEquals(test.getId(), "America/New_York");
 523         assertEquals(test.getRules().isFixedOffset(), false);
 524     }
 525 
 526     public void test_NewYork_getOffset() {
 527         ZoneId test = ZoneId.of("America/New_York");
 528         ZoneOffset offset = ZoneOffset.ofHours(-5);
 529         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, offset)), ZoneOffset.ofHours(-5));
 530         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, offset)), ZoneOffset.ofHours(-5));
 531         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, offset)), ZoneOffset.ofHours(-5));
 532         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, offset)), ZoneOffset.ofHours(-4));
 533         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, offset)), ZoneOffset.ofHours(-4));
 534         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, offset)), ZoneOffset.ofHours(-4));
 535         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, offset)), ZoneOffset.ofHours(-4));
 536         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, offset)), ZoneOffset.ofHours(-4));
 537         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, offset)), ZoneOffset.ofHours(-4));
 538         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, offset)), ZoneOffset.ofHours(-4));
 539         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 540         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, offset)), ZoneOffset.ofHours(-5));
 541         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 28, offset)), ZoneOffset.ofHours(-5));
 542         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 28, offset)), ZoneOffset.ofHours(-5));
 543         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, offset)), ZoneOffset.ofHours(-4));
 544         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 28, offset)), ZoneOffset.ofHours(-4));
 545         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 28, offset)), ZoneOffset.ofHours(-4));
 546         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 28, offset)), ZoneOffset.ofHours(-4));
 547         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 28, offset)), ZoneOffset.ofHours(-4));
 548         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 28, offset)), ZoneOffset.ofHours(-4));
 549         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 28, offset)), ZoneOffset.ofHours(-4));
 550         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, offset)), ZoneOffset.ofHours(-4));
 551         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 28, offset)), ZoneOffset.ofHours(-5));
 552         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5));
 553     }
 554 
 555     public void test_NewYork_getOffset_toDST() {
 556         ZoneId test = ZoneId.of("America/New_York");
 557         ZoneOffset offset = ZoneOffset.ofHours(-5);
 558         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 8, offset)), ZoneOffset.ofHours(-5));
 559         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, offset)), ZoneOffset.ofHours(-5));
 560         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 10, offset)), ZoneOffset.ofHours(-4));
 561         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 11, offset)), ZoneOffset.ofHours(-4));
 562         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 12, offset)), ZoneOffset.ofHours(-4));
 563         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4));
 564         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4));
 565         // cutover at 02:00 local
 566         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5));
 567         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4));
 568     }
 569 
 570     public void test_NewYork_getOffset_fromDST() {
 571         ZoneId test = ZoneId.of("America/New_York");
 572         ZoneOffset offset = ZoneOffset.ofHours(-4);
 573         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 574         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, offset)), ZoneOffset.ofHours(-4));
 575         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 3, offset)), ZoneOffset.ofHours(-5));
 576         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 4, offset)), ZoneOffset.ofHours(-5));
 577         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 5, offset)), ZoneOffset.ofHours(-5));
 578         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5));
 579         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5));
 580         // cutover at 02:00 local
 581         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4));
 582         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5));
 583     }
 584 
 585     public void test_NewYork_getOffsetInfo() {
 586         ZoneId test = ZoneId.of("America/New_York");
 587         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1);
 588         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(-5), 1);
 589         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(-5), 1);
 590         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(-4), 1);
 591         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(-4), 1);
 592         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(-4), 1);
 593         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(-4), 1);
 594         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(-4), 1);
 595         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(-4), 1);
 596         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(-4), 1);
 597         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 598         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(-5), 1);
 599         checkOffset(test.getRules(), createLDT(2008, 1, 28), ZoneOffset.ofHours(-5), 1);
 600         checkOffset(test.getRules(), createLDT(2008, 2, 28), ZoneOffset.ofHours(-5), 1);
 601         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(-4), 1);
 602         checkOffset(test.getRules(), createLDT(2008, 4, 28), ZoneOffset.ofHours(-4), 1);
 603         checkOffset(test.getRules(), createLDT(2008, 5, 28), ZoneOffset.ofHours(-4), 1);
 604         checkOffset(test.getRules(), createLDT(2008, 6, 28), ZoneOffset.ofHours(-4), 1);
 605         checkOffset(test.getRules(), createLDT(2008, 7, 28), ZoneOffset.ofHours(-4), 1);
 606         checkOffset(test.getRules(), createLDT(2008, 8, 28), ZoneOffset.ofHours(-4), 1);
 607         checkOffset(test.getRules(), createLDT(2008, 9, 28), ZoneOffset.ofHours(-4), 1);
 608         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(-4), 1);
 609         checkOffset(test.getRules(), createLDT(2008, 11, 28), ZoneOffset.ofHours(-5), 1);
 610         checkOffset(test.getRules(), createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1);
 611     }
 612 
 613     public void test_NewYork_getOffsetInfo_toDST() {
 614         ZoneId test = ZoneId.of("America/New_York");
 615         checkOffset(test.getRules(), createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1);
 616         checkOffset(test.getRules(), createLDT(2008, 3, 9), ZoneOffset.ofHours(-5), 1);
 617         checkOffset(test.getRules(), createLDT(2008, 3, 10), ZoneOffset.ofHours(-4), 1);
 618         checkOffset(test.getRules(), createLDT(2008, 3, 11), ZoneOffset.ofHours(-4), 1);
 619         checkOffset(test.getRules(), createLDT(2008, 3, 12), ZoneOffset.ofHours(-4), 1);
 620         checkOffset(test.getRules(), createLDT(2008, 3, 13), ZoneOffset.ofHours(-4), 1);
 621         checkOffset(test.getRules(), createLDT(2008, 3, 14), ZoneOffset.ofHours(-4), 1);
 622         // cutover at 02:00 local
 623         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 1, 59, 59, 999999999), ZoneOffset.ofHours(-5), 1);
 624         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 2, 30, 0, 0), ZoneOffset.ofHours(-5), GAP);
 625         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1);
 626     }
 627 
 628     public void test_NewYork_getOffsetInfo_fromDST() {
 629         ZoneId test = ZoneId.of("America/New_York");
 630         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 631         checkOffset(test.getRules(), createLDT(2008, 11, 2), ZoneOffset.ofHours(-4), 1);
 632         checkOffset(test.getRules(), createLDT(2008, 11, 3), ZoneOffset.ofHours(-5), 1);
 633         checkOffset(test.getRules(), createLDT(2008, 11, 4), ZoneOffset.ofHours(-5), 1);
 634         checkOffset(test.getRules(), createLDT(2008, 11, 5), ZoneOffset.ofHours(-5), 1);
 635         checkOffset(test.getRules(), createLDT(2008, 11, 6), ZoneOffset.ofHours(-5), 1);
 636         checkOffset(test.getRules(), createLDT(2008, 11, 7), ZoneOffset.ofHours(-5), 1);
 637         // cutover at 02:00 local
 638         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 0, 59, 59, 999999999), ZoneOffset.ofHours(-4), 1);
 639         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 1, 30, 0, 0), ZoneOffset.ofHours(-4), OVERLAP);
 640         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1);
 641     }
 642 
 643     public void test_NewYork_getOffsetInfo_gap() {
 644         ZoneId test = ZoneId.of("America/New_York");
 645         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0);
 646         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-5), GAP);
 647         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5));
 648         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4));
 649         assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, 0, 0, ZoneOffset.ofHours(-5)));
 650         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-6)), false);
 651         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false);
 652         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false);
 653         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-3)), false);
 654         assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]");
 655 
 656         assertFalse(trans.equals(null));
 657         assertFalse(trans.equals(ZoneOffset.ofHours(-5)));
 658         assertTrue(trans.equals(trans));
 659 
 660         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 661         assertTrue(trans.equals(otherTrans));
 662 
 663         assertEquals(trans.hashCode(), otherTrans.hashCode());
 664     }
 665 
 666     public void test_NewYork_getOffsetInfo_overlap() {
 667         ZoneId test = ZoneId.of("America/New_York");
 668         final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0);
 669         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-4), OVERLAP);
 670         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4));
 671         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5));
 672         assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, 0, 0, ZoneOffset.ofHours(-4)));
 673         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 674         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true);
 675         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true);
 676         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 677         assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]");
 678 
 679         assertFalse(trans.equals(null));
 680         assertFalse(trans.equals(ZoneOffset.ofHours(-4)));
 681         assertTrue(trans.equals(trans));
 682 
 683         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 684         assertTrue(trans.equals(otherTrans));
 685 
 686         assertEquals(trans.hashCode(), otherTrans.hashCode());
 687     }
 688 
 689     //-----------------------------------------------------------------------
 690     // getXxx() isXxx()
 691     //-----------------------------------------------------------------------
 692     public void test_get_Tzdb() {
 693         ZoneId test = ZoneId.of("Europe/London");
 694         assertEquals(test.getId(), "Europe/London");
 695         assertEquals(test.getRules().isFixedOffset(), false);
 696     }
 697 
 698     public void test_get_TzdbFixed() {
 699         ZoneId test = ZoneId.of("+01:30");
 700         assertEquals(test.getId(), "+01:30");
 701         assertEquals(test.getRules().isFixedOffset(), true);
 702     }
 703 
 704     //-----------------------------------------------------------------------
 705     //-----------------------------------------------------------------------
 706     //-----------------------------------------------------------------------
 707     private Instant createInstant(int year, int month, int day, ZoneOffset offset) {
 708         return LocalDateTime.of(year, month, day, 0, 0).toInstant(offset);
 709     }
 710 
 711     private Instant createInstant(int year, int month, int day, int hour, int min, int sec, int nano, ZoneOffset offset) {
 712         return LocalDateTime.of(year, month, day, hour, min, sec, nano).toInstant(offset);
 713     }
 714 
 715     private ZonedDateTime createZDT(int year, int month, int day, int hour, int min, int sec, int nano, ZoneId zone) {
 716         return LocalDateTime.of(year, month, day, hour, min, sec, nano).atZone(zone);
 717     }
 718 
 719     private LocalDateTime createLDT(int year, int month, int day) {
 720         return LocalDateTime.of(year, month, day, 0, 0);
 721     }
 722 
 723     private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) {
 724         List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime);
 725         assertEquals(validOffsets.size(), type);
 726         assertEquals(rules.getOffset(dateTime), offset);
 727         if (type == 1) {
 728             assertEquals(validOffsets.get(0), offset);
 729             return null;
 730         } else {
 731             ZoneOffsetTransition zot = rules.getTransition(dateTime);
 732             assertNotNull(zot);
 733             assertEquals(zot.isOverlap(), type == 2);
 734             assertEquals(zot.isGap(), type == 0);
 735             assertEquals(zot.isValidOffset(offset), type == 2);
 736             return zot;
 737         }
 738     }
 739 
 740 }