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 java.time.*;
  63 
  64 import static org.testng.Assert.assertEquals;
  65 import static org.testng.Assert.assertFalse;
  66 import static org.testng.Assert.assertNotNull;
  67 import static org.testng.Assert.assertSame;
  68 import static org.testng.Assert.assertTrue;
  69 
  70 import java.io.IOException;
  71 import java.lang.reflect.Field;
  72 import java.lang.reflect.Modifier;
  73 import java.util.HashMap;
  74 import java.util.List;
  75 import java.util.Locale;
  76 import java.util.Map;
  77 import java.util.SimpleTimeZone;
  78 import java.util.TimeZone;
  79 
  80 import java.time.temporal.Queries;
  81 import java.time.temporal.TemporalQuery;
  82 import java.time.temporal.TemporalAccessor;
  83 import java.time.temporal.TemporalField;
  84 import java.time.format.TextStyle;
  85 import java.time.zone.ZoneOffsetTransition;
  86 import java.time.zone.ZoneRules;
  87 import java.time.zone.ZoneRulesException;
  88 
  89 import org.testng.annotations.DataProvider;
  90 import org.testng.annotations.Test;
  91 
  92 /**
  93  * Test ZoneId.
  94  */
  95 @Test
  96 public class TestZoneId extends AbstractTest {
  97 
  98     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
  99     public static final String LATEST_TZDB = "2010i";
 100     private static final int OVERLAP = 2;
 101     private static final int GAP = 0;
 102 
 103     //-----------------------------------------------------------------------
 104     // Basics
 105     //-----------------------------------------------------------------------
 106     public void test_immutable() {
 107         Class<ZoneId> cls = ZoneId.class;
 108         assertTrue(Modifier.isPublic(cls.getModifiers()));
 109         Field[] fields = cls.getDeclaredFields();
 110         for (Field field : fields) {
 111             if (Modifier.isStatic(field.getModifiers()) == false) {
 112                 assertTrue(Modifier.isPrivate(field.getModifiers()));
 113                 assertTrue(Modifier.isFinal(field.getModifiers()) ||
 114                         (Modifier.isVolatile(field.getModifiers()) && Modifier.isTransient(field.getModifiers())));
 115             }
 116         }
 117     }
 118 
 119     public void test_serialization_UTC() throws Exception {
 120         ZoneId test = ZoneOffset.UTC;
 121         assertSerializableAndSame(test);
 122     }
 123 
 124     public void test_serialization_fixed() throws Exception {
 125         ZoneId test = ZoneId.of("UTC+01:30");
 126         assertSerializable(test);
 127     }
 128 
 129     public void test_serialization_Europe() throws Exception {
 130         ZoneId test = ZoneId.of("Europe/London");
 131         assertSerializable(test);
 132     }
 133 
 134     public void test_serialization_America() throws Exception {
 135         ZoneId test = ZoneId.of("America/Chicago");
 136         assertSerializable(test);
 137     }
 138 
 139     //-----------------------------------------------------------------------
 140     // UTC
 141     //-----------------------------------------------------------------------
 142     public void test_constant_UTC() {
 143         ZoneId test = ZoneOffset.UTC;
 144         assertEquals(test.getId(), "Z");
 145         assertEquals(test.getText(TextStyle.FULL, Locale.UK), "Z");
 146         assertEquals(test.getRules().isFixedOffset(), true);
 147         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), ZoneOffset.UTC);
 148         checkOffset(test.getRules(), createLDT(2008, 6, 30), ZoneOffset.UTC, 1);
 149         assertSame(test, ZoneId.of("UTC+00"));
 150     }
 151 
 152     //-----------------------------------------------------------------------
 153     // OLD_IDS_PRE_2005
 154     //-----------------------------------------------------------------------
 155     public void test_constant_OLD_IDS_PRE_2005() {
 156         Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
 157         assertEquals(ids.get("EST"), "America/Indianapolis");
 158         assertEquals(ids.get("MST"), "America/Phoenix");
 159         assertEquals(ids.get("HST"), "Pacific/Honolulu");
 160         assertEquals(ids.get("ACT"), "Australia/Darwin");
 161         assertEquals(ids.get("AET"), "Australia/Sydney");
 162         assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
 163         assertEquals(ids.get("ART"), "Africa/Cairo");
 164         assertEquals(ids.get("AST"), "America/Anchorage");
 165         assertEquals(ids.get("BET"), "America/Sao_Paulo");
 166         assertEquals(ids.get("BST"), "Asia/Dhaka");
 167         assertEquals(ids.get("CAT"), "Africa/Harare");
 168         assertEquals(ids.get("CNT"), "America/St_Johns");
 169         assertEquals(ids.get("CST"), "America/Chicago");
 170         assertEquals(ids.get("CTT"), "Asia/Shanghai");
 171         assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
 172         assertEquals(ids.get("ECT"), "Europe/Paris");
 173         assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
 174         assertEquals(ids.get("IST"), "Asia/Kolkata");
 175         assertEquals(ids.get("JST"), "Asia/Tokyo");
 176         assertEquals(ids.get("MIT"), "Pacific/Apia");
 177         assertEquals(ids.get("NET"), "Asia/Yerevan");
 178         assertEquals(ids.get("NST"), "Pacific/Auckland");
 179         assertEquals(ids.get("PLT"), "Asia/Karachi");
 180         assertEquals(ids.get("PNT"), "America/Phoenix");
 181         assertEquals(ids.get("PRT"), "America/Puerto_Rico");
 182         assertEquals(ids.get("PST"), "America/Los_Angeles");
 183         assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
 184         assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
 185     }
 186 
 187     @Test(expectedExceptions=UnsupportedOperationException.class)
 188     public void test_constant_OLD_IDS_PRE_2005_immutable() {
 189         Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005;
 190         ids.clear();
 191     }
 192 
 193     //-----------------------------------------------------------------------
 194     // OLD_IDS_POST_2005
 195     //-----------------------------------------------------------------------
 196     public void test_constant_OLD_IDS_POST_2005() {
 197         Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
 198         assertEquals(ids.get("EST"), "-05:00");
 199         assertEquals(ids.get("MST"), "-07:00");
 200         assertEquals(ids.get("HST"), "-10:00");
 201         assertEquals(ids.get("ACT"), "Australia/Darwin");
 202         assertEquals(ids.get("AET"), "Australia/Sydney");
 203         assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires");
 204         assertEquals(ids.get("ART"), "Africa/Cairo");
 205         assertEquals(ids.get("AST"), "America/Anchorage");
 206         assertEquals(ids.get("BET"), "America/Sao_Paulo");
 207         assertEquals(ids.get("BST"), "Asia/Dhaka");
 208         assertEquals(ids.get("CAT"), "Africa/Harare");
 209         assertEquals(ids.get("CNT"), "America/St_Johns");
 210         assertEquals(ids.get("CST"), "America/Chicago");
 211         assertEquals(ids.get("CTT"), "Asia/Shanghai");
 212         assertEquals(ids.get("EAT"), "Africa/Addis_Ababa");
 213         assertEquals(ids.get("ECT"), "Europe/Paris");
 214         assertEquals(ids.get("IET"), "America/Indiana/Indianapolis");
 215         assertEquals(ids.get("IST"), "Asia/Kolkata");
 216         assertEquals(ids.get("JST"), "Asia/Tokyo");
 217         assertEquals(ids.get("MIT"), "Pacific/Apia");
 218         assertEquals(ids.get("NET"), "Asia/Yerevan");
 219         assertEquals(ids.get("NST"), "Pacific/Auckland");
 220         assertEquals(ids.get("PLT"), "Asia/Karachi");
 221         assertEquals(ids.get("PNT"), "America/Phoenix");
 222         assertEquals(ids.get("PRT"), "America/Puerto_Rico");
 223         assertEquals(ids.get("PST"), "America/Los_Angeles");
 224         assertEquals(ids.get("SST"), "Pacific/Guadalcanal");
 225         assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh");
 226     }
 227 
 228     @Test(expectedExceptions=UnsupportedOperationException.class)
 229     public void test_constant_OLD_IDS_POST_2005_immutable() {
 230         Map<String, String> ids = ZoneId.OLD_IDS_POST_2005;
 231         ids.clear();
 232     }
 233 
 234     //-----------------------------------------------------------------------
 235     // system default
 236     //-----------------------------------------------------------------------
 237     public void test_systemDefault() {
 238         ZoneId test = ZoneId.systemDefault();
 239         assertEquals(test.getId(), TimeZone.getDefault().getID());
 240     }
 241 
 242     @Test(expectedExceptions = DateTimeException.class)
 243     public void test_systemDefault_unableToConvert_badFormat() {
 244         TimeZone current = TimeZone.getDefault();
 245         try {
 246             TimeZone.setDefault(new SimpleTimeZone(127, "Something Weird"));
 247             ZoneId.systemDefault();
 248         } finally {
 249             TimeZone.setDefault(current);
 250         }
 251     }
 252 
 253     @Test(expectedExceptions = ZoneRulesException.class)
 254     public void test_systemDefault_unableToConvert_unknownId() {
 255         TimeZone current = TimeZone.getDefault();
 256         try {
 257             TimeZone.setDefault(new SimpleTimeZone(127, "SomethingWeird"));
 258             ZoneId.systemDefault();
 259         } finally {
 260             TimeZone.setDefault(current);
 261         }
 262     }
 263 
 264     //-----------------------------------------------------------------------
 265     // mapped factory
 266     //-----------------------------------------------------------------------
 267     public void test_of_string_Map() {
 268         Map<String, String> map = new HashMap<String, String>();
 269         map.put("LONDON", "Europe/London");
 270         map.put("PARIS", "Europe/Paris");
 271         ZoneId test = ZoneId.of("LONDON", map);
 272         assertEquals(test.getId(), "Europe/London");
 273     }
 274 
 275     public void test_of_string_Map_lookThrough() {
 276         Map<String, String> map = new HashMap<String, String>();
 277         map.put("LONDON", "Europe/London");
 278         map.put("PARIS", "Europe/Paris");
 279         ZoneId test = ZoneId.of("Europe/Madrid", map);
 280         assertEquals(test.getId(), "Europe/Madrid");
 281     }
 282 
 283     public void test_of_string_Map_emptyMap() {
 284         Map<String, String> map = new HashMap<String, String>();
 285         ZoneId test = ZoneId.of("Europe/Madrid", map);
 286         assertEquals(test.getId(), "Europe/Madrid");
 287     }
 288 
 289     @Test(expectedExceptions=DateTimeException.class)
 290     public void test_of_string_Map_badFormat() {
 291         Map<String, String> map = new HashMap<String, String>();
 292         ZoneId.of("Not kknown", map);
 293     }
 294 
 295     @Test(expectedExceptions=ZoneRulesException.class)
 296     public void test_of_string_Map_unknown() {
 297         Map<String, String> map = new HashMap<String, String>();
 298         ZoneId.of("Unknown", map);
 299     }
 300 
 301     //-----------------------------------------------------------------------
 302     // regular factory
 303     //-----------------------------------------------------------------------
 304     @DataProvider(name="String_UTC")
 305     Object[][] data_of_string_UTC() {
 306         return new Object[][] {
 307             {""}, {"Z"},
 308             {"+00"},{"+0000"},{"+00:00"},{"+000000"},{"+00:00:00"},
 309             {"-00"},{"-0000"},{"-00:00"},{"-000000"},{"-00:00:00"},
 310         };
 311     }
 312 
 313     @Test(dataProvider="String_UTC")
 314     public void test_of_string_UTC(String id) {
 315         ZoneId test = ZoneId.of("UTC" + id);
 316         assertSame(test, ZoneOffset.UTC);
 317     }
 318 
 319     @Test(dataProvider="String_UTC")
 320     public void test_of_string_GMT(String id) {
 321         ZoneId test = ZoneId.of("GMT" + id);
 322         assertSame(test, ZoneOffset.UTC);
 323     }
 324 
 325     //-----------------------------------------------------------------------
 326     @DataProvider(name="String_Fixed")
 327     Object[][] data_of_string_Fixed() {
 328         return new Object[][] {
 329             {"Z", "Z"},
 330             {"+0", "Z"},
 331             {"+5", "+05:00"},
 332             {"+01", "+01:00"},
 333             {"+0100", "+01:00"},{"+01:00", "+01:00"},
 334             {"+010000", "+01:00"},{"+01:00:00", "+01:00"},
 335             {"+12", "+12:00"},
 336             {"+1234", "+12:34"},{"+12:34", "+12:34"},
 337             {"+123456", "+12:34:56"},{"+12:34:56", "+12:34:56"},
 338             {"-02", "-02:00"},
 339             {"-5", "-05:00"},
 340             {"-0200", "-02:00"},{"-02:00", "-02:00"},
 341             {"-020000", "-02:00"},{"-02:00:00", "-02:00"},
 342         };
 343     }
 344 
 345     @Test(dataProvider="String_Fixed")
 346     public void test_of_string_offset(String input, String id) {
 347         ZoneId test = ZoneId.of(input);
 348         assertEquals(test.getId(), id);
 349         assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
 350         assertEquals(test.getRules().isFixedOffset(), true);
 351         ZoneOffset offset = ZoneOffset.of(id);
 352         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 353         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 354     }
 355 
 356     @Test(dataProvider="String_Fixed")
 357     public void test_of_string_FixedUTC(String input, String id) {
 358         ZoneId test = ZoneId.of("UTC" + input);
 359         assertEquals(test.getId(), id);
 360         assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
 361         assertEquals(test.getRules().isFixedOffset(), true);
 362         ZoneOffset offset = ZoneOffset.of(id);
 363         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 364         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 365     }
 366 
 367     @Test(dataProvider="String_Fixed")
 368     public void test_of_string_FixedGMT(String input, String id) {
 369         ZoneId test = ZoneId.of("GMT" + input);
 370         assertEquals(test.getId(), id);
 371         assertEquals(test.getText(TextStyle.FULL, Locale.UK), id);
 372         assertEquals(test.getRules().isFixedOffset(), true);
 373         ZoneOffset offset = ZoneOffset.of(id);
 374         assertEquals(test.getRules().getOffset(Instant.ofEpochSecond(0L)), offset);
 375         checkOffset(test.getRules(), createLDT(2008, 6, 30), offset, 1);
 376     }
 377 
 378     //-----------------------------------------------------------------------
 379     @DataProvider(name="String_UTC_Invalid")
 380     Object[][] data_of_string_UTC_invalid() {
 381         return new Object[][] {
 382                 {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"},
 383                 {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"},
 384                 {"+0:00"}, {"+00:0"}, {"+0:0"},
 385                 {"+000"}, {"+00000"},
 386                 {"+0:00:00"}, {"+00:0:00"}, {"+00:00:0"}, {"+0:0:0"}, {"+0:0:00"}, {"+00:0:0"}, {"+0:00:0"},
 387                 {"+01_00"}, {"+01;00"}, {"+01@00"}, {"+01:AA"},
 388                 {"+19"}, {"+19:00"}, {"+18:01"}, {"+18:00:01"}, {"+1801"}, {"+180001"},
 389                 {"-0:00"}, {"-00:0"}, {"-0:0"},
 390                 {"-000"}, {"-00000"},
 391                 {"-0:00:00"}, {"-00:0:00"}, {"-00:00:0"}, {"-0:0:0"}, {"-0:0:00"}, {"-00:0:0"}, {"-0:00:0"},
 392                 {"-19"}, {"-19:00"}, {"-18:01"}, {"-18:00:01"}, {"-1801"}, {"-180001"},
 393                 {"-01_00"}, {"-01;00"}, {"-01@00"}, {"-01:AA"},
 394                 {"@01:00"},
 395         };
 396     }
 397 
 398     @Test(dataProvider="String_UTC_Invalid", expectedExceptions=DateTimeException.class)
 399     public void test_of_string_UTC_invalid(String id) {
 400         ZoneId.of("UTC" + id);
 401     }
 402 
 403     @Test(dataProvider="String_UTC_Invalid", expectedExceptions=DateTimeException.class)
 404     public void test_of_string_GMT_invalid(String id) {
 405         ZoneId.of("GMT" + id);
 406     }
 407 
 408     //-----------------------------------------------------------------------
 409     @DataProvider(name="String_Invalid")
 410     Object[][] data_of_string_invalid() {
 411         // \u00ef is a random unicode character
 412         return new Object[][] {
 413                 {""}, {":"}, {"#"},
 414                 {"\u00ef"}, {"`"}, {"!"}, {"\""}, {"\u00ef"}, {"$"}, {"^"}, {"&"}, {"*"}, {"("}, {")"}, {"="},
 415                 {"\\"}, {"|"}, {","}, {"<"}, {">"}, {"?"}, {";"}, {"'"}, {"["}, {"]"}, {"{"}, {"}"},
 416                 {"\u00ef:A"}, {"`:A"}, {"!:A"}, {"\":A"}, {"\u00ef:A"}, {"$:A"}, {"^:A"}, {"&:A"}, {"*:A"}, {"(:A"}, {"):A"}, {"=:A"}, {"+:A"},
 417                 {"\\:A"}, {"|:A"}, {",:A"}, {"<:A"}, {">:A"}, {"?:A"}, {";:A"}, {"::A"}, {"':A"}, {"@:A"}, {"~:A"}, {"[:A"}, {"]:A"}, {"{:A"}, {"}:A"},
 418                 {"A:B#\u00ef"}, {"A:B#`"}, {"A:B#!"}, {"A:B#\""}, {"A:B#\u00ef"}, {"A:B#$"}, {"A:B#^"}, {"A:B#&"}, {"A:B#*"},
 419                 {"A:B#("}, {"A:B#)"}, {"A:B#="}, {"A:B#+"},
 420                 {"A:B#\\"}, {"A:B#|"}, {"A:B#,"}, {"A:B#<"}, {"A:B#>"}, {"A:B#?"}, {"A:B#;"}, {"A:B#:"},
 421                 {"A:B#'"}, {"A:B#@"}, {"A:B#~"}, {"A:B#["}, {"A:B#]"}, {"A:B#{"}, {"A:B#}"},
 422         };
 423     }
 424 
 425     @Test(dataProvider="String_Invalid", expectedExceptions=DateTimeException.class)
 426     public void test_of_string_invalid(String id) {
 427         ZoneId.of(id);
 428     }
 429 
 430     //-----------------------------------------------------------------------
 431     public void test_of_string_GMT0() {
 432         ZoneId test = ZoneId.of("GMT0");
 433         assertEquals(test.getId(), "Z");
 434         assertEquals(test.getRules().isFixedOffset(), true);
 435     }
 436 
 437     //-----------------------------------------------------------------------
 438     public void test_of_string_London() {
 439         ZoneId test = ZoneId.of("Europe/London");
 440         assertEquals(test.getId(), "Europe/London");
 441         assertEquals(test.getRules().isFixedOffset(), false);
 442     }
 443 
 444     //-----------------------------------------------------------------------
 445     @Test(expectedExceptions=NullPointerException.class)
 446     public void test_of_string_null() {
 447         ZoneId.of((String) null);
 448     }
 449 
 450     @Test(expectedExceptions=ZoneRulesException.class)
 451     public void test_of_string_unknown_simple() {
 452         ZoneId.of("Unknown");
 453     }
 454 
 455     //-------------------------------------------------------------------------
 456     // TODO: test by deserialization
 457 //    public void test_ofUnchecked_string_invalidNotChecked() {
 458 //        ZoneRegion test = ZoneRegion.ofLenient("Unknown");
 459 //        assertEquals(test.getId(), "Unknown");
 460 //    }
 461 //
 462 //    public void test_ofUnchecked_string_invalidNotChecked_unusualCharacters() {
 463 //        ZoneRegion test = ZoneRegion.ofLenient("QWERTYUIOPASDFGHJKLZXCVBNM~/._+-");
 464 //        assertEquals(test.getId(), "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-");
 465 //    }
 466 
 467     //-----------------------------------------------------------------------
 468     // from(TemporalAccessor)
 469     //-----------------------------------------------------------------------
 470     public void test_factory_from_DateTimeAccessor_zoneId() {
 471         TemporalAccessor mock = new TemporalAccessor() {
 472             @Override
 473             public boolean isSupported(TemporalField field) {
 474                 return false;
 475             }
 476 
 477             @Override
 478             public long getLong(TemporalField field) {
 479                 throw new DateTimeException("Mock");
 480             }
 481 
 482             @Override
 483             public <R> R query(TemporalQuery<R> query) {
 484                 if (query == Queries.zoneId()) {
 485                     return (R) ZONE_PARIS;
 486                 }
 487                 return TemporalAccessor.super.query(query);
 488             }
 489         };
 490         assertEquals(ZoneId.from(mock), ZONE_PARIS);
 491     }
 492 
 493     public void test_factory_from_DateTimeAccessor_offset() {
 494         ZoneOffset offset = ZoneOffset.ofHours(1);
 495         assertEquals(ZoneId.from(offset), offset);
 496     }
 497 
 498     @Test(expectedExceptions=DateTimeException.class)
 499     public void test_factory_from_DateTimeAccessor_invalid_noDerive() {
 500         ZoneId.from(LocalTime.of(12, 30));
 501     }
 502 
 503     @Test(expectedExceptions=NullPointerException.class)
 504     public void test_factory_from_DateTimeAccessor_null() {
 505         ZoneId.from((TemporalAccessor) null);
 506     }
 507 
 508     //-----------------------------------------------------------------------
 509     // Europe/London
 510     //-----------------------------------------------------------------------
 511     public void test_London() {
 512         ZoneId test = ZoneId.of("Europe/London");
 513         assertEquals(test.getId(), "Europe/London");
 514         assertEquals(test.getRules().isFixedOffset(), false);
 515     }
 516 
 517     public void test_London_getOffset() {
 518         ZoneId test = ZoneId.of("Europe/London");
 519         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 520         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 521         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 522         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 523         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 524         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 525         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 526         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 527         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 528         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 529         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 530         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 531     }
 532 
 533     public void test_London_getOffset_toDST() {
 534         ZoneId test = ZoneId.of("Europe/London");
 535         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 536         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 537         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 538         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 539         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 540         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 541         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 542         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 543         // cutover at 01:00Z
 544         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 545         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 546     }
 547 
 548     public void test_London_getOffset_fromDST() {
 549         ZoneId test = ZoneId.of("Europe/London");
 550         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 551         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 552         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 553         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 554         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 555         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 556         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 557         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 558         // cutover at 01:00Z
 559         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 560         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(0));
 561     }
 562 
 563     public void test_London_getOffsetInfo() {
 564         ZoneId test = ZoneId.of("Europe/London");
 565         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(0), 1);
 566         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(0), 1);
 567         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(0), 1);
 568         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(1), 1);
 569         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(1), 1);
 570         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(1), 1);
 571         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(1), 1);
 572         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(1), 1);
 573         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(1), 1);
 574         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(1), 1);
 575         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(0), 1);
 576         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(0), 1);
 577     }
 578 
 579     public void test_London_getOffsetInfo_toDST() {
 580         ZoneId test = ZoneId.of("Europe/London");
 581         checkOffset(test.getRules(), createLDT(2008, 3, 24), ZoneOffset.ofHours(0), 1);
 582         checkOffset(test.getRules(), createLDT(2008, 3, 25), ZoneOffset.ofHours(0), 1);
 583         checkOffset(test.getRules(), createLDT(2008, 3, 26), ZoneOffset.ofHours(0), 1);
 584         checkOffset(test.getRules(), createLDT(2008, 3, 27), ZoneOffset.ofHours(0), 1);
 585         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(0), 1);
 586         checkOffset(test.getRules(), createLDT(2008, 3, 29), ZoneOffset.ofHours(0), 1);
 587         checkOffset(test.getRules(), createLDT(2008, 3, 30), ZoneOffset.ofHours(0), 1);
 588         checkOffset(test.getRules(), createLDT(2008, 3, 31), ZoneOffset.ofHours(1), 1);
 589         // cutover at 01:00Z
 590         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 0, 59, 59, 999999999), ZoneOffset.ofHours(0), 1);
 591         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 1, 30, 0, 0), ZoneOffset.ofHours(0), GAP);
 592         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0), ZoneOffset.ofHours(1), 1);
 593     }
 594 
 595     public void test_London_getOffsetInfo_fromDST() {
 596         ZoneId test = ZoneId.of("Europe/London");
 597         checkOffset(test.getRules(), createLDT(2008, 10, 24), ZoneOffset.ofHours(1), 1);
 598         checkOffset(test.getRules(), createLDT(2008, 10, 25), ZoneOffset.ofHours(1), 1);
 599         checkOffset(test.getRules(), createLDT(2008, 10, 26), ZoneOffset.ofHours(1), 1);
 600         checkOffset(test.getRules(), createLDT(2008, 10, 27), ZoneOffset.ofHours(0), 1);
 601         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(0), 1);
 602         checkOffset(test.getRules(), createLDT(2008, 10, 29), ZoneOffset.ofHours(0), 1);
 603         checkOffset(test.getRules(), createLDT(2008, 10, 30), ZoneOffset.ofHours(0), 1);
 604         checkOffset(test.getRules(), createLDT(2008, 10, 31), ZoneOffset.ofHours(0), 1);
 605         // cutover at 01:00Z
 606         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 0, 59, 59, 999999999), ZoneOffset.ofHours(1), 1);
 607         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 1, 30, 0, 0), ZoneOffset.ofHours(1), OVERLAP);
 608         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0), ZoneOffset.ofHours(0), 1);
 609     }
 610 
 611     public void test_London_getOffsetInfo_gap() {
 612         ZoneId test = ZoneId.of("Europe/London");
 613         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0);
 614         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(0), GAP);
 615         assertEquals(trans.isGap(), true);
 616         assertEquals(trans.isOverlap(), false);
 617         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(0));
 618         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1));
 619         assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC));
 620         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0));
 621         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0));
 622         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 623         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 624         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false);
 625         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 626         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]");
 627 
 628         assertFalse(trans.equals(null));
 629         assertFalse(trans.equals(ZoneOffset.ofHours(0)));
 630         assertTrue(trans.equals(trans));
 631 
 632         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 633         assertTrue(trans.equals(otherTrans));
 634         assertEquals(trans.hashCode(), otherTrans.hashCode());
 635     }
 636 
 637     public void test_London_getOffsetInfo_overlap() {
 638         ZoneId test = ZoneId.of("Europe/London");
 639         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0);
 640         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), OVERLAP);
 641         assertEquals(trans.isGap(), false);
 642         assertEquals(trans.isOverlap(), true);
 643         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1));
 644         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(0));
 645         assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC));
 646         assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0));
 647         assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0));
 648         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 649         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), true);
 650         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true);
 651         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 652         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]");
 653 
 654         assertFalse(trans.equals(null));
 655         assertFalse(trans.equals(ZoneOffset.ofHours(1)));
 656         assertTrue(trans.equals(trans));
 657 
 658         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 659         assertTrue(trans.equals(otherTrans));
 660         assertEquals(trans.hashCode(), otherTrans.hashCode());
 661     }
 662 
 663     //-----------------------------------------------------------------------
 664     // Europe/Paris
 665     //-----------------------------------------------------------------------
 666     public void test_Paris() {
 667         ZoneId test = ZoneId.of("Europe/Paris");
 668         assertEquals(test.getId(), "Europe/Paris");
 669         assertEquals(test.getRules().isFixedOffset(), false);
 670     }
 671 
 672     public void test_Paris_getOffset() {
 673         ZoneId test = ZoneId.of("Europe/Paris");
 674         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 675         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 676         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 677         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 678         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 679         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 680         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 681         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 682         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 683         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 684         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 685         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 686     }
 687 
 688     public void test_Paris_getOffset_toDST() {
 689         ZoneId test = ZoneId.of("Europe/Paris");
 690         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 691         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 692         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 693         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 694         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 695         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 696         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 697         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 698         // cutover at 01:00Z
 699         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 700         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 701     }
 702 
 703     public void test_Paris_getOffset_fromDST() {
 704         ZoneId test = ZoneId.of("Europe/Paris");
 705         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 706         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 25, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 707         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 708         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 27, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 709         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 710         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 29, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 711         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 30, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 712         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 31, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 713         // cutover at 01:00Z
 714         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 0, 59, 59, 999999999, ZoneOffset.UTC)), ZoneOffset.ofHours(2));
 715         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), ZoneOffset.ofHours(1));
 716     }
 717 
 718     public void test_Paris_getOffsetInfo() {
 719         ZoneId test = ZoneId.of("Europe/Paris");
 720         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(1), 1);
 721         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(1), 1);
 722         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(1), 1);
 723         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(2), 1);
 724         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(2), 1);
 725         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(2), 1);
 726         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(2), 1);
 727         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(2), 1);
 728         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(2), 1);
 729         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(2), 1);
 730         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(1), 1);
 731         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(1), 1);
 732     }
 733 
 734     public void test_Paris_getOffsetInfo_toDST() {
 735         ZoneId test = ZoneId.of("Europe/Paris");
 736         checkOffset(test.getRules(), createLDT(2008, 3, 24), ZoneOffset.ofHours(1), 1);
 737         checkOffset(test.getRules(), createLDT(2008, 3, 25), ZoneOffset.ofHours(1), 1);
 738         checkOffset(test.getRules(), createLDT(2008, 3, 26), ZoneOffset.ofHours(1), 1);
 739         checkOffset(test.getRules(), createLDT(2008, 3, 27), ZoneOffset.ofHours(1), 1);
 740         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(1), 1);
 741         checkOffset(test.getRules(), createLDT(2008, 3, 29), ZoneOffset.ofHours(1), 1);
 742         checkOffset(test.getRules(), createLDT(2008, 3, 30), ZoneOffset.ofHours(1), 1);
 743         checkOffset(test.getRules(), createLDT(2008, 3, 31), ZoneOffset.ofHours(2), 1);
 744         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 745         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 1, 59, 59, 999999999), ZoneOffset.ofHours(1), 1);
 746         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 2, 30, 0, 0), ZoneOffset.ofHours(1), GAP);
 747         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), ZoneOffset.ofHours(2), 1);
 748     }
 749 
 750     public void test_Paris_getOffsetInfo_fromDST() {
 751         ZoneId test = ZoneId.of("Europe/Paris");
 752         checkOffset(test.getRules(), createLDT(2008, 10, 24), ZoneOffset.ofHours(2), 1);
 753         checkOffset(test.getRules(), createLDT(2008, 10, 25), ZoneOffset.ofHours(2), 1);
 754         checkOffset(test.getRules(), createLDT(2008, 10, 26), ZoneOffset.ofHours(2), 1);
 755         checkOffset(test.getRules(), createLDT(2008, 10, 27), ZoneOffset.ofHours(1), 1);
 756         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(1), 1);
 757         checkOffset(test.getRules(), createLDT(2008, 10, 29), ZoneOffset.ofHours(1), 1);
 758         checkOffset(test.getRules(), createLDT(2008, 10, 30), ZoneOffset.ofHours(1), 1);
 759         checkOffset(test.getRules(), createLDT(2008, 10, 31), ZoneOffset.ofHours(1), 1);
 760         // cutover at 01:00Z which is 02:00+01:00(local Paris time)
 761         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 1, 59, 59, 999999999), ZoneOffset.ofHours(2), 1);
 762         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 2, 30, 0, 0), ZoneOffset.ofHours(2), OVERLAP);
 763         checkOffset(test.getRules(), LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), ZoneOffset.ofHours(1), 1);
 764     }
 765 
 766     public void test_Paris_getOffsetInfo_gap() {
 767         ZoneId test = ZoneId.of("Europe/Paris");
 768         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0);
 769         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), GAP);
 770         assertEquals(trans.isGap(), true);
 771         assertEquals(trans.isOverlap(), false);
 772         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1));
 773         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(2));
 774         assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC));
 775         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 776         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false);
 777         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 778         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false);
 779         assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]");
 780 
 781         assertFalse(trans.equals(null));
 782         assertFalse(trans.equals(ZoneOffset.ofHours(1)));
 783         assertTrue(trans.equals(trans));
 784 
 785         final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime);
 786         assertTrue(trans.equals(otherDis));
 787         assertEquals(trans.hashCode(), otherDis.hashCode());
 788     }
 789 
 790     public void test_Paris_getOffsetInfo_overlap() {
 791         ZoneId test = ZoneId.of("Europe/Paris");
 792         final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0);
 793         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(2), OVERLAP);
 794         assertEquals(trans.isGap(), false);
 795         assertEquals(trans.isOverlap(), true);
 796         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(2));
 797         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1));
 798         assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC));
 799         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false);
 800         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true);
 801         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), true);
 802         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false);
 803         assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]");
 804 
 805         assertFalse(trans.equals(null));
 806         assertFalse(trans.equals(ZoneOffset.ofHours(2)));
 807         assertTrue(trans.equals(trans));
 808 
 809         final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime);
 810         assertTrue(trans.equals(otherDis));
 811         assertEquals(trans.hashCode(), otherDis.hashCode());
 812     }
 813 
 814     //-----------------------------------------------------------------------
 815     // America/New_York
 816     //-----------------------------------------------------------------------
 817     public void test_NewYork() {
 818         ZoneId test = ZoneId.of("America/New_York");
 819         assertEquals(test.getId(), "America/New_York");
 820         assertEquals(test.getRules().isFixedOffset(), false);
 821     }
 822 
 823     public void test_NewYork_getOffset() {
 824         ZoneId test = ZoneId.of("America/New_York");
 825         ZoneOffset offset = ZoneOffset.ofHours(-5);
 826         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 1, offset)), ZoneOffset.ofHours(-5));
 827         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 1, offset)), ZoneOffset.ofHours(-5));
 828         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 1, offset)), ZoneOffset.ofHours(-5));
 829         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 1, offset)), ZoneOffset.ofHours(-4));
 830         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 1, offset)), ZoneOffset.ofHours(-4));
 831         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 1, offset)), ZoneOffset.ofHours(-4));
 832         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 1, offset)), ZoneOffset.ofHours(-4));
 833         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 1, offset)), ZoneOffset.ofHours(-4));
 834         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 1, offset)), ZoneOffset.ofHours(-4));
 835         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 1, offset)), ZoneOffset.ofHours(-4));
 836         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 837         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 1, offset)), ZoneOffset.ofHours(-5));
 838         assertEquals(test.getRules().getOffset(createInstant(2008, 1, 28, offset)), ZoneOffset.ofHours(-5));
 839         assertEquals(test.getRules().getOffset(createInstant(2008, 2, 28, offset)), ZoneOffset.ofHours(-5));
 840         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 28, offset)), ZoneOffset.ofHours(-4));
 841         assertEquals(test.getRules().getOffset(createInstant(2008, 4, 28, offset)), ZoneOffset.ofHours(-4));
 842         assertEquals(test.getRules().getOffset(createInstant(2008, 5, 28, offset)), ZoneOffset.ofHours(-4));
 843         assertEquals(test.getRules().getOffset(createInstant(2008, 6, 28, offset)), ZoneOffset.ofHours(-4));
 844         assertEquals(test.getRules().getOffset(createInstant(2008, 7, 28, offset)), ZoneOffset.ofHours(-4));
 845         assertEquals(test.getRules().getOffset(createInstant(2008, 8, 28, offset)), ZoneOffset.ofHours(-4));
 846         assertEquals(test.getRules().getOffset(createInstant(2008, 9, 28, offset)), ZoneOffset.ofHours(-4));
 847         assertEquals(test.getRules().getOffset(createInstant(2008, 10, 28, offset)), ZoneOffset.ofHours(-4));
 848         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 28, offset)), ZoneOffset.ofHours(-5));
 849         assertEquals(test.getRules().getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5));
 850     }
 851 
 852     public void test_NewYork_getOffset_toDST() {
 853         ZoneId test = ZoneId.of("America/New_York");
 854         ZoneOffset offset = ZoneOffset.ofHours(-5);
 855         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 8, offset)), ZoneOffset.ofHours(-5));
 856         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, offset)), ZoneOffset.ofHours(-5));
 857         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 10, offset)), ZoneOffset.ofHours(-4));
 858         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 11, offset)), ZoneOffset.ofHours(-4));
 859         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 12, offset)), ZoneOffset.ofHours(-4));
 860         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 13, offset)), ZoneOffset.ofHours(-4));
 861         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 14, offset)), ZoneOffset.ofHours(-4));
 862         // cutover at 02:00 local
 863         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-5));
 864         assertEquals(test.getRules().getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4));
 865     }
 866 
 867     public void test_NewYork_getOffset_fromDST() {
 868         ZoneId test = ZoneId.of("America/New_York");
 869         ZoneOffset offset = ZoneOffset.ofHours(-4);
 870         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 1, offset)), ZoneOffset.ofHours(-4));
 871         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, offset)), ZoneOffset.ofHours(-4));
 872         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 3, offset)), ZoneOffset.ofHours(-5));
 873         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 4, offset)), ZoneOffset.ofHours(-5));
 874         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 5, offset)), ZoneOffset.ofHours(-5));
 875         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 6, offset)), ZoneOffset.ofHours(-5));
 876         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 7, offset)), ZoneOffset.ofHours(-5));
 877         // cutover at 02:00 local
 878         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 1, 59, 59, 999999999, offset)), ZoneOffset.ofHours(-4));
 879         assertEquals(test.getRules().getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5));
 880     }
 881 
 882     public void test_NewYork_getOffsetInfo() {
 883         ZoneId test = ZoneId.of("America/New_York");
 884         checkOffset(test.getRules(), createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1);
 885         checkOffset(test.getRules(), createLDT(2008, 2, 1), ZoneOffset.ofHours(-5), 1);
 886         checkOffset(test.getRules(), createLDT(2008, 3, 1), ZoneOffset.ofHours(-5), 1);
 887         checkOffset(test.getRules(), createLDT(2008, 4, 1), ZoneOffset.ofHours(-4), 1);
 888         checkOffset(test.getRules(), createLDT(2008, 5, 1), ZoneOffset.ofHours(-4), 1);
 889         checkOffset(test.getRules(), createLDT(2008, 6, 1), ZoneOffset.ofHours(-4), 1);
 890         checkOffset(test.getRules(), createLDT(2008, 7, 1), ZoneOffset.ofHours(-4), 1);
 891         checkOffset(test.getRules(), createLDT(2008, 8, 1), ZoneOffset.ofHours(-4), 1);
 892         checkOffset(test.getRules(), createLDT(2008, 9, 1), ZoneOffset.ofHours(-4), 1);
 893         checkOffset(test.getRules(), createLDT(2008, 10, 1), ZoneOffset.ofHours(-4), 1);
 894         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 895         checkOffset(test.getRules(), createLDT(2008, 12, 1), ZoneOffset.ofHours(-5), 1);
 896         checkOffset(test.getRules(), createLDT(2008, 1, 28), ZoneOffset.ofHours(-5), 1);
 897         checkOffset(test.getRules(), createLDT(2008, 2, 28), ZoneOffset.ofHours(-5), 1);
 898         checkOffset(test.getRules(), createLDT(2008, 3, 28), ZoneOffset.ofHours(-4), 1);
 899         checkOffset(test.getRules(), createLDT(2008, 4, 28), ZoneOffset.ofHours(-4), 1);
 900         checkOffset(test.getRules(), createLDT(2008, 5, 28), ZoneOffset.ofHours(-4), 1);
 901         checkOffset(test.getRules(), createLDT(2008, 6, 28), ZoneOffset.ofHours(-4), 1);
 902         checkOffset(test.getRules(), createLDT(2008, 7, 28), ZoneOffset.ofHours(-4), 1);
 903         checkOffset(test.getRules(), createLDT(2008, 8, 28), ZoneOffset.ofHours(-4), 1);
 904         checkOffset(test.getRules(), createLDT(2008, 9, 28), ZoneOffset.ofHours(-4), 1);
 905         checkOffset(test.getRules(), createLDT(2008, 10, 28), ZoneOffset.ofHours(-4), 1);
 906         checkOffset(test.getRules(), createLDT(2008, 11, 28), ZoneOffset.ofHours(-5), 1);
 907         checkOffset(test.getRules(), createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1);
 908     }
 909 
 910     public void test_NewYork_getOffsetInfo_toDST() {
 911         ZoneId test = ZoneId.of("America/New_York");
 912         checkOffset(test.getRules(), createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1);
 913         checkOffset(test.getRules(), createLDT(2008, 3, 9), ZoneOffset.ofHours(-5), 1);
 914         checkOffset(test.getRules(), createLDT(2008, 3, 10), ZoneOffset.ofHours(-4), 1);
 915         checkOffset(test.getRules(), createLDT(2008, 3, 11), ZoneOffset.ofHours(-4), 1);
 916         checkOffset(test.getRules(), createLDT(2008, 3, 12), ZoneOffset.ofHours(-4), 1);
 917         checkOffset(test.getRules(), createLDT(2008, 3, 13), ZoneOffset.ofHours(-4), 1);
 918         checkOffset(test.getRules(), createLDT(2008, 3, 14), ZoneOffset.ofHours(-4), 1);
 919         // cutover at 02:00 local
 920         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 1, 59, 59, 999999999), ZoneOffset.ofHours(-5), 1);
 921         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 2, 30, 0, 0), ZoneOffset.ofHours(-5), GAP);
 922         checkOffset(test.getRules(), LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1);
 923     }
 924 
 925     public void test_NewYork_getOffsetInfo_fromDST() {
 926         ZoneId test = ZoneId.of("America/New_York");
 927         checkOffset(test.getRules(), createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
 928         checkOffset(test.getRules(), createLDT(2008, 11, 2), ZoneOffset.ofHours(-4), 1);
 929         checkOffset(test.getRules(), createLDT(2008, 11, 3), ZoneOffset.ofHours(-5), 1);
 930         checkOffset(test.getRules(), createLDT(2008, 11, 4), ZoneOffset.ofHours(-5), 1);
 931         checkOffset(test.getRules(), createLDT(2008, 11, 5), ZoneOffset.ofHours(-5), 1);
 932         checkOffset(test.getRules(), createLDT(2008, 11, 6), ZoneOffset.ofHours(-5), 1);
 933         checkOffset(test.getRules(), createLDT(2008, 11, 7), ZoneOffset.ofHours(-5), 1);
 934         // cutover at 02:00 local
 935         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 0, 59, 59, 999999999), ZoneOffset.ofHours(-4), 1);
 936         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 1, 30, 0, 0), ZoneOffset.ofHours(-4), OVERLAP);
 937         checkOffset(test.getRules(), LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1);
 938     }
 939 
 940     public void test_NewYork_getOffsetInfo_gap() {
 941         ZoneId test = ZoneId.of("America/New_York");
 942         final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0);
 943         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-5), GAP);
 944         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5));
 945         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4));
 946         assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, 0, 0, ZoneOffset.ofHours(-5)));
 947         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-6)), false);
 948         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false);
 949         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false);
 950         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-3)), false);
 951         assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]");
 952 
 953         assertFalse(trans.equals(null));
 954         assertFalse(trans.equals(ZoneOffset.ofHours(-5)));
 955         assertTrue(trans.equals(trans));
 956 
 957         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 958         assertTrue(trans.equals(otherTrans));
 959 
 960         assertEquals(trans.hashCode(), otherTrans.hashCode());
 961     }
 962 
 963     public void test_NewYork_getOffsetInfo_overlap() {
 964         ZoneId test = ZoneId.of("America/New_York");
 965         final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0);
 966         ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-4), OVERLAP);
 967         assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4));
 968         assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5));
 969         assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, 0, 0, ZoneOffset.ofHours(-4)));
 970         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false);
 971         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true);
 972         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true);
 973         assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false);
 974         assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]");
 975 
 976         assertFalse(trans.equals(null));
 977         assertFalse(trans.equals(ZoneOffset.ofHours(-4)));
 978         assertTrue(trans.equals(trans));
 979 
 980         final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime);
 981         assertTrue(trans.equals(otherTrans));
 982 
 983         assertEquals(trans.hashCode(), otherTrans.hashCode());
 984     }
 985 
 986     //-----------------------------------------------------------------------
 987     // getXxx() isXxx()
 988     //-----------------------------------------------------------------------
 989     public void test_get_Tzdb() {
 990         ZoneId test = ZoneId.of("Europe/London");
 991         assertEquals(test.getId(), "Europe/London");
 992         assertEquals(test.getRules().isFixedOffset(), false);
 993     }
 994 
 995     public void test_get_TzdbFixed() {
 996         ZoneId test = ZoneId.of("+01:30");
 997         assertEquals(test.getId(), "+01:30");
 998         assertEquals(test.getRules().isFixedOffset(), true);
 999     }
1000 
1001     //-----------------------------------------------------------------------
1002     // equals() / hashCode()
1003     //-----------------------------------------------------------------------
1004     public void test_equals() {
1005         ZoneId test1 = ZoneId.of("Europe/London");
1006         ZoneId test2 = ZoneId.of("Europe/Paris");
1007         ZoneId test2b = ZoneId.of("Europe/Paris");
1008         assertEquals(test1.equals(test2), false);
1009         assertEquals(test2.equals(test1), false);
1010 
1011         assertEquals(test1.equals(test1), true);
1012         assertEquals(test2.equals(test2), true);
1013         assertEquals(test2.equals(test2b), true);
1014 
1015         assertEquals(test1.hashCode() == test1.hashCode(), true);
1016         assertEquals(test2.hashCode() == test2.hashCode(), true);
1017         assertEquals(test2.hashCode() == test2b.hashCode(), true);
1018     }
1019 
1020     public void test_equals_null() {
1021         assertEquals(ZoneId.of("Europe/London").equals(null), false);
1022     }
1023 
1024     public void test_equals_notTimeZone() {
1025         assertEquals(ZoneId.of("Europe/London").equals("Europe/London"), false);
1026     }
1027 
1028     //-----------------------------------------------------------------------
1029     // toString()
1030     //-----------------------------------------------------------------------
1031     @DataProvider(name="ToString")
1032     Object[][] data_toString() {
1033         return new Object[][] {
1034             {"Europe/London", "Europe/London"},
1035             {"Europe/Paris", "Europe/Paris"},
1036             {"Europe/Berlin", "Europe/Berlin"},
1037             {"UTC", "Z"},
1038             {"UTC+01:00", "+01:00"},
1039         };
1040     }
1041 
1042     @Test(dataProvider="ToString")
1043     public void test_toString(String id, String expected) {
1044         ZoneId test = ZoneId.of(id);
1045         assertEquals(test.toString(), expected);
1046     }
1047 
1048     //-----------------------------------------------------------------------
1049     //-----------------------------------------------------------------------
1050     //-----------------------------------------------------------------------
1051     private Instant createInstant(int year, int month, int day, ZoneOffset offset) {
1052         return LocalDateTime.of(year, month, day, 0, 0).toInstant(offset);
1053     }
1054 
1055     private Instant createInstant(int year, int month, int day, int hour, int min, int sec, int nano, ZoneOffset offset) {
1056         return LocalDateTime.of(year, month, day, hour, min, sec, nano).toInstant(offset);
1057     }
1058 
1059     private ZonedDateTime createZDT(int year, int month, int day, int hour, int min, int sec, int nano, ZoneId zone) {
1060         return LocalDateTime.of(year, month, day, hour, min, sec, nano).atZone(zone);
1061     }
1062 
1063     private LocalDateTime createLDT(int year, int month, int day) {
1064         return LocalDateTime.of(year, month, day, 0, 0);
1065     }
1066 
1067     private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) {
1068         List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime);
1069         assertEquals(validOffsets.size(), type);
1070         assertEquals(rules.getOffset(dateTime), offset);
1071         if (type == 1) {
1072             assertEquals(validOffsets.get(0), offset);
1073             return null;
1074         } else {
1075             ZoneOffsetTransition zot = rules.getTransition(dateTime);
1076             assertNotNull(zot);
1077             assertEquals(zot.isOverlap(), type == 2);
1078             assertEquals(zot.isGap(), type == 0);
1079             assertEquals(zot.isValidOffset(offset), type == 2);
1080             return zot;
1081         }
1082     }
1083 
1084 }