1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * This file is available under and governed by the GNU General Public
  26  * License version 2 only, as published by the Free Software Foundation.
  27  * However, the following notice accompanied the original version of this
  28  * file:
  29  *
  30  * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
  31  *
  32  * All rights reserved.
  33  *
  34  * Redistribution and use in source and binary forms, with or without
  35  * modification, are permitted provided that the following conditions are met:
  36  *
  37  *  * Redistributions of source code must retain the above copyright notice,
  38  *    this list of conditions and the following disclaimer.
  39  *
  40  *  * Redistributions in binary form must reproduce the above copyright notice,
  41  *    this list of conditions and the following disclaimer in the documentation
  42  *    and/or other materials provided with the distribution.
  43  *
  44  *  * Neither the name of JSR-310 nor the names of its contributors
  45  *    may be used to endorse or promote products derived from this software
  46  *    without specific prior written permission.
  47  *
  48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59  */
  60 package tck.java.time;
  61 
  62 import static java.time.Month.JANUARY;
  63 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
  64 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
  65 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
  66 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
  67 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
  68 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
  69 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
  70 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
  71 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
  72 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
  73 import static java.time.temporal.ChronoField.EPOCH_DAY;
  74 import static java.time.temporal.ChronoField.ERA;
  75 import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
  76 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
  77 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
  78 import static java.time.temporal.ChronoField.MICRO_OF_DAY;
  79 import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
  80 import static java.time.temporal.ChronoField.MILLI_OF_DAY;
  81 import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
  82 import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
  83 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
  84 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
  85 import static java.time.temporal.ChronoField.NANO_OF_DAY;
  86 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
  87 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  88 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
  89 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
  90 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  91 import static java.time.temporal.ChronoField.YEAR;
  92 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
  93 import static java.time.temporal.ChronoUnit.DAYS;
  94 import static java.time.temporal.ChronoUnit.HOURS;
  95 import static java.time.temporal.ChronoUnit.MINUTES;
  96 import static java.time.temporal.ChronoUnit.NANOS;
  97 import static java.time.temporal.ChronoUnit.SECONDS;
  98 import static org.testng.Assert.assertEquals;
  99 import static org.testng.Assert.assertTrue;
 100 
 101 import java.io.ByteArrayOutputStream;
 102 import java.io.DataOutputStream;
 103 import java.io.IOException;
 104 import java.time.Clock;
 105 import java.time.DateTimeException;
 106 import java.time.Duration;
 107 import java.time.Instant;
 108 import java.time.LocalDate;
 109 import java.time.LocalDateTime;
 110 import java.time.LocalTime;
 111 import java.time.Month;
 112 import java.time.OffsetDateTime;
 113 import java.time.OffsetTime;
 114 import java.time.Period;
 115 import java.time.Year;
 116 import java.time.ZoneId;
 117 import java.time.ZoneOffset;
 118 import java.time.ZonedDateTime;
 119 import java.time.chrono.IsoChronology;
 120 import java.time.format.DateTimeFormatter;
 121 import java.time.format.DateTimeParseException;
 122 import java.time.temporal.ChronoField;
 123 import java.time.temporal.ChronoUnit;
 124 import java.time.temporal.JulianFields;
 125 import java.time.temporal.TemporalAccessor;
 126 import java.time.temporal.TemporalAdjuster;
 127 import java.time.temporal.TemporalAmount;
 128 import java.time.temporal.TemporalField;
 129 import java.time.temporal.TemporalQuery;
 130 import java.util.ArrayList;
 131 import java.util.Arrays;
 132 import java.util.List;
 133 
 134 import org.testng.annotations.BeforeMethod;
 135 import org.testng.annotations.DataProvider;
 136 import org.testng.annotations.Test;
 137 
 138 /**
 139  * Test ZonedDateTime.
 140  */
 141 @Test
 142 public class TCKZonedDateTime extends AbstractDateTimeTest {
 143 
 144     private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1);
 145     private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2);
 146     private static final ZoneOffset OFFSET_0130 = ZoneOffset.of("+01:30");
 147     private static final ZoneOffset OFFSET_MAX = ZoneOffset.MAX;
 148     private static final ZoneOffset OFFSET_MIN = ZoneOffset.MIN;
 149 
 150     private static final ZoneId ZONE_0100 = OFFSET_0100;
 151     private static final ZoneId ZONE_0200 = OFFSET_0200;
 152     private static final ZoneId ZONE_M0100 = ZoneOffset.ofHours(-1);
 153     private static final ZoneId ZONE_LONDON = ZoneId.of("Europe/London");
 154     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 155     private LocalDateTime TEST_PARIS_GAP_2008_03_30_02_30;
 156     private LocalDateTime TEST_PARIS_OVERLAP_2008_10_26_02_30;
 157     private LocalDateTime TEST_LOCAL_2008_06_30_11_30_59_500;
 158     private ZonedDateTime TEST_DATE_TIME;
 159     private ZonedDateTime TEST_DATE_TIME_PARIS;
 160 
 161     @BeforeMethod
 162     public void setUp() {
 163         TEST_LOCAL_2008_06_30_11_30_59_500 = LocalDateTime.of(2008, 6, 30, 11, 30, 59, 500);
 164         TEST_DATE_TIME = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
 165         TEST_DATE_TIME_PARIS = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
 166         TEST_PARIS_OVERLAP_2008_10_26_02_30 = LocalDateTime.of(2008, 10, 26, 2, 30);
 167         TEST_PARIS_GAP_2008_03_30_02_30 = LocalDateTime.of(2008, 3, 30, 2, 30);
 168     }
 169 
 170     //-----------------------------------------------------------------------
 171     @Override
 172     protected List<TemporalAccessor> samples() {
 173         TemporalAccessor[] array = {TEST_DATE_TIME, };
 174         return Arrays.asList(array);
 175     }
 176 
 177     @Override
 178     protected List<TemporalField> validFields() {
 179         TemporalField[] array = {
 180             NANO_OF_SECOND,
 181             NANO_OF_DAY,
 182             MICRO_OF_SECOND,
 183             MICRO_OF_DAY,
 184             MILLI_OF_SECOND,
 185             MILLI_OF_DAY,
 186             SECOND_OF_MINUTE,
 187             SECOND_OF_DAY,
 188             MINUTE_OF_HOUR,
 189             MINUTE_OF_DAY,
 190             CLOCK_HOUR_OF_AMPM,
 191             HOUR_OF_AMPM,
 192             CLOCK_HOUR_OF_DAY,
 193             HOUR_OF_DAY,
 194             AMPM_OF_DAY,
 195             DAY_OF_WEEK,
 196             ALIGNED_DAY_OF_WEEK_IN_MONTH,
 197             ALIGNED_DAY_OF_WEEK_IN_YEAR,
 198             DAY_OF_MONTH,
 199             DAY_OF_YEAR,
 200             EPOCH_DAY,
 201             ALIGNED_WEEK_OF_MONTH,
 202             ALIGNED_WEEK_OF_YEAR,
 203             MONTH_OF_YEAR,
 204             PROLEPTIC_MONTH,
 205             YEAR_OF_ERA,
 206             YEAR,
 207             ERA,
 208             OFFSET_SECONDS,
 209             INSTANT_SECONDS,
 210             JulianFields.JULIAN_DAY,
 211             JulianFields.MODIFIED_JULIAN_DAY,
 212             JulianFields.RATA_DIE,
 213         };
 214         return Arrays.asList(array);
 215     }
 216 
 217     @Override
 218     protected List<TemporalField> invalidFields() {
 219         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
 220         list.removeAll(validFields());
 221         return list;
 222     }
 223 
 224     //-----------------------------------------------------------------------
 225     @Test
 226     public void test_serialization() throws ClassNotFoundException, IOException {
 227         assertSerializable(TEST_DATE_TIME);
 228     }
 229 
 230     @Test
 231     public void test_serialization_format_zoneId() throws Exception {
 232         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 233         try (DataOutputStream dos = new DataOutputStream(baos) ) {
 234             dos.writeByte(6);
 235             dos.writeInt(2012); // date
 236             dos.writeByte(9);
 237             dos.writeByte(16);
 238             dos.writeByte(22);  // time
 239             dos.writeByte(17);
 240             dos.writeByte(59);
 241             dos.writeInt(470_000_000);
 242             dos.writeByte(4);  // offset
 243             dos.writeByte(7);  // zoneId
 244             dos.writeUTF("Europe/London");
 245         }
 246         byte[] bytes = baos.toByteArray();
 247         ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London"));
 248         assertSerializedBySer(zdt, bytes);
 249     }
 250 
 251     @Test
 252     public void test_serialization_format_zoneOffset() throws Exception {
 253         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 254         try (DataOutputStream dos = new DataOutputStream(baos) ) {
 255             dos.writeByte(6);
 256             dos.writeInt(2012); // date
 257             dos.writeByte(9);
 258             dos.writeByte(16);
 259             dos.writeByte(22);  // time
 260             dos.writeByte(17);
 261             dos.writeByte(59);
 262             dos.writeInt(470_000_000);
 263             dos.writeByte(4);  // offset
 264             dos.writeByte(8);  // zoneId
 265             dos.writeByte(4);
 266         }
 267         byte[] bytes = baos.toByteArray();
 268         ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1));
 269         assertSerializedBySer(zdt, bytes);
 270     }
 271 
 272     //-----------------------------------------------------------------------
 273     // now()
 274     //-----------------------------------------------------------------------
 275     @Test
 276     public void now() {
 277         ZonedDateTime expected = ZonedDateTime.now(Clock.systemDefaultZone());
 278         ZonedDateTime test = ZonedDateTime.now();
 279         long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
 280         if (diff >= 100000000) {
 281             // may be date change
 282             expected = ZonedDateTime.now(Clock.systemDefaultZone());
 283             test = ZonedDateTime.now();
 284             diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
 285         }
 286         assertTrue(diff < 100000000);  // less than 0.1 secs
 287     }
 288 
 289     //-----------------------------------------------------------------------
 290     // now(ZoneId)
 291     //-----------------------------------------------------------------------
 292     @Test(expectedExceptions=NullPointerException.class)
 293     public void now_ZoneId_nullZoneId() {
 294         ZonedDateTime.now((ZoneId) null);
 295     }
 296 
 297     @Test
 298     public void now_ZoneId() {
 299         ZoneId zone = ZoneId.of("UTC+01:02:03");
 300         ZonedDateTime expected = ZonedDateTime.now(Clock.system(zone));
 301         ZonedDateTime test = ZonedDateTime.now(zone);
 302         for (int i = 0; i < 100; i++) {
 303             if (expected.equals(test)) {
 304                 return;
 305             }
 306             expected = ZonedDateTime.now(Clock.system(zone));
 307             test = ZonedDateTime.now(zone);
 308         }
 309         assertEquals(test, expected);
 310     }
 311 
 312     //-----------------------------------------------------------------------
 313     // now(Clock)
 314     //-----------------------------------------------------------------------
 315     @Test(expectedExceptions=NullPointerException.class)
 316     public void now_Clock_nullClock() {
 317         ZonedDateTime.now((Clock) null);
 318     }
 319 
 320     @Test
 321     public void now_Clock_allSecsInDay_utc() {
 322         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 323             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 324             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 325             ZonedDateTime test = ZonedDateTime.now(clock);
 326             assertEquals(test.getYear(), 1970);
 327             assertEquals(test.getMonth(), Month.JANUARY);
 328             assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60 ? 1 : 2));
 329             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
 330             assertEquals(test.getMinute(), (i / 60) % 60);
 331             assertEquals(test.getSecond(), i % 60);
 332             assertEquals(test.getNano(), 123456789);
 333             assertEquals(test.getOffset(), ZoneOffset.UTC);
 334             assertEquals(test.getZone(), ZoneOffset.UTC);
 335         }
 336     }
 337 
 338     @Test
 339     public void now_Clock_allSecsInDay_zone() {
 340         ZoneId zone = ZoneId.of("Europe/London");
 341         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 342             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 343             ZonedDateTime expected = ZonedDateTime.ofInstant(instant, zone);
 344             Clock clock = Clock.fixed(expected.toInstant(), zone);
 345             ZonedDateTime test = ZonedDateTime.now(clock);
 346             assertEquals(test, expected);
 347         }
 348     }
 349 
 350     @Test
 351     public void now_Clock_allSecsInDay_beforeEpoch() {
 352         LocalTime expected = LocalTime.MIDNIGHT.plusNanos(123456789L);
 353         for (int i =-1; i >= -(24 * 60 * 60); i--) {
 354             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
 355             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 356             ZonedDateTime test = ZonedDateTime.now(clock);
 357             assertEquals(test.getYear(), 1969);
 358             assertEquals(test.getMonth(), Month.DECEMBER);
 359             assertEquals(test.getDayOfMonth(), 31);
 360             expected = expected.minusSeconds(1);
 361             assertEquals(test.toLocalTime(), expected);
 362             assertEquals(test.getOffset(), ZoneOffset.UTC);
 363             assertEquals(test.getZone(), ZoneOffset.UTC);
 364         }
 365     }
 366 
 367     @Test
 368     public void now_Clock_offsets() {
 369         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(1970, 1, 1, 12, 0), ZoneOffset.UTC);
 370         for (int i = -9; i < 15; i++) {
 371             ZoneOffset offset = ZoneOffset.ofHours(i);
 372             Clock clock = Clock.fixed(base.toInstant(), offset);
 373             ZonedDateTime test = ZonedDateTime.now(clock);
 374             assertEquals(test.getHour(), (12 + i) % 24);
 375             assertEquals(test.getMinute(), 0);
 376             assertEquals(test.getSecond(), 0);
 377             assertEquals(test.getNano(), 0);
 378             assertEquals(test.getOffset(), offset);
 379             assertEquals(test.getZone(), offset);
 380         }
 381     }
 382 
 383     //-----------------------------------------------------------------------
 384     // dateTime factories
 385     //-----------------------------------------------------------------------
 386     void check(ZonedDateTime test, int y, int m, int d, int h, int min, int s, int n, ZoneOffset offset, ZoneId zone) {
 387         assertEquals(test.getYear(), y);
 388         assertEquals(test.getMonth().getValue(), m);
 389         assertEquals(test.getDayOfMonth(), d);
 390         assertEquals(test.getHour(), h);
 391         assertEquals(test.getMinute(), min);
 392         assertEquals(test.getSecond(), s);
 393         assertEquals(test.getNano(), n);
 394         assertEquals(test.getOffset(), offset);
 395         assertEquals(test.getZone(), zone);
 396     }
 397 
 398     //-----------------------------------------------------------------------
 399     // of(LocalDate, LocalTime, ZoneId)
 400     //-----------------------------------------------------------------------
 401     @Test
 402     public void factory_of_LocalDateLocalTime() {
 403         ZonedDateTime test = ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
 404         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 405     }
 406 
 407     @Test
 408     public void factory_of_LocalDateLocalTime_inGap() {
 409         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30.toLocalDate(), TEST_PARIS_GAP_2008_03_30_02_30.toLocalTime(), ZONE_PARIS);
 410         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 411     }
 412 
 413     @Test
 414     public void factory_of_LocalDateLocalTime_inOverlap() {
 415         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalDate(), TEST_PARIS_OVERLAP_2008_10_26_02_30.toLocalTime(), ZONE_PARIS);
 416         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
 417     }
 418 
 419     @Test(expectedExceptions=NullPointerException.class)
 420     public void factory_of_LocalDateLocalTime_nullDate() {
 421         ZonedDateTime.of((LocalDate) null, LocalTime.of(11, 30, 10, 500), ZONE_PARIS);
 422     }
 423 
 424     @Test(expectedExceptions=NullPointerException.class)
 425     public void factory_of_LocalDateLocalTime_nullTime() {
 426         ZonedDateTime.of(LocalDate.of(2008, 6, 30), (LocalTime) null, ZONE_PARIS);
 427     }
 428 
 429     @Test(expectedExceptions=NullPointerException.class)
 430     public void factory_of_LocalDateLocalTime_nullZone() {
 431         ZonedDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30, 10, 500), null);
 432     }
 433 
 434     //-----------------------------------------------------------------------
 435     // of(LocalDateTime, ZoneId)
 436     //-----------------------------------------------------------------------
 437     @Test
 438     public void factory_of_LocalDateTime() {
 439         LocalDateTime base = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 440         ZonedDateTime test = ZonedDateTime.of(base, ZONE_PARIS);
 441         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 442     }
 443 
 444     @Test
 445     public void factory_of_LocalDateTime_inGap() {
 446         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_GAP_2008_03_30_02_30, ZONE_PARIS);
 447         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 448     }
 449 
 450     @Test
 451     public void factory_of_LocalDateTime_inOverlap() {
 452         ZonedDateTime test = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30, ZONE_PARIS);
 453         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time in summer offset
 454     }
 455 
 456     @Test(expectedExceptions=NullPointerException.class)
 457     public void factory_of_LocalDateTime_nullDateTime() {
 458         ZonedDateTime.of((LocalDateTime) null, ZONE_PARIS);
 459     }
 460 
 461     @Test(expectedExceptions=NullPointerException.class)
 462     public void factory_of_LocalDateTime_nullZone() {
 463         LocalDateTime base = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 464         ZonedDateTime.of(base, null);
 465     }
 466 
 467     //-----------------------------------------------------------------------
 468     // of(int..., ZoneId)
 469     //-----------------------------------------------------------------------
 470     @Test
 471     public void factory_of_ints() {
 472         ZonedDateTime test = ZonedDateTime.of(2008, 6, 30, 11, 30, 10, 500, ZONE_PARIS);
 473         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 474     }
 475 
 476     //-----------------------------------------------------------------------
 477     // ofInstant(Instant, ZoneId)
 478     //-----------------------------------------------------------------------
 479     @Test
 480     public void factory_ofInstant_Instant_ZR() {
 481         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 35).toInstant(OFFSET_0200);
 482         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 483         check(test, 2008, 6, 30, 11, 30, 10, 35, OFFSET_0200, ZONE_PARIS);
 484     }
 485 
 486     @Test
 487     public void factory_ofInstant_Instant_ZO() {
 488         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 45).toInstant(OFFSET_0200);
 489         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_0200);
 490         check(test, 2008, 6, 30, 11, 30, 10, 45, OFFSET_0200, OFFSET_0200);
 491     }
 492 
 493     @Test
 494     public void factory_ofInstant_Instant_inGap() {
 495         Instant instant = TEST_PARIS_GAP_2008_03_30_02_30.toInstant(OFFSET_0100);
 496         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 497         check(test, 2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // one hour later in summer offset
 498     }
 499 
 500     @Test
 501     public void factory_ofInstant_Instant_inOverlap_earlier() {
 502         Instant instant = TEST_PARIS_OVERLAP_2008_10_26_02_30.toInstant(OFFSET_0200);
 503         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 504         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // same time and offset
 505     }
 506 
 507     @Test
 508     public void factory_ofInstant_Instant_inOverlap_later() {
 509         Instant instant = TEST_PARIS_OVERLAP_2008_10_26_02_30.toInstant(OFFSET_0100);
 510         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 511         check(test, 2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS);  // same time and offset
 512     }
 513 
 514     @Test
 515     public void factory_ofInstant_Instant_invalidOffset() {
 516         Instant instant = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).toInstant(OFFSET_0130);
 517         ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZONE_PARIS);
 518         check(test, 2008, 6, 30, 12, 0, 10, 500, OFFSET_0200, ZONE_PARIS);  // corrected offset, thus altered time
 519     }
 520 
 521     @Test
 522     public void factory_ofInstant_allSecsInDay() {
 523         for (int i = 0; i < (24 * 60 * 60); i++) {
 524             Instant instant = Instant.ofEpochSecond(i);
 525             ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_0100);
 526             assertEquals(test.getYear(), 1970);
 527             assertEquals(test.getMonth(), Month.JANUARY);
 528             assertEquals(test.getDayOfMonth(), 1 + (i >= 23 * 60 * 60 ? 1 : 0));
 529             assertEquals(test.getHour(), ((i / (60 * 60)) + 1) % 24);
 530             assertEquals(test.getMinute(), (i / 60) % 60);
 531             assertEquals(test.getSecond(), i % 60);
 532         }
 533     }
 534 
 535     @Test
 536     public void factory_ofInstant_allDaysInCycle() {
 537         // sanity check using different algorithm
 538         ZonedDateTime expected = LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0).atZone(ZoneOffset.UTC);
 539         for (long i = 0; i < 146097; i++) {
 540             Instant instant = Instant.ofEpochSecond(i * 24L * 60L * 60L);
 541             ZonedDateTime test = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 542             assertEquals(test, expected);
 543             expected = expected.plusDays(1);
 544         }
 545     }
 546 
 547     @Test
 548     public void factory_ofInstant_minWithMinOffset() {
 549         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 550         int year = Year.MIN_VALUE;
 551         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 552         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L - OFFSET_MIN.getTotalSeconds());
 553         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 554         assertEquals(test.getYear(), Year.MIN_VALUE);
 555         assertEquals(test.getMonth().getValue(), 1);
 556         assertEquals(test.getDayOfMonth(), 1);
 557         assertEquals(test.getOffset(), OFFSET_MIN);
 558         assertEquals(test.getHour(), 0);
 559         assertEquals(test.getMinute(), 0);
 560         assertEquals(test.getSecond(), 0);
 561         assertEquals(test.getNano(), 0);
 562     }
 563 
 564     @Test
 565     public void factory_ofInstant_minWithMaxOffset() {
 566         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 567         int year = Year.MIN_VALUE;
 568         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 569         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L - OFFSET_MAX.getTotalSeconds());
 570         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 571         assertEquals(test.getYear(), Year.MIN_VALUE);
 572         assertEquals(test.getMonth().getValue(), 1);
 573         assertEquals(test.getDayOfMonth(), 1);
 574         assertEquals(test.getOffset(), OFFSET_MAX);
 575         assertEquals(test.getHour(), 0);
 576         assertEquals(test.getMinute(), 0);
 577         assertEquals(test.getSecond(), 0);
 578         assertEquals(test.getNano(), 0);
 579     }
 580 
 581     @Test
 582     public void factory_ofInstant_maxWithMinOffset() {
 583         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 584         int year = Year.MAX_VALUE;
 585         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) + 365 - days_0000_to_1970;
 586         Instant instant = Instant.ofEpochSecond((days + 1) * 24L * 60L * 60L - 1 - OFFSET_MIN.getTotalSeconds());
 587         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 588         assertEquals(test.getYear(), Year.MAX_VALUE);
 589         assertEquals(test.getMonth().getValue(), 12);
 590         assertEquals(test.getDayOfMonth(), 31);
 591         assertEquals(test.getOffset(), OFFSET_MIN);
 592         assertEquals(test.getHour(), 23);
 593         assertEquals(test.getMinute(), 59);
 594         assertEquals(test.getSecond(), 59);
 595         assertEquals(test.getNano(), 0);
 596     }
 597 
 598     @Test
 599     public void factory_ofInstant_maxWithMaxOffset() {
 600         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 601         int year = Year.MAX_VALUE;
 602         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) + 365 - days_0000_to_1970;
 603         Instant instant = Instant.ofEpochSecond((days + 1) * 24L * 60L * 60L - 1 - OFFSET_MAX.getTotalSeconds());
 604         ZonedDateTime test = ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 605         assertEquals(test.getYear(), Year.MAX_VALUE);
 606         assertEquals(test.getMonth().getValue(), 12);
 607         assertEquals(test.getDayOfMonth(), 31);
 608         assertEquals(test.getOffset(), OFFSET_MAX);
 609         assertEquals(test.getHour(), 23);
 610         assertEquals(test.getMinute(), 59);
 611         assertEquals(test.getSecond(), 59);
 612         assertEquals(test.getNano(), 0);
 613     }
 614 
 615     //-----------------------------------------------------------------------
 616     @Test(expectedExceptions=DateTimeException.class)
 617     public void factory_ofInstant_maxInstantWithMaxOffset() {
 618         Instant instant = Instant.ofEpochSecond(Long.MAX_VALUE);
 619         ZonedDateTime.ofInstant(instant, OFFSET_MAX);
 620     }
 621 
 622     @Test(expectedExceptions=DateTimeException.class)
 623     public void factory_ofInstant_maxInstantWithMinOffset() {
 624         Instant instant = Instant.ofEpochSecond(Long.MAX_VALUE);
 625         ZonedDateTime.ofInstant(instant, OFFSET_MIN);
 626     }
 627 
 628     @Test(expectedExceptions=DateTimeException.class)
 629     public void factory_ofInstant_tooBig() {
 630         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 631         long year = Year.MAX_VALUE + 1L;
 632         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 633         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L);
 634         ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 635     }
 636 
 637     @Test(expectedExceptions=DateTimeException.class)
 638     public void factory_ofInstant_tooLow() {
 639         long days_0000_to_1970 = (146097 * 5) - (30 * 365 + 7);
 640         int year = Year.MIN_VALUE - 1;
 641         long days = (year * 365L + (year / 4 - year / 100 + year / 400)) - days_0000_to_1970;
 642         Instant instant = Instant.ofEpochSecond(days * 24L * 60L * 60L);
 643         ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
 644     }
 645 
 646     @Test(expectedExceptions=NullPointerException.class)
 647     public void factory_ofInstant_Instant_nullInstant() {
 648         ZonedDateTime.ofInstant((Instant) null, ZONE_0100);
 649     }
 650 
 651     @Test(expectedExceptions=NullPointerException.class)
 652     public void factory_ofInstant_Instant_nullZone() {
 653         ZonedDateTime.ofInstant(Instant.EPOCH, null);
 654     }
 655 
 656     //-----------------------------------------------------------------------
 657     // ofStrict(LocalDateTime, ZoneId, ZoneOffset)
 658     //-----------------------------------------------------------------------
 659     @Test
 660     public void factory_ofStrict_LDT_ZI_ZO() {
 661         LocalDateTime normal = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500);
 662         ZonedDateTime test = ZonedDateTime.ofStrict(normal, OFFSET_0200, ZONE_PARIS);
 663         check(test, 2008, 6, 30, 11, 30, 10, 500, OFFSET_0200, ZONE_PARIS);
 664     }
 665 
 666     @Test(expectedExceptions=DateTimeException.class)
 667     public void factory_ofStrict_LDT_ZI_ZO_inGap() {
 668         try {
 669             ZonedDateTime.ofStrict(TEST_PARIS_GAP_2008_03_30_02_30, OFFSET_0100, ZONE_PARIS);
 670         } catch (DateTimeException ex) {
 671             assertEquals(ex.getMessage().contains(" gap"), true);
 672             throw ex;
 673         }
 674     }
 675 
 676     @Test(expectedExceptions=DateTimeException.class)
 677     public void factory_ofStrict_LDT_ZI_ZO_inOverlap_invalidOfset() {
 678         try {
 679             ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0130, ZONE_PARIS);
 680         } catch (DateTimeException ex) {
 681             assertEquals(ex.getMessage().contains(" is not valid for "), true);
 682             throw ex;
 683         }
 684     }
 685 
 686     @Test(expectedExceptions=DateTimeException.class)
 687     public void factory_ofStrict_LDT_ZI_ZO_invalidOffset() {
 688         try {
 689             ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0130, ZONE_PARIS);
 690         } catch (DateTimeException ex) {
 691             assertEquals(ex.getMessage().contains(" is not valid for "), true);
 692             throw ex;
 693         }
 694     }
 695 
 696     @Test(expectedExceptions=NullPointerException.class)
 697     public void factory_ofStrict_LDT_ZI_ZO_nullLDT() {
 698         ZonedDateTime.ofStrict((LocalDateTime) null, OFFSET_0100, ZONE_PARIS);
 699     }
 700 
 701     @Test(expectedExceptions=NullPointerException.class)
 702     public void factory_ofStrict_LDT_ZI_ZO_nullZO() {
 703         ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, null, ZONE_PARIS);
 704     }
 705 
 706     @Test(expectedExceptions=NullPointerException.class)
 707     public void factory_ofStrict_LDT_ZI_ZO_nullZI() {
 708         ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0100, null);
 709     }
 710 
 711     //-----------------------------------------------------------------------
 712     // from(TemporalAccessor)
 713     //-----------------------------------------------------------------------
 714     @Test
 715     public void factory_from_TemporalAccessor_ZDT() {
 716         assertEquals(ZonedDateTime.from(TEST_DATE_TIME_PARIS), TEST_DATE_TIME_PARIS);
 717     }
 718 
 719     @Test
 720     public void factory_from_TemporalAccessor_LDT_ZoneId() {
 721         assertEquals(ZonedDateTime.from(new TemporalAccessor() {
 722             @Override
 723             public boolean isSupported(TemporalField field) {
 724                 return TEST_DATE_TIME_PARIS.toLocalDateTime().isSupported(field);
 725             }
 726             @Override
 727             public long getLong(TemporalField field) {
 728                 return TEST_DATE_TIME_PARIS.toLocalDateTime().getLong(field);
 729             }
 730             @SuppressWarnings("unchecked")
 731             @Override
 732             public <R> R query(TemporalQuery<R> query) {
 733                 if (query == TemporalQuery.zoneId()) {
 734                     return (R) TEST_DATE_TIME_PARIS.getZone();
 735                 }
 736                 return TemporalAccessor.super.query(query);
 737             }
 738         }), TEST_DATE_TIME_PARIS);
 739     }
 740 
 741     @Test
 742     public void factory_from_TemporalAccessor_Instant_ZoneId() {
 743         assertEquals(ZonedDateTime.from(new TemporalAccessor() {
 744             @Override
 745             public boolean isSupported(TemporalField field) {
 746                 return field == INSTANT_SECONDS || field == NANO_OF_SECOND;
 747             }
 748 
 749             @Override
 750             public long getLong(TemporalField field) {
 751                 return TEST_DATE_TIME_PARIS.toInstant().getLong(field);
 752             }
 753 
 754             @SuppressWarnings("unchecked")
 755             @Override
 756             public <R> R query(TemporalQuery<R> query) {
 757                 if (query == TemporalQuery.zoneId()) {
 758                     return (R) TEST_DATE_TIME_PARIS.getZone();
 759                 }
 760                 return TemporalAccessor.super.query(query);
 761             }
 762         }), TEST_DATE_TIME_PARIS);
 763     }
 764 
 765     @Test(expectedExceptions=DateTimeException.class)
 766     public void factory_from_TemporalAccessor_invalid_noDerive() {
 767         ZonedDateTime.from(LocalTime.of(12, 30));
 768     }
 769 
 770     @Test(expectedExceptions=NullPointerException.class)
 771     public void factory_from_TemporalAccessor_null() {
 772         ZonedDateTime.from((TemporalAccessor) null);
 773     }
 774 
 775     //-----------------------------------------------------------------------
 776     // parse()
 777     //-----------------------------------------------------------------------
 778     @Test(dataProvider="sampleToString")
 779     public void test_parse(int y, int month, int d, int h, int m, int s, int n, String zoneId, String text) {
 780         ZonedDateTime t = ZonedDateTime.parse(text);
 781         assertEquals(t.getYear(), y);
 782         assertEquals(t.getMonth().getValue(), month);
 783         assertEquals(t.getDayOfMonth(), d);
 784         assertEquals(t.getHour(), h);
 785         assertEquals(t.getMinute(), m);
 786         assertEquals(t.getSecond(), s);
 787         assertEquals(t.getNano(), n);
 788         assertEquals(t.getZone().getId(), zoneId);
 789     }
 790 
 791     @DataProvider(name="parseAdditional")
 792     Object[][] data_parseAdditional() {
 793         return new Object[][] {
 794                 {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
 795                 {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
 796                 {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "Z"},
 797                 {"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 798                 {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 799                 {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 800                 {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
 801                 {"2012-06-30T12:30:40-01:00[-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
 802                 {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
 803                 {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
 804                 {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"},
 805                 {"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"},
 806         };
 807     }
 808 
 809     @Test(dataProvider="parseAdditional")
 810     public void test_parseAdditional(String text, int y, int month, int d, int h, int m, int s, int n, String zoneId) {
 811         ZonedDateTime t = ZonedDateTime.parse(text);
 812         assertEquals(t.getYear(), y);
 813         assertEquals(t.getMonth().getValue(), month);
 814         assertEquals(t.getDayOfMonth(), d);
 815         assertEquals(t.getHour(), h);
 816         assertEquals(t.getMinute(), m);
 817         assertEquals(t.getSecond(), s);
 818         assertEquals(t.getNano(), n);
 819         assertEquals(t.getZone().getId(), zoneId);
 820     }
 821 
 822     @Test(expectedExceptions=DateTimeParseException.class)
 823     public void factory_parse_illegalValue() {
 824         ZonedDateTime.parse("2008-06-32T11:15+01:00[Europe/Paris]");
 825     }
 826 
 827     @Test(expectedExceptions=DateTimeParseException.class)
 828     public void factory_parse_invalidValue() {
 829         ZonedDateTime.parse("2008-06-31T11:15+01:00[Europe/Paris]");
 830     }
 831 
 832     @Test(expectedExceptions=NullPointerException.class)
 833     public void factory_parse_nullText() {
 834         ZonedDateTime.parse((String) null);
 835     }
 836 
 837     //-----------------------------------------------------------------------
 838     // parse(DateTimeFormatter)
 839     //-----------------------------------------------------------------------
 840     @Test
 841     public void factory_parse_formatter() {
 842         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s VV");
 843         ZonedDateTime test = ZonedDateTime.parse("2010 12 3 11 30 0 Europe/London", f);
 844         assertEquals(test, ZonedDateTime.of(LocalDateTime.of(2010, 12, 3, 11, 30), ZoneId.of("Europe/London")));
 845     }
 846 
 847     @Test(expectedExceptions=NullPointerException.class)
 848     public void factory_parse_formatter_nullText() {
 849         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
 850         ZonedDateTime.parse((String) null, f);
 851     }
 852 
 853     @Test(expectedExceptions=NullPointerException.class)
 854     public void factory_parse_formatter_nullFormatter() {
 855         ZonedDateTime.parse("ANY", null);
 856     }
 857 
 858     //-----------------------------------------------------------------------
 859     // basics
 860     //-----------------------------------------------------------------------
 861     @DataProvider(name="sampleTimes")
 862     Object[][] provider_sampleTimes() {
 863         return new Object[][] {
 864             {2008, 6, 30, 11, 30, 20, 500, ZONE_0100},
 865             {2008, 6, 30, 11, 0, 0, 0, ZONE_0100},
 866             {2008, 6, 30, 11, 30, 20, 500, ZONE_PARIS},
 867             {2008, 6, 30, 11, 0, 0, 0, ZONE_PARIS},
 868             {2008, 6, 30, 23, 59, 59, 999999999, ZONE_0100},
 869             {-1, 1, 1, 0, 0, 0, 0, ZONE_0100},
 870         };
 871     }
 872 
 873     @Test(dataProvider="sampleTimes")
 874     public void test_get(int y, int o, int d, int h, int m, int s, int n, ZoneId zone) {
 875         LocalDate localDate = LocalDate.of(y, o, d);
 876         LocalTime localTime = LocalTime.of(h, m, s, n);
 877         LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
 878         ZoneOffset offset = zone.getRules().getOffset(localDateTime);
 879         ZonedDateTime a = ZonedDateTime.of(localDateTime, zone);
 880 
 881         assertEquals(a.getYear(), localDate.getYear());
 882         assertEquals(a.getMonth(), localDate.getMonth());
 883         assertEquals(a.getDayOfMonth(), localDate.getDayOfMonth());
 884         assertEquals(a.getDayOfYear(), localDate.getDayOfYear());
 885         assertEquals(a.getDayOfWeek(), localDate.getDayOfWeek());
 886 
 887         assertEquals(a.getHour(), localTime.getHour());
 888         assertEquals(a.getMinute(), localTime.getMinute());
 889         assertEquals(a.getSecond(), localTime.getSecond());
 890         assertEquals(a.getNano(), localTime.getNano());
 891 
 892         assertEquals(a.toLocalDate(), localDate);
 893         assertEquals(a.toLocalTime(), localTime);
 894         assertEquals(a.toLocalDateTime(), localDateTime);
 895         if (zone instanceof ZoneOffset) {
 896             assertEquals(a.toString(), localDateTime.toString() + offset.toString());
 897         } else {
 898             assertEquals(a.toString(), localDateTime.toString() + offset.toString() + "[" + zone.toString() + "]");
 899         }
 900     }
 901 
 902     //-----------------------------------------------------------------------
 903     // get(TemporalField)
 904     //-----------------------------------------------------------------------
 905     @Test
 906     public void test_get_TemporalField() {
 907         ZonedDateTime test = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321), ZONE_0100);
 908         assertEquals(test.get(ChronoField.YEAR), 2008);
 909         assertEquals(test.get(ChronoField.MONTH_OF_YEAR), 6);
 910         assertEquals(test.get(ChronoField.DAY_OF_MONTH), 30);
 911         assertEquals(test.get(ChronoField.DAY_OF_WEEK), 1);
 912         assertEquals(test.get(ChronoField.DAY_OF_YEAR), 182);
 913 
 914         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
 915         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
 916         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
 917         assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
 918         assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
 919         assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
 920 
 921         assertEquals(test.get(ChronoField.OFFSET_SECONDS), 3600);
 922     }
 923 
 924     @Test
 925     public void test_getLong_TemporalField() {
 926         ZonedDateTime test = ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321), ZONE_0100);
 927         assertEquals(test.getLong(ChronoField.YEAR), 2008);
 928         assertEquals(test.getLong(ChronoField.MONTH_OF_YEAR), 6);
 929         assertEquals(test.getLong(ChronoField.DAY_OF_MONTH), 30);
 930         assertEquals(test.getLong(ChronoField.DAY_OF_WEEK), 1);
 931         assertEquals(test.getLong(ChronoField.DAY_OF_YEAR), 182);
 932 
 933         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
 934         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
 935         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
 936         assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
 937         assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
 938         assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
 939 
 940         assertEquals(test.getLong(ChronoField.OFFSET_SECONDS), 3600);
 941         assertEquals(test.getLong(ChronoField.INSTANT_SECONDS), test.toEpochSecond());
 942     }
 943 
 944     //-----------------------------------------------------------------------
 945     // query(TemporalQuery)
 946     //-----------------------------------------------------------------------
 947     @Test
 948     public void test_query_chrono() {
 949         assertEquals(TEST_DATE_TIME.query(TemporalQuery.chronology()), IsoChronology.INSTANCE);
 950         assertEquals(TemporalQuery.chronology().queryFrom(TEST_DATE_TIME), IsoChronology.INSTANCE);
 951     }
 952 
 953     @Test
 954     public void test_query_zoneId() {
 955         assertEquals(TEST_DATE_TIME.query(TemporalQuery.zoneId()), TEST_DATE_TIME.getZone());
 956         assertEquals(TemporalQuery.zoneId().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getZone());
 957     }
 958 
 959     @Test
 960     public void test_query_precision() {
 961         assertEquals(TEST_DATE_TIME.query(TemporalQuery.precision()), NANOS);
 962         assertEquals(TemporalQuery.precision().queryFrom(TEST_DATE_TIME), NANOS);
 963     }
 964 
 965     @Test
 966     public void test_query_offset() {
 967         assertEquals(TEST_DATE_TIME.query(TemporalQuery.offset()), TEST_DATE_TIME.getOffset());
 968         assertEquals(TemporalQuery.offset().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getOffset());
 969     }
 970 
 971     @Test
 972     public void test_query_zone() {
 973         assertEquals(TEST_DATE_TIME.query(TemporalQuery.zone()), TEST_DATE_TIME.getZone());
 974         assertEquals(TemporalQuery.zone().queryFrom(TEST_DATE_TIME), TEST_DATE_TIME.getZone());
 975     }
 976 
 977     @Test(expectedExceptions=NullPointerException.class)
 978     public void test_query_null() {
 979         TEST_DATE_TIME.query(null);
 980     }
 981 
 982     //-----------------------------------------------------------------------
 983     // withEarlierOffsetAtOverlap()
 984     //-----------------------------------------------------------------------
 985     @Test
 986     public void test_withEarlierOffsetAtOverlap_notAtOverlap() {
 987         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0200, ZONE_PARIS);
 988         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
 989         assertEquals(test, base);  // not changed
 990     }
 991 
 992     @Test
 993     public void test_withEarlierOffsetAtOverlap_atOverlap() {
 994         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0100, ZONE_PARIS);
 995         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
 996         assertEquals(test.getOffset(), OFFSET_0200);  // offset changed to earlier
 997         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
 998     }
 999 
1000     @Test
1001     public void test_withEarlierOffsetAtOverlap_atOverlap_noChange() {
1002         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0200, ZONE_PARIS);
1003         ZonedDateTime test = base.withEarlierOffsetAtOverlap();
1004         assertEquals(test, base);  // not changed
1005     }
1006 
1007     //-----------------------------------------------------------------------
1008     // withLaterOffsetAtOverlap()
1009     //-----------------------------------------------------------------------
1010     @Test
1011     public void test_withLaterOffsetAtOverlap_notAtOverlap() {
1012         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_LOCAL_2008_06_30_11_30_59_500, OFFSET_0200, ZONE_PARIS);
1013         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1014         assertEquals(test, base);  // not changed
1015     }
1016 
1017     @Test
1018     public void test_withLaterOffsetAtOverlap_atOverlap() {
1019         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0200, ZONE_PARIS);
1020         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1021         assertEquals(test.getOffset(), OFFSET_0100);  // offset changed to later
1022         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());  // date-time not changed
1023     }
1024 
1025     @Test
1026     public void test_withLaterOffsetAtOverlap_atOverlap_noChange() {
1027         ZonedDateTime base = ZonedDateTime.ofStrict(TEST_PARIS_OVERLAP_2008_10_26_02_30, OFFSET_0100, ZONE_PARIS);
1028         ZonedDateTime test = base.withLaterOffsetAtOverlap();
1029         assertEquals(test, base);  // not changed
1030     }
1031 
1032     //-----------------------------------------------------------------------
1033     // withZoneSameLocal(ZoneId)
1034     //-----------------------------------------------------------------------
1035     @Test
1036     public void test_withZoneSameLocal() {
1037         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1038         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1039         ZonedDateTime test = base.withZoneSameLocal(ZONE_0200);
1040         assertEquals(test.toLocalDateTime(), base.toLocalDateTime());
1041     }
1042 
1043     @Test
1044     public void test_withZoneSameLocal_noChange() {
1045         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1046         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1047         ZonedDateTime test = base.withZoneSameLocal(ZONE_0100);
1048         assertEquals(test, base);
1049     }
1050 
1051     @Test
1052     public void test_withZoneSameLocal_retainOffset1() {
1053         LocalDateTime ldt = LocalDateTime.of(2008, 11, 2, 1, 30, 59, 0);  // overlap
1054         ZonedDateTime base = ZonedDateTime.of(ldt, ZoneId.of("UTC-04:00") );
1055         ZonedDateTime test = base.withZoneSameLocal(ZoneId.of("America/New_York"));
1056         assertEquals(base.getOffset(), ZoneOffset.ofHours(-4));
1057         assertEquals(test.getOffset(), ZoneOffset.ofHours(-4));
1058     }
1059 
1060     @Test
1061     public void test_withZoneSameLocal_retainOffset2() {
1062         LocalDateTime ldt = LocalDateTime.of(2008, 11, 2, 1, 30, 59, 0);  // overlap
1063         ZonedDateTime base = ZonedDateTime.of(ldt, ZoneId.of("UTC-05:00") );
1064         ZonedDateTime test = base.withZoneSameLocal(ZoneId.of("America/New_York"));
1065         assertEquals(base.getOffset(), ZoneOffset.ofHours(-5));
1066         assertEquals(test.getOffset(), ZoneOffset.ofHours(-5));
1067     }
1068 
1069     @Test(expectedExceptions=NullPointerException.class)
1070     public void test_withZoneSameLocal_null() {
1071         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1072         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1073         base.withZoneSameLocal(null);
1074     }
1075 
1076     //-----------------------------------------------------------------------
1077     // withZoneSameInstant()
1078     //-----------------------------------------------------------------------
1079     @Test
1080     public void test_withZoneSameInstant() {
1081         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1082         ZonedDateTime test = base.withZoneSameInstant(ZONE_0200);
1083         ZonedDateTime expected = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.plusHours(1), ZONE_0200);
1084         assertEquals(test, expected);
1085     }
1086 
1087     @Test
1088     public void test_withZoneSameInstant_noChange() {
1089         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1090         ZonedDateTime test = base.withZoneSameInstant(ZONE_0100);
1091         assertEquals(test, base);
1092     }
1093 
1094     @Test(expectedExceptions=NullPointerException.class)
1095     public void test_withZoneSameInstant_null() {
1096         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1097         base.withZoneSameInstant(null);
1098     }
1099 
1100     //-----------------------------------------------------------------------
1101     // withFixedOffsetZone()
1102     //-----------------------------------------------------------------------
1103     @Test
1104     public void test_withZoneLocked() {
1105         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1106         ZonedDateTime test = base.withFixedOffsetZone();
1107         ZonedDateTime expected = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0200);
1108         assertEquals(test, expected);
1109     }
1110 
1111     //-----------------------------------------------------------------------
1112     // with(TemporalAdjuster)
1113     //-----------------------------------------------------------------------
1114     @Test
1115     public void test_with_adjuster_LocalDateTime_sameOffset() {
1116         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1117         ZonedDateTime test = base.with(LocalDateTime.of(2012, 7, 15, 14, 30));
1118         check(test, 2012, 7, 15, 14, 30, 0, 0, OFFSET_0200, ZONE_PARIS);
1119     }
1120 
1121     @Test
1122     public void test_with_adjuster_LocalDateTime_adjustedOffset() {
1123         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1124         ZonedDateTime test = base.with(LocalDateTime.of(2012, 1, 15, 14, 30));
1125         check(test, 2012, 1, 15, 14, 30, 0, 0, OFFSET_0100, ZONE_PARIS);
1126     }
1127 
1128     @Test
1129     public void test_with_adjuster_LocalDate() {
1130         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_PARIS);
1131         ZonedDateTime test = base.with(LocalDate.of(2012, 7, 28));
1132         check(test, 2012, 7, 28, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS);
1133     }
1134 
1135     @Test
1136     public void test_with_adjuster_LocalTime() {
1137         ZonedDateTime base = ZonedDateTime.of(TEST_PARIS_OVERLAP_2008_10_26_02_30, ZONE_PARIS);
1138         ZonedDateTime test = base.with(LocalTime.of(2, 29));
1139         check(test, 2008, 10, 26, 2, 29, 0, 0, OFFSET_0200, ZONE_PARIS);
1140     }
1141 
1142     @Test
1143     public void test_with_adjuster_Year() {
1144         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1145         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1146         ZonedDateTime test = base.with(Year.of(2007));
1147         assertEquals(test, ZonedDateTime.of(ldt.withYear(2007), ZONE_0100));
1148     }
1149 
1150     @Test
1151     public void test_with_adjuster_Month_adjustedDayOfMonth() {
1152         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1153         ZonedDateTime test = base.with(Month.JUNE);
1154         check(test, 2012, 6, 30, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);
1155     }
1156 
1157     @Test
1158     public void test_with_adjuster_Offset_same() {
1159         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1160         ZonedDateTime test = base.with(ZoneOffset.ofHours(2));
1161         check(test, 2012, 7, 31, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);
1162     }
1163 
1164     @Test
1165     public void test_with_adjuster_Offset_timeAdjust() {
1166         ZonedDateTime base = ZonedDateTime.of(LocalDateTime.of(2012, 7, 31, 0, 0), ZONE_PARIS);
1167         ZonedDateTime test = base.with(ZoneOffset.ofHours(1));
1168         check(test, 2012, 7, 31, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // invalid offset ignored
1169     }
1170 
1171     @Test
1172     public void test_with_adjuster_LocalDate_retainOffset1() {
1173         ZoneId newYork = ZoneId.of("America/New_York");
1174         LocalDateTime ldt = LocalDateTime.of(2008, 11, 1, 1, 30);
1175         ZonedDateTime base = ZonedDateTime.of(ldt, newYork);
1176         assertEquals(base.getOffset(), ZoneOffset.ofHours(-4));
1177         ZonedDateTime test = base.with(LocalDate.of(2008, 11, 2));
1178         assertEquals(test.getOffset(), ZoneOffset.ofHours(-4));
1179     }
1180 
1181     @Test
1182     public void test_with_adjuster_LocalDate_retainOffset2() {
1183         ZoneId newYork = ZoneId.of("America/New_York");
1184         LocalDateTime ldt = LocalDateTime.of(2008, 11, 3, 1, 30);
1185         ZonedDateTime base = ZonedDateTime.of(ldt, newYork);
1186         assertEquals(base.getOffset(), ZoneOffset.ofHours(-5));
1187         ZonedDateTime test = base.with(LocalDate.of(2008, 11, 2));
1188         assertEquals(test.getOffset(), ZoneOffset.ofHours(-5));
1189     }
1190 
1191     @Test
1192     public void test_with_adjuster_OffsetDateTime_validOffsetNotInOverlap() {
1193         // ODT will be a valid ZDT for the zone, so must be retained exactly
1194         OffsetDateTime odt = TEST_LOCAL_2008_06_30_11_30_59_500.atOffset(OFFSET_0200);
1195         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1196         ZonedDateTime test = zdt.with(odt);
1197         assertEquals(test.toOffsetDateTime(), odt);
1198     }
1199 
1200     @Test
1201     public void test_with_adjuster_OffsetDateTime_invalidOffsetIgnored() {
1202         // ODT has invalid offset for ZDT, so only LDT is set
1203         OffsetDateTime odt = TEST_LOCAL_2008_06_30_11_30_59_500.atOffset(OFFSET_0130);
1204         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1205         ZonedDateTime test = zdt.with(odt);
1206         assertEquals(test.toLocalDateTime(), TEST_LOCAL_2008_06_30_11_30_59_500);
1207         assertEquals(test.getOffset(), zdt.getOffset());
1208     }
1209 
1210     @Test
1211     public void test_with_adjuster_OffsetDateTime_retainOffsetInOverlap1() {
1212         // ODT will be a valid ZDT for the zone, so must be retained exactly
1213         OffsetDateTime odt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atOffset(OFFSET_0100);
1214         ZonedDateTime zdt = TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS);
1215         ZonedDateTime test = zdt.with(odt);
1216         assertEquals(test.toOffsetDateTime(), odt);
1217     }
1218 
1219     @Test
1220     public void test_with_adjuster_OffsetDateTime_retainOffsetInOverlap2() {
1221         // ODT will be a valid ZDT for the zone, so must be retained exactly
1222         OffsetDateTime odt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atOffset(OFFSET_0200);
1223         ZonedDateTime zdt = TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS);
1224         ZonedDateTime test = zdt.with(odt);
1225         assertEquals(test.toOffsetDateTime(), odt);
1226     }
1227 
1228     @Test
1229     public void test_with_adjuster_OffsetTime_validOffsetNotInOverlap() {
1230         // OT has valid offset for resulting time
1231         OffsetTime ot = OffsetTime.of(15, 50, 30, 40, OFFSET_0100);
1232         ZonedDateTime zdt = TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS);
1233         ZonedDateTime test = zdt.with(ot);
1234         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 15, 50, 30, 40));
1235         assertEquals(test.getOffset(), OFFSET_0100);
1236     }
1237 
1238     @Test
1239     public void test_with_adjuster_OffsetTime_invalidOffsetIgnored1() {
1240         // OT has invalid offset for ZDT, so only LT is set
1241         OffsetTime ot = OffsetTime.of(0, 50, 30, 40, OFFSET_0130);
1242         ZonedDateTime zdt = dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // earlier part of overlap
1243         ZonedDateTime test = zdt.with(ot);
1244         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 0, 50, 30, 40));
1245         assertEquals(test.getOffset(), OFFSET_0200);  // offset not adjusted
1246     }
1247 
1248     @Test
1249     public void test_with_adjuster_OffsetTime_invalidOffsetIgnored2() {
1250         // OT has invalid offset for ZDT, so only LT is set
1251         OffsetTime ot = OffsetTime.of(15, 50, 30, 40, OFFSET_0130);
1252         ZonedDateTime zdt = dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS);  // earlier part of overlap
1253         ZonedDateTime test = zdt.with(ot);
1254         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 15, 50, 30, 40));
1255         assertEquals(test.getOffset(), OFFSET_0100);  // offset adjusted because of time change
1256     }
1257 
1258     @Test
1259     public void test_with_adjuster_OffsetTime_validOffsetIntoOverlap1() {
1260         // OT has valid offset for resulting time
1261         OffsetTime ot = OffsetTime.of(2, 30, 30, 40, OFFSET_0100);  // valid offset in overlap
1262         ZonedDateTime zdt = dateTime(2008, 10, 26, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // just before overlap
1263         ZonedDateTime test = zdt.with(ot);
1264         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 2, 30, 30, 40));
1265         assertEquals(test.getOffset(), OFFSET_0100);
1266     }
1267 
1268     @Test
1269     public void test_with_adjuster_OffsetTime_validOffsetIntoOverlap2() {
1270         // OT has valid offset for resulting time
1271         OffsetTime ot = OffsetTime.of(2, 30, 30, 40, OFFSET_0200);  // valid offset in overlap
1272         ZonedDateTime zdt = dateTime(2008, 10, 26, 0, 0, 0, 0, OFFSET_0200, ZONE_PARIS);  // just before overlap
1273         ZonedDateTime test = zdt.with(ot);
1274         assertEquals(test.toLocalDateTime(), dateTime(2008, 10, 26, 2, 30, 30, 40));
1275         assertEquals(test.getOffset(), OFFSET_0200);
1276     }
1277 
1278     @Test(expectedExceptions=NullPointerException.class)
1279     public void test_with_adjuster_null() {
1280         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1281         base.with((TemporalAdjuster) null);
1282     }
1283 
1284     //-----------------------------------------------------------------------
1285     // with(long,TemporalUnit)
1286     //-----------------------------------------------------------------------
1287     @DataProvider(name = "withFieldLong")
1288     Object[][] data_withFieldLong() {
1289         return new Object[][] {
1290                 // set simple fields
1291                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), YEAR, 2009,
1292                         dateTime(2009, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1293                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), MONTH_OF_YEAR, 7,
1294                         dateTime(2008, 7, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1295                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), DAY_OF_MONTH, 15,
1296                         dateTime(2008, 6, 15, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1297                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), HOUR_OF_DAY, 14,
1298                         dateTime(2008, 6, 30, 14, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},
1299 
1300                 // set around overlap
1301                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), HOUR_OF_DAY, 0,
1302                         dateTime(2008, 10, 26, 0, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1303                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), HOUR_OF_DAY, 0,
1304                         dateTime(2008, 10, 26, 0, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1305                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), MINUTE_OF_HOUR, 20,
1306                         dateTime(2008, 10, 26, 2, 20, 0, 0, OFFSET_0200, ZONE_PARIS)},  // offset unchanged
1307                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), MINUTE_OF_HOUR, 20,
1308                         dateTime(2008, 10, 26, 2, 20, 0, 0, OFFSET_0100, ZONE_PARIS)},  // offset unchanged
1309                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), HOUR_OF_DAY, 3,
1310                         dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1311                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), HOUR_OF_DAY, 3,
1312                         dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1313 
1314                 // set offset
1315                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), OFFSET_SECONDS, 7200,
1316                         dateTime(2008, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},  // offset unchanged
1317                 {TEST_LOCAL_2008_06_30_11_30_59_500.atZone(ZONE_PARIS), OFFSET_SECONDS, 3600,
1318                         dateTime(2008, 6, 30, 11, 30, 59, 500, OFFSET_0200, ZONE_PARIS)},  // invalid offset ignored
1319                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), OFFSET_SECONDS, 3600,
1320                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1321                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), OFFSET_SECONDS, 3600,
1322                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1323                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withEarlierOffsetAtOverlap(), OFFSET_SECONDS, 7200,
1324                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1325                 {TEST_PARIS_OVERLAP_2008_10_26_02_30.atZone(ZONE_PARIS).withLaterOffsetAtOverlap(), OFFSET_SECONDS, 7200,
1326                         dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1327         };
1328     };
1329 
1330     @Test(dataProvider = "withFieldLong")
1331     public void test_with_fieldLong(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1332         assertEquals(base.with(setField, setValue), expected);
1333     }
1334 
1335     @Test(dataProvider = "withFieldLong")
1336     public void test_with_adjuster_ensureZoneOffsetConsistent(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1337         if (setField == OFFSET_SECONDS) {
1338             assertEquals(base.with(ZoneOffset.ofTotalSeconds(setValue)), expected);
1339         }
1340     }
1341 
1342     @Test(dataProvider = "withFieldLong")
1343     public void test_with_adjuster_ensureOffsetDateTimeConsistent(ZonedDateTime base, TemporalField setField, int setValue, ZonedDateTime expected) {
1344         if (setField == OFFSET_SECONDS) {
1345             OffsetDateTime odt = base.toOffsetDateTime().with(setField, setValue);
1346             assertEquals(base.with(odt), expected);
1347         }
1348     }
1349 
1350     //-----------------------------------------------------------------------
1351     // withYear()
1352     //-----------------------------------------------------------------------
1353     @Test
1354     public void test_withYear_normal() {
1355         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1356         ZonedDateTime test = base.withYear(2007);
1357         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withYear(2007), ZONE_0100));
1358     }
1359 
1360     @Test
1361     public void test_withYear_noChange() {
1362         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1363         ZonedDateTime test = base.withYear(2008);
1364         assertEquals(test, base);
1365     }
1366 
1367     //-----------------------------------------------------------------------
1368     // with(Month)
1369     //-----------------------------------------------------------------------
1370     @Test
1371     public void test_withMonth_Month_normal() {
1372         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1373         ZonedDateTime test = base.with(JANUARY);
1374         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMonth(1), ZONE_0100));
1375     }
1376 
1377     @Test(expectedExceptions = NullPointerException.class)
1378     public void test_withMonth_Month_null() {
1379         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1380         base.with((Month) null);
1381     }
1382 
1383     //-----------------------------------------------------------------------
1384     // withMonth()
1385     //-----------------------------------------------------------------------
1386     @Test
1387     public void test_withMonth_normal() {
1388         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1389         ZonedDateTime test = base.withMonth(1);
1390         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMonth(1), ZONE_0100));
1391     }
1392 
1393     @Test
1394     public void test_withMonth_noChange() {
1395         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1396         ZonedDateTime test = base.withMonth(6);
1397         assertEquals(test, base);
1398     }
1399 
1400     @Test(expectedExceptions=DateTimeException.class)
1401     public void test_withMonth_tooBig() {
1402         TEST_DATE_TIME.withMonth(13);
1403     }
1404 
1405     @Test(expectedExceptions=DateTimeException.class)
1406     public void test_withMonth_tooSmall() {
1407         TEST_DATE_TIME.withMonth(0);
1408     }
1409 
1410     //-----------------------------------------------------------------------
1411     // withDayOfMonth()
1412     //-----------------------------------------------------------------------
1413     @Test
1414     public void test_withDayOfMonth_normal() {
1415         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1416         ZonedDateTime test = base.withDayOfMonth(15);
1417         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withDayOfMonth(15), ZONE_0100));
1418     }
1419 
1420     @Test
1421     public void test_withDayOfMonth_noChange() {
1422         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1423         ZonedDateTime test = base.withDayOfMonth(30);
1424         assertEquals(test, base);
1425     }
1426 
1427     @Test(expectedExceptions=DateTimeException.class)
1428     public void test_withDayOfMonth_tooBig() {
1429         LocalDateTime.of(2007, 7, 2, 11, 30).atZone(ZONE_PARIS).withDayOfMonth(32);
1430     }
1431 
1432     @Test(expectedExceptions=DateTimeException.class)
1433     public void test_withDayOfMonth_tooSmall() {
1434         TEST_DATE_TIME.withDayOfMonth(0);
1435     }
1436 
1437     @Test(expectedExceptions=DateTimeException.class)
1438     public void test_withDayOfMonth_invalid31() {
1439         LocalDateTime.of(2007, 6, 2, 11, 30).atZone(ZONE_PARIS).withDayOfMonth(31);
1440     }
1441 
1442     //-----------------------------------------------------------------------
1443     // withDayOfYear()
1444     //-----------------------------------------------------------------------
1445     @Test
1446     public void test_withDayOfYear_normal() {
1447         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1448         ZonedDateTime test = base.withDayOfYear(33);
1449         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withDayOfYear(33), ZONE_0100));
1450     }
1451 
1452     @Test
1453     public void test_withDayOfYear_noChange() {
1454         LocalDateTime ldt = LocalDateTime.of(2008, 2, 5, 23, 30, 59, 0);
1455         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1456         ZonedDateTime test = base.withDayOfYear(36);
1457         assertEquals(test, base);
1458     }
1459 
1460     @Test(expectedExceptions=DateTimeException.class)
1461     public void test_withDayOfYear_tooBig() {
1462         TEST_DATE_TIME.withDayOfYear(367);
1463     }
1464 
1465     @Test(expectedExceptions=DateTimeException.class)
1466     public void test_withDayOfYear_tooSmall() {
1467         TEST_DATE_TIME.withDayOfYear(0);
1468     }
1469 
1470     @Test(expectedExceptions=DateTimeException.class)
1471     public void test_withDayOfYear_invalid366() {
1472         LocalDateTime.of(2007, 2, 2, 11, 30).atZone(ZONE_PARIS).withDayOfYear(366);
1473     }
1474 
1475     //-----------------------------------------------------------------------
1476     // withHour()
1477     //-----------------------------------------------------------------------
1478     @Test
1479     public void test_withHour_normal() {
1480         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1481         ZonedDateTime test = base.withHour(15);
1482         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withHour(15), ZONE_0100));
1483     }
1484 
1485     @Test
1486     public void test_withHour_noChange() {
1487         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1488         ZonedDateTime test = base.withHour(11);
1489         assertEquals(test, base);
1490     }
1491 
1492     //-----------------------------------------------------------------------
1493     // withMinute()
1494     //-----------------------------------------------------------------------
1495     @Test
1496     public void test_withMinute_normal() {
1497         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1498         ZonedDateTime test = base.withMinute(15);
1499         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withMinute(15), ZONE_0100));
1500     }
1501 
1502     @Test
1503     public void test_withMinute_noChange() {
1504         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1505         ZonedDateTime test = base.withMinute(30);
1506         assertEquals(test, base);
1507     }
1508 
1509     //-----------------------------------------------------------------------
1510     // withSecond()
1511     //-----------------------------------------------------------------------
1512     @Test
1513     public void test_withSecond_normal() {
1514         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1515         ZonedDateTime test = base.withSecond(12);
1516         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withSecond(12), ZONE_0100));
1517     }
1518 
1519     @Test
1520     public void test_withSecond_noChange() {
1521         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1522         ZonedDateTime test = base.withSecond(59);
1523         assertEquals(test, base);
1524     }
1525 
1526     //-----------------------------------------------------------------------
1527     // withNano()
1528     //-----------------------------------------------------------------------
1529     @Test
1530     public void test_withNanoOfSecond_normal() {
1531         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1532         ZonedDateTime test = base.withNano(15);
1533         assertEquals(test, ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500.withNano(15), ZONE_0100));
1534     }
1535 
1536     @Test
1537     public void test_withNanoOfSecond_noChange() {
1538         ZonedDateTime base = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
1539         ZonedDateTime test = base.withNano(500);
1540         assertEquals(test, base);
1541     }
1542 
1543     //-----------------------------------------------------------------------
1544     // truncatedTo(TemporalUnit)
1545     //-----------------------------------------------------------------------
1546     @Test
1547     public void test_truncatedTo_normal() {
1548         assertEquals(TEST_DATE_TIME.truncatedTo(NANOS), TEST_DATE_TIME);
1549         assertEquals(TEST_DATE_TIME.truncatedTo(SECONDS), TEST_DATE_TIME.withNano(0));
1550         assertEquals(TEST_DATE_TIME.truncatedTo(DAYS), TEST_DATE_TIME.with(LocalTime.MIDNIGHT));
1551     }
1552 
1553     @Test(expectedExceptions=NullPointerException.class)
1554     public void test_truncatedTo_null() {
1555         TEST_DATE_TIME.truncatedTo(null);
1556     }
1557 
1558     //-----------------------------------------------------------------------
1559     // plus/minus
1560     //-----------------------------------------------------------------------
1561     @DataProvider(name="plusDays")
1562     Object[][] data_plusDays() {
1563         return new Object[][] {
1564             // normal
1565             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 0, dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1566             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 1, dateTime(2008, 7, 1, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1567             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), -1, dateTime(2008, 6, 29, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1568             // skip over gap
1569             {dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 31, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1570             {dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 29, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1571             // land in gap
1572             {dateTime(2008, 3, 29, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1573             {dateTime(2008, 3, 31, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1574             // skip over overlap
1575             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 27, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1576             {dateTime(2008, 10, 25, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1577             // land in overlap
1578             {dateTime(2008, 10, 25, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1579             {dateTime(2008, 10, 27, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS), -1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1580         };
1581     }
1582 
1583     @DataProvider(name="plusTime")
1584     Object[][] data_plusTime() {
1585         return new Object[][] {
1586             // normal
1587             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 0, dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1588             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), 1, dateTime(2008, 7, 1, 0, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1589             {dateTime(2008, 6, 30, 23, 30, 59, 0, OFFSET_0100, ZONE_0100), -1, dateTime(2008, 6, 30, 22, 30, 59, 0, OFFSET_0100, ZONE_0100)},
1590             // gap
1591             {dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS), 1, dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1592             {dateTime(2008, 3, 30, 3, 30, 0, 0, OFFSET_0200, ZONE_PARIS), -1, dateTime(2008, 3, 30, 1, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1593             // overlap
1594             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS)},
1595             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 2, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1596             {dateTime(2008, 10, 26, 1, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 3, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1597             {dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 1, dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1598             {dateTime(2008, 10, 26, 2, 30, 0, 0, OFFSET_0200, ZONE_PARIS), 2, dateTime(2008, 10, 26, 3, 30, 0, 0, OFFSET_0100, ZONE_PARIS)},
1599         };
1600     }
1601 
1602     //-----------------------------------------------------------------------
1603     // plus(TemporalAmount)
1604     //-----------------------------------------------------------------------
1605     @Test(dataProvider="plusDays")
1606     public void test_plus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
1607         assertEquals(base.plus(Period.ofDays(amount)), expected);
1608     }
1609 
1610     @Test(dataProvider="plusTime")
1611     public void test_plus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1612         assertEquals(base.plus(MockSimplePeriod.of(amount, HOURS)), expected);
1613     }
1614 
1615     @Test(dataProvider="plusTime")
1616     public void test_plus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1617         assertEquals(base.plus(Duration.ofHours(amount)), expected);
1618     }
1619 
1620     @Test
1621     public void test_plus_TemporalAmount() {
1622         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1623         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1624         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2009, 1, 1, 12, 30, 59, 500), ZONE_0100);
1625         assertEquals(t.plus(period), expected);
1626     }
1627 
1628     @Test
1629     public void test_plus_TemporalAmount_Duration() {
1630         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
1631         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1632         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 16, 36, 5, 500), ZONE_0100);
1633         assertEquals(t.plus(duration), expected);
1634     }
1635 
1636     @Test
1637     public void test_plus_TemporalAmount_Period_zero() {
1638         ZonedDateTime t = TEST_DATE_TIME.plus(MockSimplePeriod.ZERO_DAYS);
1639         assertEquals(t, TEST_DATE_TIME);
1640     }
1641 
1642     @Test
1643     public void test_plus_TemporalAmount_Duration_zero() {
1644         ZonedDateTime t = TEST_DATE_TIME.plus(Duration.ZERO);
1645         assertEquals(t, TEST_DATE_TIME);
1646     }
1647 
1648     @Test(expectedExceptions=NullPointerException.class)
1649     public void test_plus_TemporalAmount_null() {
1650         TEST_DATE_TIME.plus((TemporalAmount) null);
1651     }
1652 
1653     //-----------------------------------------------------------------------
1654     // plus(long,TemporalUnit)
1655     //-----------------------------------------------------------------------
1656     @Test(dataProvider="plusDays")
1657     public void test_plus_longUnit_days(ZonedDateTime base, long amount, ZonedDateTime expected) {
1658         assertEquals(base.plus(amount, DAYS), expected);
1659     }
1660 
1661     @Test(dataProvider="plusTime")
1662     public void test_plus_longUnit_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1663         assertEquals(base.plus(amount, HOURS), expected);
1664     }
1665 
1666     @Test(dataProvider="plusTime")
1667     public void test_plus_longUnit_minutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1668         assertEquals(base.plus(amount * 60, MINUTES), expected);
1669     }
1670 
1671     @Test(dataProvider="plusTime")
1672     public void test_plus_longUnit_seconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1673         assertEquals(base.plus(amount * 3600, SECONDS), expected);
1674     }
1675 
1676     @Test(dataProvider="plusTime")
1677     public void test_plus_longUnit_nanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1678         assertEquals(base.plus(amount * 3600_000_000_000L, NANOS), expected);
1679     }
1680 
1681     @Test(expectedExceptions=NullPointerException.class)
1682     public void test_plus_longUnit_null() {
1683         TEST_DATE_TIME_PARIS.plus(0, null);
1684     }
1685 
1686     //-----------------------------------------------------------------------
1687     // plusYears()
1688     //-----------------------------------------------------------------------
1689     @Test
1690     public void test_plusYears() {
1691         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1692         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1693         ZonedDateTime test = base.plusYears(1);
1694         assertEquals(test, ZonedDateTime.of(ldt.plusYears(1), ZONE_0100));
1695     }
1696 
1697     @Test
1698     public void test_plusYears_zero() {
1699         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1700         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1701         ZonedDateTime test = base.plusYears(0);
1702         assertEquals(test, base);
1703     }
1704 
1705     //-----------------------------------------------------------------------
1706     // plusMonths()
1707     //-----------------------------------------------------------------------
1708     @Test
1709     public void test_plusMonths() {
1710         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1711         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1712         ZonedDateTime test = base.plusMonths(1);
1713         assertEquals(test, ZonedDateTime.of(ldt.plusMonths(1), ZONE_0100));
1714     }
1715 
1716     @Test
1717     public void test_plusMonths_zero() {
1718         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1719         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1720         ZonedDateTime test = base.plusMonths(0);
1721         assertEquals(test, base);
1722     }
1723 
1724     //-----------------------------------------------------------------------
1725     // plusWeeks()
1726     //-----------------------------------------------------------------------
1727     @Test
1728     public void test_plusWeeks() {
1729         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1730         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1731         ZonedDateTime test = base.plusWeeks(1);
1732         assertEquals(test, ZonedDateTime.of(ldt.plusWeeks(1), ZONE_0100));
1733     }
1734 
1735     @Test
1736     public void test_plusWeeks_zero() {
1737         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1738         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1739         ZonedDateTime test = base.plusWeeks(0);
1740         assertEquals(test, base);
1741     }
1742 
1743     //-----------------------------------------------------------------------
1744     // plusDays()
1745     //-----------------------------------------------------------------------
1746     @Test(dataProvider="plusDays")
1747     public void test_plusDays(ZonedDateTime base, long amount, ZonedDateTime expected) {
1748         assertEquals(base.plusDays(amount), expected);
1749     }
1750 
1751     //-----------------------------------------------------------------------
1752     // plusHours()
1753     //-----------------------------------------------------------------------
1754     @Test(dataProvider="plusTime")
1755     public void test_plusHours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1756         assertEquals(base.plusHours(amount), expected);
1757     }
1758 
1759     //-----------------------------------------------------------------------
1760     // plusMinutes()
1761     //-----------------------------------------------------------------------
1762     @Test(dataProvider="plusTime")
1763     public void test_plusMinutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1764         assertEquals(base.plusMinutes(amount * 60), expected);
1765     }
1766 
1767     @Test
1768     public void test_plusMinutes_minutes() {
1769         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1770         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1771         ZonedDateTime test = base.plusMinutes(30);
1772         assertEquals(test, ZonedDateTime.of(ldt.plusMinutes(30), ZONE_0100));
1773     }
1774 
1775     //-----------------------------------------------------------------------
1776     // plusSeconds()
1777     //-----------------------------------------------------------------------
1778     @Test(dataProvider="plusTime")
1779     public void test_plusSeconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1780         assertEquals(base.plusSeconds(amount * 3600), expected);
1781     }
1782 
1783     @Test
1784     public void test_plusSeconds_seconds() {
1785         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1786         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1787         ZonedDateTime test = base.plusSeconds(1);
1788         assertEquals(test, ZonedDateTime.of(ldt.plusSeconds(1), ZONE_0100));
1789     }
1790 
1791     //-----------------------------------------------------------------------
1792     // plusNanos()
1793     //-----------------------------------------------------------------------
1794     @Test(dataProvider="plusTime")
1795     public void test_plusNanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1796         assertEquals(base.plusNanos(amount * 3600_000_000_000L), expected);
1797     }
1798 
1799     @Test
1800     public void test_plusNanos_nanos() {
1801         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1802         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1803         ZonedDateTime test = base.plusNanos(1);
1804         assertEquals(test, ZonedDateTime.of(ldt.plusNanos(1), ZONE_0100));
1805     }
1806 
1807     //-----------------------------------------------------------------------
1808     // minus(TemporalAmount)
1809     //-----------------------------------------------------------------------
1810     @Test(dataProvider="plusDays")
1811     public void test_minus_TemporalAmount_Period_days(ZonedDateTime base, int amount, ZonedDateTime expected) {
1812         assertEquals(base.minus(Period.ofDays(-amount)), expected);
1813     }
1814 
1815     @Test(dataProvider="plusTime")
1816     public void test_minus_TemporalAmount_Period_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1817         assertEquals(base.minus(MockSimplePeriod.of(-amount, HOURS)), expected);
1818     }
1819 
1820     @Test(dataProvider="plusTime")
1821     public void test_minus_TemporalAmount_Duration_hours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1822         assertEquals(base.minus(Duration.ofHours(-amount)), expected);
1823     }
1824 
1825     @Test
1826     public void test_minus_TemporalAmount() {
1827         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1828         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1829         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2007, 11, 1, 12, 30, 59, 500), ZONE_0100);
1830         assertEquals(t.minus(period), expected);
1831     }
1832 
1833     @Test
1834     public void test_minus_TemporalAmount_Duration() {
1835         Duration duration = Duration.ofSeconds(4L * 60 * 60 + 5L * 60 + 6L);
1836         ZonedDateTime t = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 12, 30, 59, 500), ZONE_0100);
1837         ZonedDateTime expected = ZonedDateTime.of(LocalDateTime.of(2008, 6, 1, 8, 25, 53, 500), ZONE_0100);
1838         assertEquals(t.minus(duration), expected);
1839     }
1840 
1841     @Test
1842     public void test_minus_TemporalAmount_Period_zero() {
1843         ZonedDateTime t = TEST_DATE_TIME.minus(MockSimplePeriod.ZERO_DAYS);
1844         assertEquals(t, TEST_DATE_TIME);
1845     }
1846 
1847     @Test
1848     public void test_minus_TemporalAmount_Duration_zero() {
1849         ZonedDateTime t = TEST_DATE_TIME.minus(Duration.ZERO);
1850         assertEquals(t, TEST_DATE_TIME);
1851     }
1852 
1853     @Test(expectedExceptions=NullPointerException.class)
1854     public void test_minus_TemporalAmount_null() {
1855         TEST_DATE_TIME.minus((TemporalAmount) null);
1856     }
1857 
1858     //-----------------------------------------------------------------------
1859     // minusYears()
1860     //-----------------------------------------------------------------------
1861     @Test
1862     public void test_minusYears() {
1863         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1864         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1865         ZonedDateTime test = base.minusYears(1);
1866         assertEquals(test, ZonedDateTime.of(ldt.minusYears(1), ZONE_0100));
1867     }
1868 
1869     @Test
1870     public void test_minusYears_zero() {
1871         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1872         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1873         ZonedDateTime test = base.minusYears(0);
1874         assertEquals(test, base);
1875     }
1876 
1877     //-----------------------------------------------------------------------
1878     // minusMonths()
1879     //-----------------------------------------------------------------------
1880     @Test
1881     public void test_minusMonths() {
1882         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1883         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1884         ZonedDateTime test = base.minusMonths(1);
1885         assertEquals(test, ZonedDateTime.of(ldt.minusMonths(1), ZONE_0100));
1886     }
1887 
1888     @Test
1889     public void test_minusMonths_zero() {
1890         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1891         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1892         ZonedDateTime test = base.minusMonths(0);
1893         assertEquals(test, base);
1894     }
1895 
1896     //-----------------------------------------------------------------------
1897     // minusWeeks()
1898     //-----------------------------------------------------------------------
1899     @Test
1900     public void test_minusWeeks() {
1901         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1902         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1903         ZonedDateTime test = base.minusWeeks(1);
1904         assertEquals(test, ZonedDateTime.of(ldt.minusWeeks(1), ZONE_0100));
1905     }
1906 
1907     @Test
1908     public void test_minusWeeks_zero() {
1909         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1910         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1911         ZonedDateTime test = base.minusWeeks(0);
1912         assertEquals(test, base);
1913     }
1914 
1915     //-----------------------------------------------------------------------
1916     // minusDays()
1917     //-----------------------------------------------------------------------
1918     @Test(dataProvider="plusDays")
1919     public void test_minusDays(ZonedDateTime base, long amount, ZonedDateTime expected) {
1920         assertEquals(base.minusDays(-amount), expected);
1921     }
1922 
1923     //-----------------------------------------------------------------------
1924     // minusHours()
1925     //-----------------------------------------------------------------------
1926     @Test(dataProvider="plusTime")
1927     public void test_minusHours(ZonedDateTime base, long amount, ZonedDateTime expected) {
1928         assertEquals(base.minusHours(-amount), expected);
1929     }
1930 
1931     //-----------------------------------------------------------------------
1932     // minusMinutes()
1933     //-----------------------------------------------------------------------
1934     @Test(dataProvider="plusTime")
1935     public void test_minusMinutes(ZonedDateTime base, long amount, ZonedDateTime expected) {
1936         assertEquals(base.minusMinutes(-amount * 60), expected);
1937     }
1938 
1939     @Test
1940     public void test_minusMinutes_minutes() {
1941         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1942         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1943         ZonedDateTime test = base.minusMinutes(30);
1944         assertEquals(test, ZonedDateTime.of(ldt.minusMinutes(30), ZONE_0100));
1945     }
1946 
1947     //-----------------------------------------------------------------------
1948     // minusSeconds()
1949     //-----------------------------------------------------------------------
1950     @Test(dataProvider="plusTime")
1951     public void test_minusSeconds(ZonedDateTime base, long amount, ZonedDateTime expected) {
1952         assertEquals(base.minusSeconds(-amount * 3600), expected);
1953     }
1954 
1955     @Test
1956     public void test_minusSeconds_seconds() {
1957         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1958         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1959         ZonedDateTime test = base.minusSeconds(1);
1960         assertEquals(test, ZonedDateTime.of(ldt.minusSeconds(1), ZONE_0100));
1961     }
1962 
1963     //-----------------------------------------------------------------------
1964     // minusNanos()
1965     //-----------------------------------------------------------------------
1966     @Test(dataProvider="plusTime")
1967     public void test_minusNanos(ZonedDateTime base, long amount, ZonedDateTime expected) {
1968         assertEquals(base.minusNanos(-amount * 3600_000_000_000L), expected);
1969     }
1970 
1971     @Test
1972     public void test_minusNanos_nanos() {
1973         LocalDateTime ldt = LocalDateTime.of(2008, 6, 30, 23, 30, 59, 0);
1974         ZonedDateTime base = ZonedDateTime.of(ldt, ZONE_0100);
1975         ZonedDateTime test = base.minusNanos(1);
1976         assertEquals(test, ZonedDateTime.of(ldt.minusNanos(1), ZONE_0100));
1977     }
1978 
1979     //-----------------------------------------------------------------------
1980     // periodUntil(Temporal,TemporalUnit)
1981     //-----------------------------------------------------------------------
1982     // TODO: more tests for period between two different zones
1983     // compare results to OffsetDateTime.periodUntil, especially wrt dates
1984 
1985     @Test(dataProvider="plusDays")
1986     public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) {
1987         if (base.toLocalTime().equals(end.toLocalTime()) == false) {
1988             return;  // avoid DST gap input values
1989         }
1990         assertEquals(base.periodUntil(end, DAYS), expected);
1991     }
1992 
1993     @Test(dataProvider="plusTime")
1994     public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) {
1995         assertEquals(base.periodUntil(end, HOURS), expected);
1996     }
1997 
1998     @Test(dataProvider="plusTime")
1999     public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) {
2000         assertEquals(base.periodUntil(end, MINUTES), expected * 60);
2001     }
2002 
2003     @Test(dataProvider="plusTime")
2004     public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) {
2005         assertEquals(base.periodUntil(end, SECONDS), expected * 3600);
2006     }
2007 
2008     @Test(dataProvider="plusTime")
2009     public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) {
2010         assertEquals(base.periodUntil(end, NANOS), expected * 3600_000_000_000L);
2011     }
2012 
2013     @Test
2014     public void test_periodUntil_parisLondon() {
2015         ZonedDateTime midnightLondon = LocalDate.of(2012, 6, 28).atStartOfDay(ZONE_LONDON);
2016         ZonedDateTime midnightParis1 = LocalDate.of(2012, 6, 29).atStartOfDay(ZONE_PARIS);
2017         ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS);
2018         ZonedDateTime midnightParis2 = LocalDate.of(2012, 6, 30).atStartOfDay(ZONE_PARIS);
2019 
2020         assertEquals(midnightLondon.periodUntil(midnightParis1, HOURS), 23);
2021         assertEquals(midnightLondon.periodUntil(oneAm1, HOURS), 24);
2022         assertEquals(midnightLondon.periodUntil(midnightParis2, HOURS), 23 + 24);
2023 
2024         assertEquals(midnightLondon.periodUntil(midnightParis1, DAYS), 0);
2025         assertEquals(midnightLondon.periodUntil(oneAm1, DAYS), 1);
2026         assertEquals(midnightLondon.periodUntil(midnightParis2, DAYS), 1);
2027     }
2028 
2029     @Test
2030     public void test_periodUntil_gap() {
2031         ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
2032         ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
2033 
2034         assertEquals(before.periodUntil(after, HOURS), 23);
2035         assertEquals(before.periodUntil(after, DAYS), 1);
2036     }
2037 
2038     @Test
2039     public void test_periodUntil_overlap() {
2040         ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
2041         ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
2042 
2043         assertEquals(before.periodUntil(after, HOURS), 25);
2044         assertEquals(before.periodUntil(after, DAYS), 1);
2045     }
2046 
2047     @Test(expectedExceptions=DateTimeException.class)
2048     public void test_periodUntil_differentType() {
2049         TEST_DATE_TIME_PARIS.periodUntil(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS);
2050     }
2051 
2052     @Test(expectedExceptions=NullPointerException.class)
2053     public void test_periodUntil_nullTemporal() {
2054         TEST_DATE_TIME_PARIS.periodUntil(null, DAYS);
2055     }
2056 
2057     @Test(expectedExceptions=NullPointerException.class)
2058     public void test_periodUntil_nullUnit() {
2059         TEST_DATE_TIME_PARIS.periodUntil(TEST_DATE_TIME_PARIS, null);
2060     }
2061 
2062     //-----------------------------------------------------------------------
2063     // format(DateTimeFormatter)
2064     //-----------------------------------------------------------------------
2065     @Test
2066     public void test_format_formatter() {
2067         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
2068         String t = ZonedDateTime.of(dateTime(2010, 12, 3, 11, 30), ZONE_PARIS).format(f);
2069         assertEquals(t, "2010 12 3 11 30 0");
2070     }
2071 
2072     @Test(expectedExceptions=NullPointerException.class)
2073     public void test_format_formatter_null() {
2074         ZonedDateTime.of(dateTime(2010, 12, 3, 11, 30), ZONE_PARIS).format(null);
2075     }
2076 
2077     //-----------------------------------------------------------------------
2078     // toOffsetDateTime()
2079     //-----------------------------------------------------------------------
2080     @Test
2081     public void test_toOffsetDateTime() {
2082         assertEquals(TEST_DATE_TIME.toOffsetDateTime(), OffsetDateTime.of(TEST_DATE_TIME.toLocalDateTime(), TEST_DATE_TIME.getOffset()));
2083     }
2084 
2085     //-----------------------------------------------------------------------
2086     // toInstant()
2087     //-----------------------------------------------------------------------
2088     @DataProvider(name="toInstant")
2089     Object[][] data_toInstant() {
2090         return new Object[][] {
2091             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0), 0L, 0},
2092             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 1), 0L, 1},
2093             {LocalDateTime.of(1970, 1, 1, 0, 0, 0, 999_999_999), 0L, 999_999_999},
2094             {LocalDateTime.of(1970, 1, 1, 0, 0, 1, 0), 1L, 0},
2095             {LocalDateTime.of(1970, 1, 1, 0, 0, 1, 1), 1L, 1},
2096             {LocalDateTime.of(1969, 12, 31, 23, 59, 59, 999999999), -1L, 999_999_999},
2097             {LocalDateTime.of(1970, 1, 2, 0, 0), 24L * 60L * 60L, 0},
2098             {LocalDateTime.of(1969, 12, 31, 0, 0), -24L * 60L * 60L, 0},
2099         };
2100     }
2101 
2102     @Test(dataProvider="toInstant")
2103     public void test_toInstant_UTC(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2104         ZonedDateTime dt = ldt.atZone(ZoneOffset.UTC);
2105         Instant test = dt.toInstant();
2106         assertEquals(test.getEpochSecond(), expectedEpSec);
2107         assertEquals(test.getNano(), expectedNos);
2108     }
2109 
2110     @Test(dataProvider="toInstant")
2111     public void test_toInstant_P0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2112         ZonedDateTime dt = ldt.atZone(ZONE_0100);
2113         Instant test = dt.toInstant();
2114         assertEquals(test.getEpochSecond(), expectedEpSec - 3600);
2115         assertEquals(test.getNano(), expectedNos);
2116     }
2117 
2118     @Test(dataProvider="toInstant")
2119     public void test_toInstant_M0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2120         ZonedDateTime dt = ldt.atZone(ZONE_M0100);
2121         Instant test = dt.toInstant();
2122         assertEquals(test.getEpochSecond(), expectedEpSec + 3600);
2123         assertEquals(test.getNano(), expectedNos);
2124     }
2125 
2126     //-----------------------------------------------------------------------
2127     // toEpochSecond()
2128     //-----------------------------------------------------------------------
2129     @Test
2130     public void test_toEpochSecond_afterEpoch() {
2131         LocalDateTime ldt = LocalDateTime.of(1970, 1, 1, 0, 0).plusHours(1);
2132         for (int i = 0; i < 100000; i++) {
2133             ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_PARIS);
2134             assertEquals(a.toEpochSecond(), i);
2135             ldt = ldt.plusSeconds(1);
2136         }
2137     }
2138 
2139     @Test
2140     public void test_toEpochSecond_beforeEpoch() {
2141         LocalDateTime ldt = LocalDateTime.of(1970, 1, 1, 0, 0).plusHours(1);
2142         for (int i = 0; i < 100000; i++) {
2143             ZonedDateTime a = ZonedDateTime.of(ldt, ZONE_PARIS);
2144             assertEquals(a.toEpochSecond(), -i);
2145             ldt = ldt.minusSeconds(1);
2146         }
2147     }
2148 
2149     @Test(dataProvider="toInstant")
2150     public void test_toEpochSecond_UTC(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2151         ZonedDateTime dt = ldt.atZone(ZoneOffset.UTC);
2152         assertEquals(dt.toEpochSecond(), expectedEpSec);
2153     }
2154 
2155     @Test(dataProvider="toInstant")
2156     public void test_toEpochSecond_P0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2157         ZonedDateTime dt = ldt.atZone(ZONE_0100);
2158         assertEquals(dt.toEpochSecond(), expectedEpSec - 3600);
2159     }
2160 
2161     @Test(dataProvider="toInstant")
2162     public void test_toEpochSecond_M0100(LocalDateTime ldt, long expectedEpSec, int expectedNos) {
2163         ZonedDateTime dt = ldt.atZone(ZONE_M0100);
2164         assertEquals(dt.toEpochSecond(), expectedEpSec + 3600);
2165     }
2166 
2167     //-----------------------------------------------------------------------
2168     // compareTo()
2169     //-----------------------------------------------------------------------
2170     @Test
2171     public void test_compareTo_time1() {
2172         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);
2173         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0100);  // a is before b due to time
2174         assertEquals(a.compareTo(b) < 0, true);
2175         assertEquals(b.compareTo(a) > 0, true);
2176         assertEquals(a.compareTo(a) == 0, true);
2177         assertEquals(b.compareTo(b) == 0, true);
2178     }
2179 
2180     @Test
2181     public void test_compareTo_time2() {
2182         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);
2183         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZONE_0100);  // a is before b due to time
2184         assertEquals(a.compareTo(b) < 0, true);
2185         assertEquals(b.compareTo(a) > 0, true);
2186         assertEquals(a.compareTo(a) == 0, true);
2187         assertEquals(b.compareTo(b) == 0, true);
2188     }
2189 
2190     @Test
2191     public void test_compareTo_offset1() {
2192         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 41, 0, ZONE_0200);
2193         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 39, 0, ZONE_0100);  // a is before b due to offset
2194         assertEquals(a.compareTo(b) < 0, true);
2195         assertEquals(b.compareTo(a) > 0, true);
2196         assertEquals(a.compareTo(a) == 0, true);
2197         assertEquals(b.compareTo(b) == 0, true);
2198     }
2199 
2200     @Test
2201     public void test_compareTo_offset2() {
2202         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 5, ZoneId.of("UTC+01:01"));
2203         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 30, 40, 4, ZONE_0100);  // a is before b due to offset
2204         assertEquals(a.compareTo(b) < 0, true);
2205         assertEquals(b.compareTo(a) > 0, true);
2206         assertEquals(a.compareTo(a) == 0, true);
2207         assertEquals(b.compareTo(b) == 0, true);
2208     }
2209 
2210     @Test
2211     public void test_compareTo_both() {
2212         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 50, 0, 0, ZONE_0200);
2213         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 20, 0, 0, ZONE_0100);  // a is before b on instant scale
2214         assertEquals(a.compareTo(b) < 0, true);
2215         assertEquals(b.compareTo(a) > 0, true);
2216         assertEquals(a.compareTo(a) == 0, true);
2217         assertEquals(b.compareTo(b) == 0, true);
2218     }
2219 
2220     @Test
2221     public void test_compareTo_bothNanos() {
2222         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 11, 20, 40, 5, ZONE_0200);
2223         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 10, 20, 40, 6, ZONE_0100);  // a is before b on instant scale
2224         assertEquals(a.compareTo(b) < 0, true);
2225         assertEquals(b.compareTo(a) > 0, true);
2226         assertEquals(a.compareTo(a) == 0, true);
2227         assertEquals(b.compareTo(b) == 0, true);
2228     }
2229 
2230     @Test
2231     public void test_compareTo_hourDifference() {
2232         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 10, 0, 0, 0, ZONE_0100);
2233         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, 11, 0, 0, 0, ZONE_0200);  // a is before b despite being same time-line time
2234         assertEquals(a.compareTo(b) < 0, true);
2235         assertEquals(b.compareTo(a) > 0, true);
2236         assertEquals(a.compareTo(a) == 0, true);
2237         assertEquals(b.compareTo(b) == 0, true);
2238     }
2239 
2240     @Test(expectedExceptions=NullPointerException.class)
2241     public void test_compareTo_null() {
2242         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2243         a.compareTo(null);
2244     }
2245 
2246     //-----------------------------------------------------------------------
2247     // isBefore()
2248     //-----------------------------------------------------------------------
2249     @DataProvider(name="IsBefore")
2250     Object[][] data_isBefore() {
2251         return new Object[][] {
2252             {11, 30, ZONE_0100, 11, 31, ZONE_0100, true}, // a is before b due to time
2253             {11, 30, ZONE_0200, 11, 30, ZONE_0100, true}, // a is before b due to offset
2254             {11, 30, ZONE_0200, 10, 30, ZONE_0100, false}, // a is equal b due to same instant
2255         };
2256     }
2257 
2258     @Test(dataProvider="IsBefore")
2259     public void test_isBefore(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
2260         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
2261         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
2262         assertEquals(a.isBefore(b), expected);
2263         assertEquals(b.isBefore(a), false);
2264         assertEquals(a.isBefore(a), false);
2265         assertEquals(b.isBefore(b), false);
2266     }
2267 
2268     @Test(expectedExceptions=NullPointerException.class)
2269     public void test_isBefore_null() {
2270         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2271         a.isBefore(null);
2272     }
2273 
2274     //-----------------------------------------------------------------------
2275     // isAfter()
2276     //-----------------------------------------------------------------------
2277     @DataProvider(name="IsAfter")
2278     Object[][] data_isAfter() {
2279         return new Object[][] {
2280             {11, 31, ZONE_0100, 11, 30, ZONE_0100, true}, // a is after b due to time
2281             {11, 30, ZONE_0100, 11, 30, ZONE_0200, true}, // a is after b due to offset
2282             {11, 30, ZONE_0200, 10, 30, ZONE_0100, false}, // a is equal b due to same instant
2283         };
2284     }
2285 
2286     @Test(dataProvider="IsAfter")
2287     public void test_isAfter(int hour1, int minute1, ZoneId zone1, int hour2, int minute2, ZoneId zone2, boolean expected) {
2288         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, hour1, minute1, 0, 0, zone1);
2289         ZonedDateTime b = ZonedDateTime.of(2008, 6, 30, hour2, minute2, 0, 0, zone2);
2290         assertEquals(a.isAfter(b), expected);
2291         assertEquals(b.isAfter(a), false);
2292         assertEquals(a.isAfter(a), false);
2293         assertEquals(b.isAfter(b), false);
2294     }
2295 
2296     @Test(expectedExceptions=NullPointerException.class)
2297     public void test_isAfter_null() {
2298         ZonedDateTime a = ZonedDateTime.of(2008, 6, 30, 23, 30, 59, 0, ZONE_0100);
2299         a.isAfter(null);
2300     }
2301 
2302     //-----------------------------------------------------------------------
2303     // equals() / hashCode()
2304     //-----------------------------------------------------------------------
2305     @Test(dataProvider="sampleTimes")
2306     public void test_equals_true(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2307         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2308         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2309         assertEquals(a.equals(b), true);
2310         assertEquals(a.hashCode() == b.hashCode(), true);
2311     }
2312     @Test(dataProvider="sampleTimes")
2313     public void test_equals_false_year_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2314         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2315         ZonedDateTime b = ZonedDateTime.of(dateTime(y + 1, o, d, h, m, s, n), ZONE_0100);
2316         assertEquals(a.equals(b), false);
2317     }
2318     @Test(dataProvider="sampleTimes")
2319     public void test_equals_false_hour_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2320         h = (h == 23 ? 22 : h);
2321         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2322         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h + 1, m, s, n), ZONE_0100);
2323         assertEquals(a.equals(b), false);
2324     }
2325     @Test(dataProvider="sampleTimes")
2326     public void test_equals_false_minute_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2327         m = (m == 59 ? 58 : m);
2328         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2329         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m + 1, s, n), ZONE_0100);
2330         assertEquals(a.equals(b), false);
2331     }
2332     @Test(dataProvider="sampleTimes")
2333     public void test_equals_false_second_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2334         s = (s == 59 ? 58 : s);
2335         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2336         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s + 1, n), ZONE_0100);
2337         assertEquals(a.equals(b), false);
2338     }
2339     @Test(dataProvider="sampleTimes")
2340     public void test_equals_false_nano_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2341         n = (n == 999999999 ? 999999998 : n);
2342         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2343         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n + 1), ZONE_0100);
2344         assertEquals(a.equals(b), false);
2345     }
2346     @Test(dataProvider="sampleTimes")
2347     public void test_equals_false_offset_differs(int y, int o, int d, int h, int m, int s, int n, ZoneId ignored) {
2348         ZonedDateTime a = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0100);
2349         ZonedDateTime b = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZONE_0200);
2350         assertEquals(a.equals(b), false);
2351     }
2352 
2353     @Test
2354     public void test_equals_itself_true() {
2355         assertEquals(TEST_DATE_TIME.equals(TEST_DATE_TIME), true);
2356     }
2357 
2358     @Test
2359     public void test_equals_string_false() {
2360         assertEquals(TEST_DATE_TIME.equals("2007-07-15"), false);
2361     }
2362 
2363     //-----------------------------------------------------------------------
2364     // toString()
2365     //-----------------------------------------------------------------------
2366     @DataProvider(name="sampleToString")
2367     Object[][] provider_sampleToString() {
2368         return new Object[][] {
2369             {2008, 6, 30, 11, 30, 59, 0, "Z", "2008-06-30T11:30:59Z"},
2370             {2008, 6, 30, 11, 30, 59, 0, "+01:00", "2008-06-30T11:30:59+01:00"},
2371             {2008, 6, 30, 11, 30, 59, 999000000, "Z", "2008-06-30T11:30:59.999Z"},
2372             {2008, 6, 30, 11, 30, 59, 999000000, "+01:00", "2008-06-30T11:30:59.999+01:00"},
2373             {2008, 6, 30, 11, 30, 59, 999000, "Z", "2008-06-30T11:30:59.000999Z"},
2374             {2008, 6, 30, 11, 30, 59, 999000, "+01:00", "2008-06-30T11:30:59.000999+01:00"},
2375             {2008, 6, 30, 11, 30, 59, 999, "Z", "2008-06-30T11:30:59.000000999Z"},
2376             {2008, 6, 30, 11, 30, 59, 999, "+01:00", "2008-06-30T11:30:59.000000999+01:00"},
2377 
2378             {2008, 6, 30, 11, 30, 59, 999, "Europe/London", "2008-06-30T11:30:59.000000999+01:00[Europe/London]"},
2379             {2008, 6, 30, 11, 30, 59, 999, "Europe/Paris", "2008-06-30T11:30:59.000000999+02:00[Europe/Paris]"},
2380         };
2381     }
2382 
2383     @Test(dataProvider="sampleToString")
2384     public void test_toString(int y, int o, int d, int h, int m, int s, int n, String zoneId, String expected) {
2385         ZonedDateTime t = ZonedDateTime.of(dateTime(y, o, d, h, m, s, n), ZoneId.of(zoneId));
2386         String str = t.toString();
2387         assertEquals(str, expected);
2388     }
2389 
2390     //-------------------------------------------------------------------------
2391     private static LocalDateTime dateTime(
2392             int year, int month, int dayOfMonth,
2393             int hour, int minute) {
2394         return LocalDateTime.of(year, month, dayOfMonth, hour, minute);
2395     }
2396 
2397     private static LocalDateTime dateTime(
2398                     int year, int month, int dayOfMonth,
2399                     int hour, int minute, int second, int nanoOfSecond) {
2400                 return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
2401             }
2402 
2403     private static ZonedDateTime dateTime(
2404             int year, int month, int dayOfMonth,
2405             int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset, ZoneId zoneId) {
2406         return ZonedDateTime.ofStrict(LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond), offset, zoneId);
2407     }
2408 
2409 }