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