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