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