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
setUp()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
samples()174     protected List<TemporalAccessor> samples() {
175         TemporalAccessor[] array = {TEST_DATE_TIME, };
176         return Arrays.asList(array);
177     }
178 
179     @Override
validFields()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
invalidFields()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
now()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 }
2429