1 /*
2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * This file is available under and governed by the GNU General Public
26  * License version 2 only, as published by the Free Software Foundation.
27  * However, the following notice accompanied the original version of this
28  * file:
29  *
30  * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
31  *
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions are met:
36  *
37  *  * Redistributions of source code must retain the above copyright notice,
38  *    this list of conditions and the following disclaimer.
39  *
40  *  * Redistributions in binary form must reproduce the above copyright notice,
41  *    this list of conditions and the following disclaimer in the documentation
42  *    and/or other materials provided with the distribution.
43  *
44  *  * Neither the name of JSR-310 nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  */
60 package tck.java.time.format;
61 
62 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
63 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
64 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
65 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
66 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
67 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
68 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
69 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
70 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
71 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
72 import static java.time.temporal.ChronoField.YEAR;
73 import static org.testng.Assert.assertEquals;
74 import static org.testng.Assert.assertTrue;
75 import static org.testng.Assert.fail;
76 
77 import java.text.ParsePosition;
78 import java.time.DateTimeException;
79 import java.time.LocalDate;
80 import java.time.LocalDateTime;
81 import java.time.Month;
82 import java.time.Year;
83 import java.time.YearMonth;
84 import java.time.ZoneId;
85 import java.time.ZoneOffset;
86 import java.time.ZonedDateTime;
87 import java.time.chrono.Chronology;
88 import java.time.chrono.IsoChronology;
89 import java.time.format.DateTimeFormatter;
90 import java.time.format.DateTimeParseException;
91 import java.time.format.FormatStyle;
92 import java.time.format.ResolverStyle;
93 import java.time.format.TextStyle;
94 import java.time.temporal.IsoFields;
95 import java.time.temporal.TemporalAccessor;
96 import java.time.temporal.TemporalField;
97 import java.time.temporal.TemporalQueries;
98 import java.time.temporal.TemporalQuery;
99 import java.util.HashMap;
100 import java.util.Iterator;
101 import java.util.Locale;
102 import java.util.Map;
103 
104 import org.testng.annotations.BeforeMethod;
105 import org.testng.annotations.DataProvider;
106 import org.testng.annotations.Test;
107 
108 /**
109  * Test DateTimeFormatter.
110  */
111 @Test
112 public class TCKDateTimeFormatters {
113 
114     @BeforeMethod
setUp()115     public void setUp() {
116     }
117 
118     //-----------------------------------------------------------------------
119     @Test(expectedExceptions=NullPointerException.class)
test_format_nullTemporalAccessor()120     public void test_format_nullTemporalAccessor() {
121         DateTimeFormatter.ISO_DATE.format((TemporalAccessor) null);
122     }
123 
124     //-----------------------------------------------------------------------
125     //-----------------------------------------------------------------------
126     //-----------------------------------------------------------------------
127     @Test
test_pattern_String()128     public void test_pattern_String() {
129         DateTimeFormatter test = DateTimeFormatter.ofPattern("d MMM yyyy");
130         Locale fmtLocale = Locale.getDefault(Locale.Category.FORMAT);
131         assertEquals(test.format(LocalDate.of(2012, 6, 30)), "30 " +
132                 Month.JUNE.getDisplayName(TextStyle.SHORT, fmtLocale) + " 2012");
133         assertEquals(test.getLocale(), fmtLocale, "Locale.Category.FORMAT");
134     }
135 
136     @Test(expectedExceptions=IllegalArgumentException.class)
test_pattern_String_invalid()137     public void test_pattern_String_invalid() {
138         DateTimeFormatter.ofPattern("p");
139     }
140 
141     @Test(expectedExceptions=NullPointerException.class)
test_pattern_String_null()142     public void test_pattern_String_null() {
143         DateTimeFormatter.ofPattern(null);
144     }
145 
146     //-----------------------------------------------------------------------
147     //-----------------------------------------------------------------------
148     //-----------------------------------------------------------------------
149     @Test
test_pattern_StringLocale()150     public void test_pattern_StringLocale() {
151         DateTimeFormatter test = DateTimeFormatter.ofPattern("d MMM yyyy", Locale.UK);
152         assertEquals(test.format(LocalDate.of(2012, 6, 30)), "30 Jun 2012");
153         assertEquals(test.getLocale(), Locale.UK);
154     }
155 
156     @Test(expectedExceptions=IllegalArgumentException.class)
test_pattern_StringLocale_invalid()157     public void test_pattern_StringLocale_invalid() {
158         DateTimeFormatter.ofPattern("p", Locale.UK);
159     }
160 
161     @Test(expectedExceptions=NullPointerException.class)
test_pattern_StringLocale_nullPattern()162     public void test_pattern_StringLocale_nullPattern() {
163         DateTimeFormatter.ofPattern(null, Locale.UK);
164     }
165 
166     @Test(expectedExceptions=NullPointerException.class)
test_pattern_StringLocale_nullLocale()167     public void test_pattern_StringLocale_nullLocale() {
168         DateTimeFormatter.ofPattern("yyyy", null);
169     }
170 
171     //-----------------------------------------------------------------------
172     //-----------------------------------------------------------------------
173     //-----------------------------------------------------------------------
174     @Test
test_ofLocalizedDate_basics()175     public void test_ofLocalizedDate_basics() {
176         assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
177         assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getZone(), null);
178         assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
179     }
180 
181     @Test
test_ofLocalizedTime_basics()182     public void test_ofLocalizedTime_basics() {
183         assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
184         assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getZone(), null);
185         assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
186     }
187 
188     @Test
test_ofLocalizedDateTime1_basics()189     public void test_ofLocalizedDateTime1_basics() {
190         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
191         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getZone(), null);
192         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
193     }
194 
195     @Test
test_ofLocalizedDateTime2_basics()196     public void test_ofLocalizedDateTime2_basics() {
197         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getChronology(), IsoChronology.INSTANCE);
198         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getZone(), null);
199         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getResolverStyle(), ResolverStyle.SMART);
200     }
201 
202     //-----------------------------------------------------------------------
203     //-----------------------------------------------------------------------
204     //-----------------------------------------------------------------------
205     @DataProvider(name="sample_isoLocalDate")
provider_sample_isoLocalDate()206     Object[][] provider_sample_isoLocalDate() {
207         return new Object[][]{
208                 {2008, null, null, null, null, null, DateTimeException.class},
209                 {null, 6, null, null, null, null, DateTimeException.class},
210                 {null, null, 30, null, null, null, DateTimeException.class},
211                 {null, null, null, "+01:00", null, null, DateTimeException.class},
212                 {null, null, null, null, "Europe/Paris", null, DateTimeException.class},
213                 {2008, 6, null, null, null, null, DateTimeException.class},
214                 {null, 6, 30, null, null, null, DateTimeException.class},
215 
216                 {2008, 6, 30, null, null,                   "2008-06-30", null},
217                 {2008, 6, 30, "+01:00", null,               "2008-06-30", null},
218                 {2008, 6, 30, "+01:00", "Europe/Paris",     "2008-06-30", null},
219                 {2008, 6, 30, null, "Europe/Paris",         "2008-06-30", null},
220 
221                 {123456, 6, 30, null, null,                 "+123456-06-30", null},
222         };
223     }
224 
225     @Test(dataProvider="sample_isoLocalDate")
test_print_isoLocalDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String expected, Class<?> expectedEx)226     public void test_print_isoLocalDate(
227             Integer year, Integer month, Integer day, String offsetId, String zoneId,
228             String expected, Class<?> expectedEx) {
229         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
230         if (expectedEx == null) {
231             assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.format(test), expected);
232         } else {
233             try {
234                 DateTimeFormatter.ISO_LOCAL_DATE.format(test);
235                 fail();
236             } catch (Exception ex) {
237                 assertTrue(expectedEx.isInstance(ex));
238             }
239         }
240     }
241 
242     @Test(dataProvider="sample_isoLocalDate")
test_parse_isoLocalDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String input, Class<?> invalid)243     public void test_parse_isoLocalDate(
244             Integer year, Integer month, Integer day, String offsetId, String zoneId,
245             String input, Class<?> invalid) {
246         if (input != null) {
247             Expected expected = createDate(year, month, day);
248             // offset/zone not expected to be parsed
249             assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
250         }
251     }
252 
253     @Test
test_parse_isoLocalDate_999999999()254     public void test_parse_isoLocalDate_999999999() {
255         Expected expected = createDate(999999999, 8, 6);
256         assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("+999999999-08-06", new ParsePosition(0)), expected);
257         assertEquals(LocalDate.parse("+999999999-08-06"), LocalDate.of(999999999, 8, 6));
258     }
259 
260     @Test
test_parse_isoLocalDate_1000000000()261     public void test_parse_isoLocalDate_1000000000() {
262         Expected expected = createDate(1000000000, 8, 6);
263         assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("+1000000000-08-06", new ParsePosition(0)), expected);
264     }
265 
266     @Test(expectedExceptions = DateTimeException.class)
test_parse_isoLocalDate_1000000000_failedCreate()267     public void test_parse_isoLocalDate_1000000000_failedCreate() {
268         LocalDate.parse("+1000000000-08-06");
269     }
270 
271     @Test
test_parse_isoLocalDate_M999999999()272     public void test_parse_isoLocalDate_M999999999() {
273         Expected expected = createDate(-999999999, 8, 6);
274         assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("-999999999-08-06", new ParsePosition(0)), expected);
275         assertEquals(LocalDate.parse("-999999999-08-06"), LocalDate.of(-999999999, 8, 6));
276     }
277 
278     @Test
test_parse_isoLocalDate_M1000000000()279     public void test_parse_isoLocalDate_M1000000000() {
280         Expected expected = createDate(-1000000000, 8, 6);
281         assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE.parseUnresolved("-1000000000-08-06", new ParsePosition(0)), expected);
282     }
283 
284     @Test(expectedExceptions = DateTimeException.class)
test_parse_isoLocalDate_M1000000000_failedCreate()285     public void test_parse_isoLocalDate_M1000000000_failedCreate() {
286         LocalDate.parse("-1000000000-08-06");
287     }
288 
289     @Test
test_isoLocalDate_basics()290     public void test_isoLocalDate_basics() {
291         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getChronology(), IsoChronology.INSTANCE);
292         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getZone(), null);
293         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getResolverStyle(), ResolverStyle.STRICT);
294     }
295 
296     //-----------------------------------------------------------------------
297     //-----------------------------------------------------------------------
298     //-----------------------------------------------------------------------
299     @DataProvider(name="sample_isoOffsetDate")
provider_sample_isoOffsetDate()300     Object[][] provider_sample_isoOffsetDate() {
301         return new Object[][]{
302                 {2008, null, null, null, null, null, DateTimeException.class},
303                 {null, 6, null, null, null, null, DateTimeException.class},
304                 {null, null, 30, null, null, null, DateTimeException.class},
305                 {null, null, null, "+01:00", null, null, DateTimeException.class},
306                 {null, null, null, null, "Europe/Paris", null, DateTimeException.class},
307                 {2008, 6, null, null, null, null, DateTimeException.class},
308                 {null, 6, 30, null, null, null, DateTimeException.class},
309 
310                 {2008, 6, 30, null, null,                   null, DateTimeException.class},
311                 {2008, 6, 30, "+01:00", null,               "2008-06-30+01:00", null},
312                 {2008, 6, 30, "+01:00", "Europe/Paris",     "2008-06-30+01:00", null},
313                 {2008, 6, 30, null, "Europe/Paris",         null, DateTimeException.class},
314 
315                 {123456, 6, 30, "+01:00", null,             "+123456-06-30+01:00", null},
316         };
317     }
318 
319     @Test(dataProvider="sample_isoOffsetDate")
test_print_isoOffsetDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String expected, Class<?> expectedEx)320     public void test_print_isoOffsetDate(
321             Integer year, Integer month, Integer day, String offsetId, String zoneId,
322             String expected, Class<?> expectedEx) {
323         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
324         if (expectedEx == null) {
325             assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.format(test), expected);
326         } else {
327             try {
328                 DateTimeFormatter.ISO_OFFSET_DATE.format(test);
329                 fail();
330             } catch (Exception ex) {
331                 assertTrue(expectedEx.isInstance(ex));
332             }
333         }
334     }
335 
336     @Test(dataProvider="sample_isoOffsetDate")
test_parse_isoOffsetDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String input, Class<?> invalid)337     public void test_parse_isoOffsetDate(
338             Integer year, Integer month, Integer day, String offsetId, String zoneId,
339             String input, Class<?> invalid) {
340         if (input != null) {
341             Expected expected = createDate(year, month, day);
342             buildCalendrical(expected, offsetId, null);  // zone not expected to be parsed
343             assertParseMatch(DateTimeFormatter.ISO_OFFSET_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
344         }
345     }
346 
347     @Test
test_isoOffsetDate_basics()348     public void test_isoOffsetDate_basics() {
349         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getChronology(), IsoChronology.INSTANCE);
350         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getZone(), null);
351         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getResolverStyle(), ResolverStyle.STRICT);
352     }
353 
354     //-----------------------------------------------------------------------
355     //-----------------------------------------------------------------------
356     //-----------------------------------------------------------------------
357     @DataProvider(name="sample_isoDate")
provider_sample_isoDate()358     Object[][] provider_sample_isoDate() {
359         return new Object[][]{
360                 {2008, null, null, null, null, null, DateTimeException.class},
361                 {null, 6, null, null, null, null, DateTimeException.class},
362                 {null, null, 30, null, null, null, DateTimeException.class},
363                 {null, null, null, "+01:00", null, null, DateTimeException.class},
364                 {null, null, null, null, "Europe/Paris", null, DateTimeException.class},
365                 {2008, 6, null, null, null, null, DateTimeException.class},
366                 {null, 6, 30, null, null, null, DateTimeException.class},
367 
368                 {2008, 6, 30, null, null,                   "2008-06-30", null},
369                 {2008, 6, 30, "+01:00", null,               "2008-06-30+01:00", null},
370                 {2008, 6, 30, "+01:00", "Europe/Paris",     "2008-06-30+01:00", null},
371                 {2008, 6, 30, null, "Europe/Paris",         "2008-06-30", null},
372 
373                 {123456, 6, 30, "+01:00", "Europe/Paris",   "+123456-06-30+01:00", null},
374         };
375     }
376 
377     @Test(dataProvider="sample_isoDate")
test_print_isoDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String expected, Class<?> expectedEx)378     public void test_print_isoDate(
379             Integer year, Integer month, Integer day, String offsetId, String zoneId,
380             String expected, Class<?> expectedEx) {
381         TemporalAccessor test = buildAccessor(year, month, day, null, null, null, null, offsetId, zoneId);
382         if (expectedEx == null) {
383             assertEquals(DateTimeFormatter.ISO_DATE.format(test), expected);
384         } else {
385             try {
386                 DateTimeFormatter.ISO_DATE.format(test);
387                 fail();
388             } catch (Exception ex) {
389                 assertTrue(expectedEx.isInstance(ex));
390             }
391         }
392     }
393 
394     @Test(dataProvider="sample_isoDate")
test_parse_isoDate( Integer year, Integer month, Integer day, String offsetId, String zoneId, String input, Class<?> invalid)395     public void test_parse_isoDate(
396             Integer year, Integer month, Integer day, String offsetId, String zoneId,
397             String input, Class<?> invalid) {
398         if (input != null) {
399             Expected expected = createDate(year, month, day);
400             if (offsetId != null) {
401                 expected.add(ZoneOffset.of(offsetId));
402             }
403             assertParseMatch(DateTimeFormatter.ISO_DATE.parseUnresolved(input, new ParsePosition(0)), expected);
404         }
405     }
406 
407     @Test
test_isoDate_basics()408     public void test_isoDate_basics() {
409         assertEquals(DateTimeFormatter.ISO_DATE.getChronology(), IsoChronology.INSTANCE);
410         assertEquals(DateTimeFormatter.ISO_DATE.getZone(), null);
411         assertEquals(DateTimeFormatter.ISO_DATE.getResolverStyle(), ResolverStyle.STRICT);
412     }
413 
414     //-----------------------------------------------------------------------
415     //-----------------------------------------------------------------------
416     //-----------------------------------------------------------------------
417     @DataProvider(name="sample_isoLocalTime")
provider_sample_isoLocalTime()418     Object[][] provider_sample_isoLocalTime() {
419         return new Object[][]{
420                 {11, null, null, null, null, null, null, DateTimeException.class},
421                 {null, 5, null, null, null, null, null, DateTimeException.class},
422                 {null, null, 30, null, null, null, null, DateTimeException.class},
423                 {null, null, null, 1, null, null, null, DateTimeException.class},
424                 {null, null, null, null, "+01:00", null, null, DateTimeException.class},
425                 {null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
426 
427                 {11, 5, null, null, null, null,     "11:05", null},
428                 {11, 5, 30, null, null, null,       "11:05:30", null},
429                 {11, 5, 30, 500000000, null, null,  "11:05:30.5", null},
430                 {11, 5, 30, 1, null, null,          "11:05:30.000000001", null},
431 
432                 {11, 5, null, null, "+01:00", null,     "11:05", null},
433                 {11, 5, 30, null, "+01:00", null,       "11:05:30", null},
434                 {11, 5, 30, 500000000, "+01:00", null,  "11:05:30.5", null},
435                 {11, 5, 30, 1, "+01:00", null,          "11:05:30.000000001", null},
436 
437                 {11, 5, null, null, "+01:00", "Europe/Paris",       "11:05", null},
438                 {11, 5, 30, null, "+01:00", "Europe/Paris",         "11:05:30", null},
439                 {11, 5, 30, 500000000, "+01:00", "Europe/Paris",    "11:05:30.5", null},
440                 {11, 5, 30, 1, "+01:00", "Europe/Paris",            "11:05:30.000000001", null},
441 
442                 {11, 5, null, null, null, "Europe/Paris",       "11:05", null},
443                 {11, 5, 30, null, null, "Europe/Paris",         "11:05:30", null},
444                 {11, 5, 30, 500000000, null, "Europe/Paris",    "11:05:30.5", null},
445                 {11, 5, 30, 1, null, "Europe/Paris",            "11:05:30.000000001", null},
446         };
447     }
448 
449     @Test(dataProvider="sample_isoLocalTime")
test_print_isoLocalTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)450     public void test_print_isoLocalTime(
451             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
452             String expected, Class<?> expectedEx) {
453         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
454         if (expectedEx == null) {
455             assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.format(test), expected);
456         } else {
457             try {
458                 DateTimeFormatter.ISO_LOCAL_TIME.format(test);
459                 fail();
460             } catch (Exception ex) {
461                 assertTrue(expectedEx.isInstance(ex));
462             }
463         }
464     }
465 
466     @Test(dataProvider="sample_isoLocalTime")
test_parse_isoLocalTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)467     public void test_parse_isoLocalTime(
468             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
469             String input, Class<?> invalid) {
470         if (input != null) {
471             Expected expected = createTime(hour, min, sec, nano);
472             // offset/zone not expected to be parsed
473             assertParseMatch(DateTimeFormatter.ISO_LOCAL_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
474         }
475     }
476 
477     @Test
test_isoLocalTime_basics()478     public void test_isoLocalTime_basics() {
479         assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getChronology(), null);
480         assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getZone(), null);
481         assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getResolverStyle(), ResolverStyle.STRICT);
482     }
483 
484     //-----------------------------------------------------------------------
485     //-----------------------------------------------------------------------
486     //-----------------------------------------------------------------------
487     @DataProvider(name="sample_isoOffsetTime")
provider_sample_isoOffsetTime()488     Object[][] provider_sample_isoOffsetTime() {
489         return new Object[][]{
490                 {11, null, null, null, null, null, null, DateTimeException.class},
491                 {null, 5, null, null, null, null, null, DateTimeException.class},
492                 {null, null, 30, null, null, null, null, DateTimeException.class},
493                 {null, null, null, 1, null, null, null, DateTimeException.class},
494                 {null, null, null, null, "+01:00", null, null, DateTimeException.class},
495                 {null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
496 
497                 {11, 5, null, null, null, null,     null, DateTimeException.class},
498                 {11, 5, 30, null, null, null,       null, DateTimeException.class},
499                 {11, 5, 30, 500000000, null, null,  null, DateTimeException.class},
500                 {11, 5, 30, 1, null, null,          null, DateTimeException.class},
501 
502                 {11, 5, null, null, "+01:00", null,     "11:05+01:00", null},
503                 {11, 5, 30, null, "+01:00", null,       "11:05:30+01:00", null},
504                 {11, 5, 30, 500000000, "+01:00", null,  "11:05:30.5+01:00", null},
505                 {11, 5, 30, 1, "+01:00", null,          "11:05:30.000000001+01:00", null},
506 
507                 {11, 5, null, null, "+01:00", "Europe/Paris",       "11:05+01:00", null},
508                 {11, 5, 30, null, "+01:00", "Europe/Paris",         "11:05:30+01:00", null},
509                 {11, 5, 30, 500000000, "+01:00", "Europe/Paris",    "11:05:30.5+01:00", null},
510                 {11, 5, 30, 1, "+01:00", "Europe/Paris",            "11:05:30.000000001+01:00", null},
511 
512                 {11, 5, null, null, null, "Europe/Paris",       null, DateTimeException.class},
513                 {11, 5, 30, null, null, "Europe/Paris",         null, DateTimeException.class},
514                 {11, 5, 30, 500000000, null, "Europe/Paris",    null, DateTimeException.class},
515                 {11, 5, 30, 1, null, "Europe/Paris",            null, DateTimeException.class},
516         };
517     }
518 
519     @Test(dataProvider="sample_isoOffsetTime")
test_print_isoOffsetTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)520     public void test_print_isoOffsetTime(
521             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
522             String expected, Class<?> expectedEx) {
523         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
524         if (expectedEx == null) {
525             assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.format(test), expected);
526         } else {
527             try {
528                 DateTimeFormatter.ISO_OFFSET_TIME.format(test);
529                 fail();
530             } catch (Exception ex) {
531                 assertTrue(expectedEx.isInstance(ex));
532             }
533         }
534     }
535 
536     @Test(dataProvider="sample_isoOffsetTime")
test_parse_isoOffsetTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)537     public void test_parse_isoOffsetTime(
538             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
539             String input, Class<?> invalid) {
540         if (input != null) {
541             Expected expected = createTime(hour, min, sec, nano);
542             buildCalendrical(expected, offsetId, null);  // zoneId is not expected from parse
543             assertParseMatch(DateTimeFormatter.ISO_OFFSET_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
544         }
545     }
546 
547     @Test
test_isoOffsetTime_basics()548     public void test_isoOffsetTime_basics() {
549         assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getChronology(), null);
550         assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getZone(), null);
551         assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getResolverStyle(), ResolverStyle.STRICT);
552     }
553 
554     //-----------------------------------------------------------------------
555     //-----------------------------------------------------------------------
556     //-----------------------------------------------------------------------
557     @DataProvider(name="sample_isoTime")
provider_sample_isoTime()558     Object[][] provider_sample_isoTime() {
559         return new Object[][]{
560                 {11, null, null, null, null, null, null, DateTimeException.class},
561                 {null, 5, null, null, null, null, null, DateTimeException.class},
562                 {null, null, 30, null, null, null, null, DateTimeException.class},
563                 {null, null, null, 1, null, null, null, DateTimeException.class},
564                 {null, null, null, null, "+01:00", null, null, DateTimeException.class},
565                 {null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
566 
567                 {11, 5, null, null, null, null,     "11:05", null},
568                 {11, 5, 30, null, null, null,       "11:05:30", null},
569                 {11, 5, 30, 500000000, null, null,  "11:05:30.5", null},
570                 {11, 5, 30, 1, null, null,          "11:05:30.000000001", null},
571 
572                 {11, 5, null, null, "+01:00", null,     "11:05+01:00", null},
573                 {11, 5, 30, null, "+01:00", null,       "11:05:30+01:00", null},
574                 {11, 5, 30, 500000000, "+01:00", null,  "11:05:30.5+01:00", null},
575                 {11, 5, 30, 1, "+01:00", null,          "11:05:30.000000001+01:00", null},
576 
577                 {11, 5, null, null, "+01:00", "Europe/Paris",       "11:05+01:00", null},
578                 {11, 5, 30, null, "+01:00", "Europe/Paris",         "11:05:30+01:00", null},
579                 {11, 5, 30, 500000000, "+01:00", "Europe/Paris",    "11:05:30.5+01:00", null},
580                 {11, 5, 30, 1, "+01:00", "Europe/Paris",            "11:05:30.000000001+01:00", null},
581 
582                 {11, 5, null, null, null, "Europe/Paris",       "11:05", null},
583                 {11, 5, 30, null, null, "Europe/Paris",         "11:05:30", null},
584                 {11, 5, 30, 500000000, null, "Europe/Paris",    "11:05:30.5", null},
585                 {11, 5, 30, 1, null, "Europe/Paris",            "11:05:30.000000001", null},
586         };
587     }
588 
589     @Test(dataProvider="sample_isoTime")
test_print_isoTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)590     public void test_print_isoTime(
591             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
592             String expected, Class<?> expectedEx) {
593         TemporalAccessor test = buildAccessor(null, null, null, hour, min, sec, nano, offsetId, zoneId);
594         if (expectedEx == null) {
595             assertEquals(DateTimeFormatter.ISO_TIME.format(test), expected);
596         } else {
597             try {
598                 DateTimeFormatter.ISO_TIME.format(test);
599                 fail();
600             } catch (Exception ex) {
601                 assertTrue(expectedEx.isInstance(ex));
602             }
603         }
604     }
605 
606     @Test(dataProvider="sample_isoTime")
test_parse_isoTime( Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)607     public void test_parse_isoTime(
608             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
609             String input, Class<?> invalid) {
610         if (input != null) {
611             Expected expected = createTime(hour, min, sec, nano);
612             if (offsetId != null) {
613                 expected.add(ZoneOffset.of(offsetId));
614             }
615             assertParseMatch(DateTimeFormatter.ISO_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
616         }
617     }
618 
619     @Test
test_isoTime_basics()620     public void test_isoTime_basics() {
621         assertEquals(DateTimeFormatter.ISO_TIME.getChronology(), null);
622         assertEquals(DateTimeFormatter.ISO_TIME.getZone(), null);
623         assertEquals(DateTimeFormatter.ISO_TIME.getResolverStyle(), ResolverStyle.STRICT);
624     }
625 
626     //-----------------------------------------------------------------------
627     //-----------------------------------------------------------------------
628     //-----------------------------------------------------------------------
629     @DataProvider(name="sample_isoLocalDateTime")
provider_sample_isoLocalDateTime()630     Object[][] provider_sample_isoLocalDateTime() {
631         return new Object[][]{
632                 {2008, null, null, null, null, null, null, null, null, null, DateTimeException.class},
633                 {null, 6, null, null, null, null, null, null, null, null, DateTimeException.class},
634                 {null, null, 30, null, null, null, null, null, null, null, DateTimeException.class},
635                 {null, null, null, 11, null, null, null, null, null, null, DateTimeException.class},
636                 {null, null, null, null, 5, null, null, null, null, null, DateTimeException.class},
637                 {null, null, null, null, null, null, null, "+01:00", null, null, DateTimeException.class},
638                 {null, null, null, null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
639                 {2008, 6, 30, 11, null, null, null, null, null, null, DateTimeException.class},
640                 {2008, 6, 30, null, 5, null, null, null, null, null, DateTimeException.class},
641                 {2008, 6, null, 11, 5, null, null, null, null, null, DateTimeException.class},
642                 {2008, null, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
643                 {null, 6, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
644 
645                 {2008, 6, 30, 11, 5, null, null, null, null,                    "2008-06-30T11:05", null},
646                 {2008, 6, 30, 11, 5, 30, null, null, null,                      "2008-06-30T11:05:30", null},
647                 {2008, 6, 30, 11, 5, 30, 500000000, null, null,                 "2008-06-30T11:05:30.5", null},
648                 {2008, 6, 30, 11, 5, 30, 1, null, null,                         "2008-06-30T11:05:30.000000001", null},
649 
650                 {2008, 6, 30, 11, 5, null, null, "+01:00", null,                "2008-06-30T11:05", null},
651                 {2008, 6, 30, 11, 5, 30, null, "+01:00", null,                  "2008-06-30T11:05:30", null},
652                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", null,             "2008-06-30T11:05:30.5", null},
653                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", null,                     "2008-06-30T11:05:30.000000001", null},
654 
655                 {2008, 6, 30, 11, 5, null, null, "+01:00", "Europe/Paris",      "2008-06-30T11:05", null},
656                 {2008, 6, 30, 11, 5, 30, null, "+01:00", "Europe/Paris",        "2008-06-30T11:05:30", null},
657                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", "Europe/Paris",   "2008-06-30T11:05:30.5", null},
658                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", "Europe/Paris",           "2008-06-30T11:05:30.000000001", null},
659 
660                 {2008, 6, 30, 11, 5, null, null, null, "Europe/Paris",          "2008-06-30T11:05", null},
661                 {2008, 6, 30, 11, 5, 30, null, null, "Europe/Paris",            "2008-06-30T11:05:30", null},
662                 {2008, 6, 30, 11, 5, 30, 500000000, null, "Europe/Paris",       "2008-06-30T11:05:30.5", null},
663                 {2008, 6, 30, 11, 5, 30, 1, null, "Europe/Paris",               "2008-06-30T11:05:30.000000001", null},
664 
665                 {123456, 6, 30, 11, 5, null, null, null, null,                  "+123456-06-30T11:05", null},
666         };
667     }
668 
669     @Test(dataProvider="sample_isoLocalDateTime")
test_print_isoLocalDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)670     public void test_print_isoLocalDateTime(
671             Integer year, Integer month, Integer day,
672             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
673             String expected, Class<?> expectedEx) {
674         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
675         if (expectedEx == null) {
676             assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(test), expected);
677         } else {
678             try {
679                 DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(test);
680                 fail();
681             } catch (Exception ex) {
682                 assertTrue(expectedEx.isInstance(ex));
683             }
684         }
685     }
686 
687     @Test(dataProvider="sample_isoLocalDateTime")
test_parse_isoLocalDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)688     public void test_parse_isoLocalDateTime(
689             Integer year, Integer month, Integer day,
690             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
691             String input, Class<?> invalid) {
692         if (input != null) {
693             Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
694             assertParseMatch(DateTimeFormatter.ISO_LOCAL_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
695         }
696     }
697 
698     @Test
test_isoLocalDateTime_basics()699     public void test_isoLocalDateTime_basics() {
700         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
701         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getZone(), null);
702         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
703     }
704 
705     //-----------------------------------------------------------------------
706     //-----------------------------------------------------------------------
707     //-----------------------------------------------------------------------
708     @DataProvider(name="sample_isoOffsetDateTime")
provider_sample_isoOffsetDateTime()709     Object[][] provider_sample_isoOffsetDateTime() {
710         return new Object[][]{
711                 {2008, null, null, null, null, null, null, null, null, null, DateTimeException.class},
712                 {null, 6, null, null, null, null, null, null, null, null, DateTimeException.class},
713                 {null, null, 30, null, null, null, null, null, null, null, DateTimeException.class},
714                 {null, null, null, 11, null, null, null, null, null, null, DateTimeException.class},
715                 {null, null, null, null, 5, null, null, null, null, null, DateTimeException.class},
716                 {null, null, null, null, null, null, null, "+01:00", null, null, DateTimeException.class},
717                 {null, null, null, null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
718                 {2008, 6, 30, 11, null, null, null, null, null, null, DateTimeException.class},
719                 {2008, 6, 30, null, 5, null, null, null, null, null, DateTimeException.class},
720                 {2008, 6, null, 11, 5, null, null, null, null, null, DateTimeException.class},
721                 {2008, null, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
722                 {null, 6, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
723 
724                 {2008, 6, 30, 11, 5, null, null, null, null,                    null, DateTimeException.class},
725                 {2008, 6, 30, 11, 5, 30, null, null, null,                      null, DateTimeException.class},
726                 {2008, 6, 30, 11, 5, 30, 500000000, null, null,                 null, DateTimeException.class},
727                 {2008, 6, 30, 11, 5, 30, 1, null, null,                         null, DateTimeException.class},
728 
729                 {2008, 6, 30, 11, 5, null, null, "+01:00", null,                "2008-06-30T11:05+01:00", null},
730                 {2008, 6, 30, 11, 5, 30, null, "+01:00", null,                  "2008-06-30T11:05:30+01:00", null},
731                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", null,             "2008-06-30T11:05:30.5+01:00", null},
732                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", null,                     "2008-06-30T11:05:30.000000001+01:00", null},
733 
734                 {2008, 6, 30, 11, 5, null, null, "+01:00", "Europe/Paris",      "2008-06-30T11:05+01:00", null},
735                 {2008, 6, 30, 11, 5, 30, null, "+01:00", "Europe/Paris",        "2008-06-30T11:05:30+01:00", null},
736                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", "Europe/Paris",   "2008-06-30T11:05:30.5+01:00", null},
737                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", "Europe/Paris",           "2008-06-30T11:05:30.000000001+01:00", null},
738 
739                 {2008, 6, 30, 11, 5, null, null, null, "Europe/Paris",          null, DateTimeException.class},
740                 {2008, 6, 30, 11, 5, 30, null, null, "Europe/Paris",            null, DateTimeException.class},
741                 {2008, 6, 30, 11, 5, 30, 500000000, null, "Europe/Paris",       null, DateTimeException.class},
742                 {2008, 6, 30, 11, 5, 30, 1, null, "Europe/Paris",               null, DateTimeException.class},
743 
744                 {123456, 6, 30, 11, 5, null, null, "+01:00", null,              "+123456-06-30T11:05+01:00", null},
745         };
746     }
747 
748     @Test(dataProvider="sample_isoOffsetDateTime")
test_print_isoOffsetDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)749     public void test_print_isoOffsetDateTime(
750             Integer year, Integer month, Integer day,
751             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
752             String expected, Class<?> expectedEx) {
753         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
754         if (expectedEx == null) {
755             assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(test), expected);
756         } else {
757             try {
758                 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(test);
759                 fail();
760             } catch (Exception ex) {
761                 assertTrue(expectedEx.isInstance(ex));
762             }
763         }
764     }
765 
766     @Test(dataProvider="sample_isoOffsetDateTime")
test_parse_isoOffsetDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)767     public void test_parse_isoOffsetDateTime(
768             Integer year, Integer month, Integer day,
769             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
770             String input, Class<?> invalid) {
771         if (input != null) {
772             Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
773             buildCalendrical(expected, offsetId, null);  // zone not expected to be parsed
774             assertParseMatch(DateTimeFormatter.ISO_OFFSET_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
775         }
776     }
777 
778     @Test
test_isoOffsetDateTime_basics()779     public void test_isoOffsetDateTime_basics() {
780         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
781         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getZone(), null);
782         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
783     }
784 
785     //-----------------------------------------------------------------------
786     //-----------------------------------------------------------------------
787     //-----------------------------------------------------------------------
788     @DataProvider(name="sample_isoZonedDateTime")
provider_sample_isoZonedDateTime()789     Object[][] provider_sample_isoZonedDateTime() {
790         return new Object[][]{
791                 {2008, null, null, null, null, null, null, null, null, null, DateTimeException.class},
792                 {null, 6, null, null, null, null, null, null, null, null, DateTimeException.class},
793                 {null, null, 30, null, null, null, null, null, null, null, DateTimeException.class},
794                 {null, null, null, 11, null, null, null, null, null, null, DateTimeException.class},
795                 {null, null, null, null, 5, null, null, null, null, null, DateTimeException.class},
796                 {null, null, null, null, null, null, null, "+01:00", null, null, DateTimeException.class},
797                 {null, null, null, null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
798                 {2008, 6, 30, 11, null, null, null, null, null, null, DateTimeException.class},
799                 {2008, 6, 30, null, 5, null, null, null, null, null, DateTimeException.class},
800                 {2008, 6, null, 11, 5, null, null, null, null, null, DateTimeException.class},
801                 {2008, null, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
802                 {null, 6, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
803 
804                 {2008, 6, 30, 11, 5, null, null, null, null,                    null, DateTimeException.class},
805                 {2008, 6, 30, 11, 5, 30, null, null, null,                      null, DateTimeException.class},
806                 {2008, 6, 30, 11, 5, 30, 500000000, null, null,                 null, DateTimeException.class},
807                 {2008, 6, 30, 11, 5, 30, 1, null, null,                         null, DateTimeException.class},
808 
809                 // allow OffsetDateTime (no harm comes of this AFAICT)
810                 {2008, 6, 30, 11, 5, null, null, "+01:00", null,                "2008-06-30T11:05+01:00", null},
811                 {2008, 6, 30, 11, 5, 30, null, "+01:00", null,                  "2008-06-30T11:05:30+01:00", null},
812                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", null,             "2008-06-30T11:05:30.5+01:00", null},
813                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", null,                     "2008-06-30T11:05:30.000000001+01:00", null},
814 
815                 // ZonedDateTime with ZoneId of ZoneOffset
816                 {2008, 6, 30, 11, 5, null, null, "+01:00", "+01:00",            "2008-06-30T11:05+01:00", null},
817                 {2008, 6, 30, 11, 5, 30, null, "+01:00", "+01:00",              "2008-06-30T11:05:30+01:00", null},
818                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", "+01:00",         "2008-06-30T11:05:30.5+01:00", null},
819                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", "+01:00",                 "2008-06-30T11:05:30.000000001+01:00", null},
820 
821                 // ZonedDateTime with ZoneId of ZoneRegion
822                 {2008, 6, 30, 11, 5, null, null, "+01:00", "Europe/Paris",      "2008-06-30T11:05+01:00[Europe/Paris]", null},
823                 {2008, 6, 30, 11, 5, 30, null, "+01:00", "Europe/Paris",        "2008-06-30T11:05:30+01:00[Europe/Paris]", null},
824                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", "Europe/Paris",   "2008-06-30T11:05:30.5+01:00[Europe/Paris]", null},
825                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", "Europe/Paris",           "2008-06-30T11:05:30.000000001+01:00[Europe/Paris]", null},
826 
827                 // offset required
828                 {2008, 6, 30, 11, 5, null, null, null, "Europe/Paris",          null, DateTimeException.class},
829                 {2008, 6, 30, 11, 5, 30, null, null, "Europe/Paris",            null, DateTimeException.class},
830                 {2008, 6, 30, 11, 5, 30, 500000000, null, "Europe/Paris",       null, DateTimeException.class},
831                 {2008, 6, 30, 11, 5, 30, 1, null, "Europe/Paris",               null, DateTimeException.class},
832 
833                 {123456, 6, 30, 11, 5, null, null, "+01:00", "Europe/Paris",    "+123456-06-30T11:05+01:00[Europe/Paris]", null},
834         };
835     }
836 
837     @Test(dataProvider="sample_isoZonedDateTime")
test_print_isoZonedDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)838     public void test_print_isoZonedDateTime(
839             Integer year, Integer month, Integer day,
840             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
841             String expected, Class<?> expectedEx) {
842         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
843         if (expectedEx == null) {
844             assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(test), expected);
845         } else {
846             try {
847                 DateTimeFormatter.ISO_ZONED_DATE_TIME.format(test);
848                 fail(test.toString());
849             } catch (Exception ex) {
850                 assertTrue(expectedEx.isInstance(ex));
851             }
852         }
853     }
854 
855     @Test(dataProvider="sample_isoZonedDateTime")
test_parse_isoZonedDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)856     public void test_parse_isoZonedDateTime(
857             Integer year, Integer month, Integer day,
858             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
859             String input, Class<?> invalid) {
860         if (input != null) {
861             Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
862             if (offsetId.equals(zoneId)) {
863                 buildCalendrical(expected, offsetId, null);
864             } else {
865                 buildCalendrical(expected, offsetId, zoneId);
866             }
867             assertParseMatch(DateTimeFormatter.ISO_ZONED_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
868         }
869     }
870 
871     @Test
test_isoZonedDateTime_basics()872     public void test_isoZonedDateTime_basics() {
873         assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
874         assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getZone(), null);
875         assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
876     }
877 
878     //-----------------------------------------------------------------------
879     //-----------------------------------------------------------------------
880     //-----------------------------------------------------------------------
881     @DataProvider(name="sample_isoDateTime")
provider_sample_isoDateTime()882     Object[][] provider_sample_isoDateTime() {
883         return new Object[][]{
884                 {2008, null, null, null, null, null, null, null, null, null, DateTimeException.class},
885                 {null, 6, null, null, null, null, null, null, null, null, DateTimeException.class},
886                 {null, null, 30, null, null, null, null, null, null, null, DateTimeException.class},
887                 {null, null, null, 11, null, null, null, null, null, null, DateTimeException.class},
888                 {null, null, null, null, 5, null, null, null, null, null, DateTimeException.class},
889                 {null, null, null, null, null, null, null, "+01:00", null, null, DateTimeException.class},
890                 {null, null, null, null, null, null, null, null, "Europe/Paris", null, DateTimeException.class},
891                 {2008, 6, 30, 11, null, null, null, null, null, null, DateTimeException.class},
892                 {2008, 6, 30, null, 5, null, null, null, null, null, DateTimeException.class},
893                 {2008, 6, null, 11, 5, null, null, null, null, null, DateTimeException.class},
894                 {2008, null, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
895                 {null, 6, 30, 11, 5, null, null, null, null, null, DateTimeException.class},
896 
897                 {2008, 6, 30, 11, 5, null, null, null, null,                    "2008-06-30T11:05", null},
898                 {2008, 6, 30, 11, 5, 30, null, null, null,                      "2008-06-30T11:05:30", null},
899                 {2008, 6, 30, 11, 5, 30, 500000000, null, null,                 "2008-06-30T11:05:30.5", null},
900                 {2008, 6, 30, 11, 5, 30, 1, null, null,                         "2008-06-30T11:05:30.000000001", null},
901 
902                 {2008, 6, 30, 11, 5, null, null, "+01:00", null,                "2008-06-30T11:05+01:00", null},
903                 {2008, 6, 30, 11, 5, 30, null, "+01:00", null,                  "2008-06-30T11:05:30+01:00", null},
904                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", null,             "2008-06-30T11:05:30.5+01:00", null},
905                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", null,                     "2008-06-30T11:05:30.000000001+01:00", null},
906 
907                 {2008, 6, 30, 11, 5, null, null, "+01:00", "Europe/Paris",      "2008-06-30T11:05+01:00[Europe/Paris]", null},
908                 {2008, 6, 30, 11, 5, 30, null, "+01:00", "Europe/Paris",        "2008-06-30T11:05:30+01:00[Europe/Paris]", null},
909                 {2008, 6, 30, 11, 5, 30, 500000000, "+01:00", "Europe/Paris",   "2008-06-30T11:05:30.5+01:00[Europe/Paris]", null},
910                 {2008, 6, 30, 11, 5, 30, 1, "+01:00", "Europe/Paris",           "2008-06-30T11:05:30.000000001+01:00[Europe/Paris]", null},
911 
912                 {2008, 6, 30, 11, 5, null, null, null, "Europe/Paris",          "2008-06-30T11:05", null},
913                 {2008, 6, 30, 11, 5, 30, null, null, "Europe/Paris",            "2008-06-30T11:05:30", null},
914                 {2008, 6, 30, 11, 5, 30, 500000000, null, "Europe/Paris",       "2008-06-30T11:05:30.5", null},
915                 {2008, 6, 30, 11, 5, 30, 1, null, "Europe/Paris",               "2008-06-30T11:05:30.000000001", null},
916 
917                 {123456, 6, 30, 11, 5, null, null, null, null,                  "+123456-06-30T11:05", null},
918         };
919     }
920 
921     @Test(dataProvider="sample_isoDateTime")
test_print_isoDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String expected, Class<?> expectedEx)922     public void test_print_isoDateTime(
923             Integer year, Integer month, Integer day,
924             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
925             String expected, Class<?> expectedEx) {
926         TemporalAccessor test = buildAccessor(year, month, day, hour, min, sec, nano, offsetId, zoneId);
927         if (expectedEx == null) {
928             assertEquals(DateTimeFormatter.ISO_DATE_TIME.format(test), expected);
929         } else {
930             try {
931                 DateTimeFormatter.ISO_DATE_TIME.format(test);
932                 fail();
933             } catch (Exception ex) {
934                 assertTrue(expectedEx.isInstance(ex));
935             }
936         }
937     }
938 
939     @Test(dataProvider="sample_isoDateTime")
test_parse_isoDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId, String input, Class<?> invalid)940     public void test_parse_isoDateTime(
941             Integer year, Integer month, Integer day,
942             Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId,
943             String input, Class<?> invalid) {
944         if (input != null) {
945             Expected expected = createDateTime(year, month, day, hour, min, sec, nano);
946             if (offsetId != null) {
947                 expected.add(ZoneOffset.of(offsetId));
948                 if (zoneId != null) {
949                     expected.zone = ZoneId.of(zoneId);
950                 }
951             }
952             assertParseMatch(DateTimeFormatter.ISO_DATE_TIME.parseUnresolved(input, new ParsePosition(0)), expected);
953         }
954     }
955 
956     @Test
test_isoDateTime_basics()957     public void test_isoDateTime_basics() {
958         assertEquals(DateTimeFormatter.ISO_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
959         assertEquals(DateTimeFormatter.ISO_DATE_TIME.getZone(), null);
960         assertEquals(DateTimeFormatter.ISO_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
961     }
962 
963     //-----------------------------------------------------------------------
964     //-----------------------------------------------------------------------
965     //-----------------------------------------------------------------------
966     @Test
test_print_isoOrdinalDate()967     public void test_print_isoOrdinalDate() {
968         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), null, null);
969         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155");
970     }
971 
972     @Test
test_print_isoOrdinalDate_offset()973     public void test_print_isoOrdinalDate_offset() {
974         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "Z", null);
975         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155Z");
976     }
977 
978     @Test
test_print_isoOrdinalDate_zoned()979     public void test_print_isoOrdinalDate_zoned() {
980         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "+02:00", "Europe/Paris");
981         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-155+02:00");
982     }
983 
984     @Test
test_print_isoOrdinalDate_zoned_largeYear()985     public void test_print_isoOrdinalDate_zoned_largeYear() {
986         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
987         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "+123456-155Z");
988     }
989 
990     @Test
test_print_isoOrdinalDate_fields()991     public void test_print_isoOrdinalDate_fields() {
992         // mock for testing that does not fully comply with TemporalAccessor contract
993         TemporalAccessor test = new TemporalAccessor() {
994             @Override
995             public boolean isSupported(TemporalField field) {
996                 return field == YEAR || field == DAY_OF_YEAR;
997             }
998             @Override
999             public long getLong(TemporalField field) {
1000                 if (field == YEAR) {
1001                     return 2008;
1002                 }
1003                 if (field == DAY_OF_YEAR) {
1004                     return 231;
1005                 }
1006                 throw new DateTimeException("Unsupported");
1007             }
1008         };
1009         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.format(test), "2008-231");
1010     }
1011 
1012     @Test(expectedExceptions=DateTimeException.class)
test_print_isoOrdinalDate_missingField()1013     public void test_print_isoOrdinalDate_missingField() {
1014         TemporalAccessor test = Year.of(2008);
1015         DateTimeFormatter.ISO_ORDINAL_DATE.format(test);
1016     }
1017 
1018     //-----------------------------------------------------------------------
1019     @Test
test_parse_isoOrdinalDate()1020     public void test_parse_isoOrdinalDate() {
1021         Expected expected = new Expected(YEAR, 2008, DAY_OF_YEAR, 123);
1022         assertParseMatch(DateTimeFormatter.ISO_ORDINAL_DATE.parseUnresolved("2008-123", new ParsePosition(0)), expected);
1023     }
1024 
1025     @Test
test_parse_isoOrdinalDate_largeYear()1026     public void test_parse_isoOrdinalDate_largeYear() {
1027         Expected expected = new Expected(YEAR, 123456, DAY_OF_YEAR, 123);
1028         assertParseMatch(DateTimeFormatter.ISO_ORDINAL_DATE.parseUnresolved("+123456-123", new ParsePosition(0)), expected);
1029     }
1030 
1031     @Test
test_isoOrdinalDate_basics()1032     public void test_isoOrdinalDate_basics() {
1033         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getChronology(), IsoChronology.INSTANCE);
1034         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getZone(), null);
1035         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getResolverStyle(), ResolverStyle.STRICT);
1036     }
1037 
1038     //-----------------------------------------------------------------------
1039     //-----------------------------------------------------------------------
1040     //-----------------------------------------------------------------------
1041     @Test
test_print_basicIsoDate()1042     public void test_print_basicIsoDate() {
1043         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), null, null);
1044         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603");
1045     }
1046 
1047     @Test
test_print_basicIsoDate_offset()1048     public void test_print_basicIsoDate_offset() {
1049         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "Z", null);
1050         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603Z");
1051     }
1052 
1053     @Test
test_print_basicIsoDate_zoned()1054     public void test_print_basicIsoDate_zoned() {
1055         TemporalAccessor test = buildAccessor(LocalDateTime.of(2008, 6, 3, 11, 5, 30), "+02:00", "Europe/Paris");
1056         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603+0200");
1057     }
1058 
1059     @Test(expectedExceptions=DateTimeException.class)
test_print_basicIsoDate_largeYear()1060     public void test_print_basicIsoDate_largeYear() {
1061         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
1062         DateTimeFormatter.BASIC_ISO_DATE.format(test);
1063     }
1064 
1065     @Test
test_print_basicIsoDate_fields()1066     public void test_print_basicIsoDate_fields() {
1067         TemporalAccessor test = buildAccessor(LocalDate.of(2008, 6, 3), null, null);
1068         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.format(test), "20080603");
1069     }
1070 
1071     @Test(expectedExceptions=DateTimeException.class)
test_print_basicIsoDate_missingField()1072     public void test_print_basicIsoDate_missingField() {
1073         TemporalAccessor test = YearMonth.of(2008, 6);
1074         DateTimeFormatter.BASIC_ISO_DATE.format(test);
1075     }
1076 
1077     //-----------------------------------------------------------------------
1078     @Test
test_parse_basicIsoDate()1079     public void test_parse_basicIsoDate() {
1080         LocalDate expected = LocalDate.of(2008, 6, 3);
1081         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.parse("20080603", LocalDate::from), expected);
1082     }
1083 
1084     @Test(expectedExceptions=DateTimeParseException.class)
test_parse_basicIsoDate_largeYear()1085     public void test_parse_basicIsoDate_largeYear() {
1086         try {
1087             LocalDate expected = LocalDate.of(123456, 6, 3);
1088             assertEquals(DateTimeFormatter.BASIC_ISO_DATE.parse("+1234560603", LocalDate::from), expected);
1089         } catch (DateTimeParseException ex) {
1090             assertEquals(ex.getErrorIndex(), 0);
1091             assertEquals(ex.getParsedString(), "+1234560603");
1092             throw ex;
1093         }
1094     }
1095 
1096     @Test
test_basicIsoDate_basics()1097     public void test_basicIsoDate_basics() {
1098         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getChronology(), IsoChronology.INSTANCE);
1099         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getZone(), null);
1100         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getResolverStyle(), ResolverStyle.STRICT);
1101     }
1102 
1103     //-----------------------------------------------------------------------
1104     //-----------------------------------------------------------------------
1105     //-----------------------------------------------------------------------
1106     @DataProvider(name="weekDate")
weekDate()1107     Iterator<Object[]> weekDate() {
1108         return new Iterator<Object[]>() {
1109             private ZonedDateTime date = ZonedDateTime.of(LocalDateTime.of(2003, 12, 29, 11, 5, 30), ZoneId.of("Europe/Paris"));
1110             private ZonedDateTime endDate = date.withYear(2005).withMonth(1).withDayOfMonth(2);
1111             private int week = 1;
1112             private int day = 1;
1113 
1114             public boolean hasNext() {
1115                 return !date.isAfter(endDate);
1116             }
1117             public Object[] next() {
1118                 StringBuilder sb = new StringBuilder("2004-W");
1119                 if (week < 10) {
1120                     sb.append('0');
1121                 }
1122                 sb.append(week).append('-').append(day).append(date.getOffset());
1123                 Object[] ret = new Object[] {date, sb.toString()};
1124                 date = date.plusDays(1);
1125                 day += 1;
1126                 if (day == 8) {
1127                     day = 1;
1128                     week++;
1129                 }
1130                 return ret;
1131             }
1132             public void remove() {
1133                 throw new UnsupportedOperationException();
1134             }
1135         };
1136     }
1137 
1138     @Test(dataProvider="weekDate")
test_print_isoWeekDate(TemporalAccessor test, String expected)1139     public void test_print_isoWeekDate(TemporalAccessor test, String expected) {
1140         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), expected);
1141     }
1142 
1143     @Test
test_print_isoWeekDate_zoned_largeYear()1144     public void test_print_isoWeekDate_zoned_largeYear() {
1145         TemporalAccessor test = buildAccessor(LocalDateTime.of(123456, 6, 3, 11, 5, 30), "Z", null);
1146         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), "+123456-W23-2Z");
1147     }
1148 
1149     @Test
test_print_isoWeekDate_fields()1150     public void test_print_isoWeekDate_fields() {
1151         TemporalAccessor test = buildAccessor(LocalDate.of(2004, 1, 27), null, null);
1152         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.format(test), "2004-W05-2");
1153     }
1154 
1155     @Test(expectedExceptions=DateTimeException.class)
test_print_isoWeekDate_missingField()1156     public void test_print_isoWeekDate_missingField() {
1157         TemporalAccessor test = YearMonth.of(2008, 6);
1158         DateTimeFormatter.ISO_WEEK_DATE.format(test);
1159     }
1160 
1161     //-----------------------------------------------------------------------
1162     @Test
test_parse_weekDate()1163     public void test_parse_weekDate() {
1164         LocalDate expected = LocalDate.of(2004, 1, 28);
1165         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.parse("2004-W05-3", LocalDate::from), expected);
1166     }
1167 
1168     @Test
test_parse_weekDate_largeYear()1169     public void test_parse_weekDate_largeYear() {
1170         TemporalAccessor parsed = DateTimeFormatter.ISO_WEEK_DATE.parseUnresolved("+123456-W04-5", new ParsePosition(0));
1171         assertEquals(parsed.getLong(IsoFields.WEEK_BASED_YEAR), 123456L);
1172         assertEquals(parsed.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR), 4L);
1173         assertEquals(parsed.getLong(DAY_OF_WEEK), 5L);
1174     }
1175 
1176     @Test
test_isoWeekDate_basics()1177     public void test_isoWeekDate_basics() {
1178         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getChronology(), IsoChronology.INSTANCE);
1179         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getZone(), null);
1180         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getResolverStyle(), ResolverStyle.STRICT);
1181     }
1182 
1183     //-----------------------------------------------------------------------
1184     //-----------------------------------------------------------------------
1185     //-----------------------------------------------------------------------
1186     @DataProvider(name="sample_isoInstant")
provider_sample_isoInstant()1187     Object[][] provider_sample_isoInstant() {
1188         return new Object[][]{
1189                 {0, 0, "1970-01-01T00:00:00Z", null},
1190                 {0, null, "1970-01-01T00:00:00Z", null},
1191                 {0, -1, null, DateTimeException.class},
1192 
1193                 {-1, 0, "1969-12-31T23:59:59Z", null},
1194                 {1, 0, "1970-01-01T00:00:01Z", null},
1195                 {60, 0, "1970-01-01T00:01:00Z", null},
1196                 {3600, 0, "1970-01-01T01:00:00Z", null},
1197                 {86400, 0, "1970-01-02T00:00:00Z", null},
1198 
1199                 {0, 1, "1970-01-01T00:00:00.000000001Z", null},
1200                 {0, 2, "1970-01-01T00:00:00.000000002Z", null},
1201                 {0, 10, "1970-01-01T00:00:00.000000010Z", null},
1202                 {0, 100, "1970-01-01T00:00:00.000000100Z", null},
1203         };
1204     }
1205 
1206     @Test(dataProvider="sample_isoInstant")
test_print_isoInstant( long instantSecs, Integer nano, String expected, Class<?> expectedEx)1207     public void test_print_isoInstant(
1208             long instantSecs, Integer nano, String expected, Class<?> expectedEx) {
1209         TemporalAccessor test = buildAccessorInstant(instantSecs, nano);
1210         if (expectedEx == null) {
1211             assertEquals(DateTimeFormatter.ISO_INSTANT.format(test), expected);
1212         } else {
1213             try {
1214                 DateTimeFormatter.ISO_INSTANT.format(test);
1215                 fail();
1216             } catch (Exception ex) {
1217                 assertTrue(expectedEx.isInstance(ex));
1218             }
1219         }
1220     }
1221 
1222     @Test(dataProvider="sample_isoInstant")
test_parse_isoInstant( long instantSecs, Integer nano, String input, Class<?> invalid)1223     public void test_parse_isoInstant(
1224             long instantSecs, Integer nano, String input, Class<?> invalid) {
1225         if (input != null) {
1226             TemporalAccessor parsed = DateTimeFormatter.ISO_INSTANT.parseUnresolved(input, new ParsePosition(0));
1227             assertEquals(parsed.getLong(INSTANT_SECONDS), instantSecs);
1228             assertEquals(parsed.getLong(NANO_OF_SECOND), (nano == null ? 0 : nano));
1229         }
1230     }
1231 
1232     @Test
test_isoInstant_basics()1233     public void test_isoInstant_basics() {
1234         assertEquals(DateTimeFormatter.ISO_INSTANT.getChronology(), null);
1235         assertEquals(DateTimeFormatter.ISO_INSTANT.getZone(), null);
1236         assertEquals(DateTimeFormatter.ISO_INSTANT.getResolverStyle(), ResolverStyle.STRICT);
1237     }
1238 
1239     //-----------------------------------------------------------------------
1240     //-----------------------------------------------------------------------
1241     //-----------------------------------------------------------------------
1242     @DataProvider(name="rfc")
data_rfc()1243     Object[][] data_rfc() {
1244         return new Object[][] {
1245             {LocalDateTime.of(2008, 6, 3, 11, 5, 30), "Z", "Tue, 3 Jun 2008 11:05:30 GMT"},
1246             {LocalDateTime.of(2008, 6, 30, 11, 5, 30), "Z", "Mon, 30 Jun 2008 11:05:30 GMT"},
1247             {LocalDateTime.of(2008, 6, 3, 11, 5, 30), "+02:00", "Tue, 3 Jun 2008 11:05:30 +0200"},
1248             {LocalDateTime.of(2008, 6, 30, 11, 5, 30), "-03:00", "Mon, 30 Jun 2008 11:05:30 -0300"},
1249         };
1250     }
1251 
1252     @Test(dataProvider="rfc")
test_print_rfc1123(LocalDateTime base, String offsetId, String expected)1253     public void test_print_rfc1123(LocalDateTime base, String offsetId, String expected) {
1254         TemporalAccessor test = buildAccessor(base, offsetId, null);
1255         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.format(test), expected);
1256     }
1257 
1258     @Test(dataProvider="rfc")
test_print_rfc1123_french(LocalDateTime base, String offsetId, String expected)1259     public void test_print_rfc1123_french(LocalDateTime base, String offsetId, String expected) {
1260         TemporalAccessor test = buildAccessor(base, offsetId, null);
1261         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(Locale.FRENCH).format(test), expected);
1262     }
1263 
1264     @Test(expectedExceptions=DateTimeException.class)
test_print_rfc1123_missingField()1265     public void test_print_rfc1123_missingField() {
1266         TemporalAccessor test = YearMonth.of(2008, 6);
1267         DateTimeFormatter.RFC_1123_DATE_TIME.format(test);
1268     }
1269 
1270     @Test
test_rfc1123_basics()1271     public void test_rfc1123_basics() {
1272         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
1273         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getZone(), null);
1274         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getResolverStyle(), ResolverStyle.SMART);
1275     }
1276 
1277     //-----------------------------------------------------------------------
1278     //-----------------------------------------------------------------------
1279     //-----------------------------------------------------------------------
createDate(Integer year, Integer month, Integer day)1280     private Expected createDate(Integer year, Integer month, Integer day) {
1281         Expected test = new Expected();
1282         if (year != null) {
1283             test.fieldValues.put(YEAR, (long) year);
1284         }
1285         if (month != null) {
1286             test.fieldValues.put(MONTH_OF_YEAR, (long) month);
1287         }
1288         if (day != null) {
1289             test.fieldValues.put(DAY_OF_MONTH, (long) day);
1290         }
1291         return test;
1292     }
1293 
createTime(Integer hour, Integer min, Integer sec, Integer nano)1294     private Expected createTime(Integer hour, Integer min, Integer sec, Integer nano) {
1295         Expected test = new Expected();
1296         if (hour != null) {
1297             test.fieldValues.put(HOUR_OF_DAY, (long) hour);
1298         }
1299         if (min != null) {
1300             test.fieldValues.put(MINUTE_OF_HOUR, (long) min);
1301         }
1302         if (sec != null) {
1303             test.fieldValues.put(SECOND_OF_MINUTE, (long) sec);
1304         }
1305         if (nano != null) {
1306             test.fieldValues.put(NANO_OF_SECOND, (long) nano);
1307         }
1308         return test;
1309     }
1310 
createDateTime( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano)1311     private Expected createDateTime(
1312             Integer year, Integer month, Integer day,
1313             Integer hour, Integer min, Integer sec, Integer nano) {
1314         Expected test = new Expected();
1315         if (year != null) {
1316             test.fieldValues.put(YEAR, (long) year);
1317         }
1318         if (month != null) {
1319             test.fieldValues.put(MONTH_OF_YEAR, (long) month);
1320         }
1321         if (day != null) {
1322             test.fieldValues.put(DAY_OF_MONTH, (long) day);
1323         }
1324         if (hour != null) {
1325             test.fieldValues.put(HOUR_OF_DAY, (long) hour);
1326         }
1327         if (min != null) {
1328             test.fieldValues.put(MINUTE_OF_HOUR, (long) min);
1329         }
1330         if (sec != null) {
1331             test.fieldValues.put(SECOND_OF_MINUTE, (long) sec);
1332         }
1333         if (nano != null) {
1334             test.fieldValues.put(NANO_OF_SECOND, (long) nano);
1335         }
1336         return test;
1337     }
1338 
buildAccessor( Integer year, Integer month, Integer day, Integer hour, Integer min, Integer sec, Integer nano, String offsetId, String zoneId)1339     private TemporalAccessor buildAccessor(
1340                     Integer year, Integer month, Integer day,
1341                     Integer hour, Integer min, Integer sec, Integer nano,
1342                     String offsetId, String zoneId) {
1343         MockAccessor mock = new MockAccessor();
1344         if (year != null) {
1345             mock.fields.put(YEAR, (long) year);
1346         }
1347         if (month != null) {
1348             mock.fields.put(MONTH_OF_YEAR, (long) month);
1349         }
1350         if (day != null) {
1351             mock.fields.put(DAY_OF_MONTH, (long) day);
1352         }
1353         if (hour != null) {
1354             mock.fields.put(HOUR_OF_DAY, (long) hour);
1355         }
1356         if (min != null) {
1357             mock.fields.put(MINUTE_OF_HOUR, (long) min);
1358         }
1359         if (sec != null) {
1360             mock.fields.put(SECOND_OF_MINUTE, (long) sec);
1361         }
1362         if (nano != null) {
1363             mock.fields.put(NANO_OF_SECOND, (long) nano);
1364         }
1365         mock.setOffset(offsetId);
1366         mock.setZone(zoneId);
1367         return mock;
1368     }
1369 
buildAccessor(LocalDateTime base, String offsetId, String zoneId)1370     private TemporalAccessor buildAccessor(LocalDateTime base, String offsetId, String zoneId) {
1371         MockAccessor mock = new MockAccessor();
1372         mock.setFields(base);
1373         mock.setOffset(offsetId);
1374         mock.setZone(zoneId);
1375         return mock;
1376     }
1377 
buildAccessor(LocalDate base, String offsetId, String zoneId)1378     private TemporalAccessor buildAccessor(LocalDate base, String offsetId, String zoneId) {
1379         MockAccessor mock = new MockAccessor();
1380         mock.setFields(base);
1381         mock.setOffset(offsetId);
1382         mock.setZone(zoneId);
1383         return mock;
1384     }
1385 
buildAccessorInstant(long instantSecs, Integer nano)1386     private TemporalAccessor buildAccessorInstant(long instantSecs, Integer nano) {
1387         MockAccessor mock = new MockAccessor();
1388         mock.fields.put(INSTANT_SECONDS, instantSecs);
1389         if (nano != null) {
1390             mock.fields.put(NANO_OF_SECOND, (long) nano);
1391         }
1392         return mock;
1393     }
1394 
buildCalendrical(Expected expected, String offsetId, String zoneId)1395     private void buildCalendrical(Expected expected, String offsetId, String zoneId) {
1396         if (offsetId != null) {
1397             expected.add(ZoneOffset.of(offsetId));
1398         }
1399         if (zoneId != null) {
1400             expected.zone = ZoneId.of(zoneId);
1401         }
1402     }
1403 
assertParseMatch(TemporalAccessor parsed, Expected expected)1404     private void assertParseMatch(TemporalAccessor parsed, Expected expected) {
1405         for (TemporalField field : expected.fieldValues.keySet()) {
1406             assertEquals(parsed.isSupported(field), true);
1407             parsed.getLong(field);
1408         }
1409         assertEquals(parsed.query(TemporalQueries.chronology()), expected.chrono);
1410         assertEquals(parsed.query(TemporalQueries.zoneId()), expected.zone);
1411     }
1412 
1413     //-------------------------------------------------------------------------
1414     static class MockAccessor implements TemporalAccessor {
1415         Map<TemporalField, Long> fields = new HashMap<>();
1416         ZoneId zoneId;
1417 
setFields(LocalDate dt)1418         void setFields(LocalDate dt) {
1419             if (dt != null) {
1420                 fields.put(YEAR, (long) dt.getYear());
1421                 fields.put(MONTH_OF_YEAR, (long) dt.getMonthValue());
1422                 fields.put(DAY_OF_MONTH, (long) dt.getDayOfMonth());
1423                 fields.put(DAY_OF_YEAR, (long) dt.getDayOfYear());
1424                 fields.put(DAY_OF_WEEK, (long) dt.getDayOfWeek().getValue());
1425                 fields.put(IsoFields.WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_BASED_YEAR));
1426                 fields.put(IsoFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
1427             }
1428         }
1429 
setFields(LocalDateTime dt)1430         void setFields(LocalDateTime dt) {
1431             if (dt != null) {
1432                 fields.put(YEAR, (long) dt.getYear());
1433                 fields.put(MONTH_OF_YEAR, (long) dt.getMonthValue());
1434                 fields.put(DAY_OF_MONTH, (long) dt.getDayOfMonth());
1435                 fields.put(DAY_OF_YEAR, (long) dt.getDayOfYear());
1436                 fields.put(DAY_OF_WEEK, (long) dt.getDayOfWeek().getValue());
1437                 fields.put(IsoFields.WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_BASED_YEAR));
1438                 fields.put(IsoFields.WEEK_OF_WEEK_BASED_YEAR, dt.getLong(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
1439                 fields.put(HOUR_OF_DAY, (long) dt.getHour());
1440                 fields.put(MINUTE_OF_HOUR, (long) dt.getMinute());
1441                 fields.put(SECOND_OF_MINUTE, (long) dt.getSecond());
1442                 fields.put(NANO_OF_SECOND, (long) dt.getNano());
1443             }
1444         }
1445 
setOffset(String offsetId)1446         void setOffset(String offsetId) {
1447             if (offsetId != null) {
1448                 this.fields.put(OFFSET_SECONDS, (long) ZoneOffset.of(offsetId).getTotalSeconds());
1449             }
1450         }
1451 
setZone(String zoneId)1452         void setZone(String zoneId) {
1453             if (zoneId != null) {
1454                 this.zoneId = ZoneId.of(zoneId);
1455             }
1456         }
1457 
1458         @Override
isSupported(TemporalField field)1459         public boolean isSupported(TemporalField field) {
1460             return fields.containsKey(field);
1461         }
1462 
1463         @Override
getLong(TemporalField field)1464         public long getLong(TemporalField field) {
1465             try {
1466                 return fields.get(field);
1467             } catch (NullPointerException ex) {
1468                 throw new DateTimeException("Field missing: " + field);
1469             }
1470         }
1471 
1472         @SuppressWarnings("unchecked")
1473         @Override
query(TemporalQuery<R> query)1474         public <R> R query(TemporalQuery<R> query) {
1475             if (query == TemporalQueries.zoneId()) {
1476                 return (R) zoneId;
1477             }
1478             return TemporalAccessor.super.query(query);
1479         }
1480 
1481         @Override
toString()1482         public String toString() {
1483             return fields + (zoneId != null ? " " + zoneId : "");
1484         }
1485     }
1486 
1487     //-----------------------------------------------------------------------
1488     static class Expected {
1489         Map<TemporalField, Long> fieldValues = new HashMap<>();
1490         ZoneId zone;
1491         Chronology chrono;
1492 
Expected()1493         Expected() {
1494         }
1495 
Expected(TemporalField field1, long value1, TemporalField field2, long value2)1496         Expected(TemporalField field1, long value1, TemporalField field2, long value2) {
1497             fieldValues.put(field1, value1);
1498             fieldValues.put(field2, value2);
1499         }
1500 
add(ZoneOffset offset)1501         void add(ZoneOffset offset) {
1502             fieldValues.put(OFFSET_SECONDS, (long) offset.getTotalSeconds());
1503         }
1504     }
1505 }
1506