View Javadoc
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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /*
27   * This file is available under and governed by the GNU General Public
28   * License version 2 only, as published by the Free Software Foundation.
29   * However, the following notice accompanied the original version of this
30   * file:
31   *
32   * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
33   *
34   * All rights reserved.
35   *
36   * Redistribution and use in source and binary forms, with or without
37   * modification, are permitted provided that the following conditions are met:
38   *
39   *  * Redistributions of source code must retain the above copyright notice,
40   *    this list of conditions and the following disclaimer.
41   *
42   *  * Redistributions in binary form must reproduce the above copyright notice,
43   *    this list of conditions and the following disclaimer in the documentation
44   *    and/or other materials provided with the distribution.
45   *
46   *  * Neither the name of JSR-310 nor the names of its contributors
47   *    may be used to endorse or promote products derived from this software
48   *    without specific prior written permission.
49   *
50   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61   */
62  package java.time.format;
63  
64  import static java.time.temporal.ChronoField.DAY_OF_MONTH;
65  import static java.time.temporal.ChronoField.DAY_OF_WEEK;
66  import static java.time.temporal.ChronoField.DAY_OF_YEAR;
67  import static java.time.temporal.ChronoField.HOUR_OF_DAY;
68  import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
69  import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
70  import static java.time.temporal.ChronoField.NANO_OF_SECOND;
71  import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
72  import static java.time.temporal.ChronoField.YEAR;
73  
74  import java.io.IOException;
75  import java.text.FieldPosition;
76  import java.text.Format;
77  import java.text.ParseException;
78  import java.text.ParsePosition;
79  import java.time.DateTimeException;
80  import java.time.Period;
81  import java.time.ZoneId;
82  import java.time.ZoneOffset;
83  import java.time.chrono.Chronology;
84  import java.time.chrono.IsoChronology;
85  import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser;
86  import java.time.temporal.ChronoField;
87  import java.time.temporal.IsoFields;
88  import java.time.temporal.TemporalAccessor;
89  import java.time.temporal.TemporalField;
90  import java.time.temporal.TemporalQuery;
91  import java.util.Arrays;
92  import java.util.Collections;
93  import java.util.HashMap;
94  import java.util.HashSet;
95  import java.util.Locale;
96  import java.util.Map;
97  import java.util.Objects;
98  import java.util.Set;
99  
100 /**
101  * Formatter for printing and parsing date-time objects.
102  * <p>
103  * This class provides the main application entry point for printing and parsing
104  * and provides common implementations of {@code DateTimeFormatter}:
105  * <ul>
106  * <li>Using predefined constants, such as {@link #ISO_LOCAL_DATE}</li>
107  * <li>Using pattern letters, such as {@code uuuu-MMM-dd}</li>
108  * <li>Using localized styles, such as {@code long} or {@code medium}</li>
109  * </ul>
110  * <p>
111  * More complex formatters are provided by
112  * {@link DateTimeFormatterBuilder DateTimeFormatterBuilder}.
113  *
114  * <p>
115  * The main date-time classes provide two methods - one for formatting,
116  * {@code format(DateTimeFormatter formatter)}, and one for parsing,
117  * {@code parse(CharSequence text, DateTimeFormatter formatter)}.
118  * <p>For example:
119  * <blockquote><pre>
120  *  String text = date.toString(formatter);
121  *  LocalDate date = LocalDate.parse(text, formatter);
122  * </pre></blockquote>
123  * <p>
124  * In addition to the format, formatters can be created with desired Locale,
125  * Chronology, ZoneId, and DecimalStyle.
126  * <p>
127  * The {@link #withLocale withLocale} method returns a new formatter that
128  * overrides the locale. The locale affects some aspects of formatting and
129  * parsing. For example, the {@link #ofLocalizedDate ofLocalizedDate} provides a
130  * formatter that uses the locale specific date format.
131  * <p>
132  * The {@link #withChronology withChronology} method returns a new formatter
133  * that overrides the chronology. If overridden, the date-time value is
134  * converted to the chronology before formatting. During parsing the date-time
135  * value is converted to the chronology before it is returned.
136  * <p>
137  * The {@link #withZone withZone} method returns a new formatter that overrides
138  * the zone. If overridden, the date-time value is converted to a ZonedDateTime
139  * with the requested ZoneId before formatting. During parsing the ZoneId is
140  * applied before the value is returned.
141  * <p>
142  * The {@link #withDecimalStyle withDecimalStyle} method returns a new formatter that
143  * overrides the {@link DecimalStyle}. The DecimalStyle symbols are used for
144  * formatting and parsing.
145  * <p>
146  * Some applications may need to use the older {@link Format java.text.Format}
147  * class for formatting. The {@link #toFormat()} method returns an
148  * implementation of {@code java.text.Format}.
149  *
150  * <h3 id="predefined">Predefined Formatters</h3>
151  * <table summary="Predefined Formatters" cellpadding="2" cellspacing="3" border="0" >
152  * <thead>
153  * <tr class="tableSubHeadingColor">
154  * <th class="colFirst" align="left">Formatter</th>
155  * <th class="colFirst" align="left">Description</th>
156  * <th class="colLast" align="left">Example</th>
157  * </tr>
158  * </thead>
159  * <tbody>
160  * <tr class="rowColor">
161  * <td>{@link #ofLocalizedDate ofLocalizedDate(dateStyle)} </td>
162  * <td> Formatter with date style from the locale </td>
163  * <td> '2011-12-03'</td>
164  * </tr>
165  * <tr class="altColor">
166  * <td> {@link #ofLocalizedTime ofLocalizedTime(timeStyle)} </td>
167  * <td> Formatter with time style from the locale </td>
168  * <td> '10:15:30'</td>
169  * </tr>
170  * <tr class="rowColor">
171  * <td> {@link #ofLocalizedDateTime ofLocalizedDateTime(dateTimeStyle)} </td>
172  * <td> Formatter with a style for date and time from the locale</td>
173  * <td> '3 Jun 2008 11:05:30'</td>
174  * </tr>
175  * <tr class="altColor">
176  * <td> {@link #ofLocalizedDateTime ofLocalizedDateTime(dateStyle,timeStyle)}
177  * </td>
178  * <td> Formatter with date and time styles from the locale </td>
179  * <td> '3 Jun 2008 11:05'</td>
180  * </tr>
181  * <tr class="rowColor">
182  * <td> {@link #BASIC_ISO_DATE}</td>
183  * <td>Basic ISO date </td> <td>'20111203'</td>
184  * </tr>
185  * <tr class="altColor">
186  * <td> {@link #ISO_LOCAL_DATE}</td>
187  * <td> ISO Local Date </td>
188  * <td>'2011-12-03'</td>
189  * </tr>
190  * <tr class="rowColor">
191  * <td> {@link #ISO_OFFSET_DATE}</td>
192  * <td> ISO Date with offset </td>
193  * <td>'2011-12-03+01:00'</td>
194  * </tr>
195  * <tr class="altColor">
196  * <td> {@link #ISO_DATE}</td>
197  * <td> ISO Date with or without offset </td>
198  * <td> '2011-12-03+01:00'; '2011-12-03'</td>
199  * </tr>
200  * <tr class="rowColor">
201  * <td> {@link #ISO_LOCAL_TIME}</td>
202  * <td> Time without offset </td>
203  * <td>'10:15:30'</td>
204  * </tr>
205  * <tr class="altColor">
206  * <td> {@link #ISO_OFFSET_TIME}</td>
207  * <td> Time with offset </td>
208  * <td>'10:15:30+01:00'</td>
209  * </tr>
210  * <tr class="rowColor">
211  * <td> {@link #ISO_TIME}</td>
212  * <td> Time with or without offset </td>
213  * <td>'10:15:30+01:00'; '10:15:30'</td>
214  * </tr>
215  * <tr class="altColor">
216  * <td> {@link #ISO_LOCAL_DATE_TIME}</td>
217  * <td> ISO Local Date and Time </td>
218  * <td>'2011-12-03T10:15:30'</td>
219  * </tr>
220  * <tr class="rowColor">
221  * <td> {@link #ISO_OFFSET_DATE_TIME}</td>
222  * <td> Date Time with Offset
223  * </td><td>2011-12-03T10:15:30+01:00'</td>
224  * </tr>
225  * <tr class="altColor">
226  * <td> {@link #ISO_ZONED_DATE_TIME}</td>
227  * <td> Zoned Date Time </td>
228  * <td>'2011-12-03T10:15:30+01:00[Europe/Paris]'</td>
229  * </tr>
230  * <tr class="rowColor">
231  * <td> {@link #ISO_DATE_TIME}</td>
232  * <td> Date and time with ZoneId </td>
233  * <td>'2011-12-03T10:15:30+01:00[Europe/Paris]'</td>
234  * </tr>
235  * <tr class="altColor">
236  * <td> {@link #ISO_ORDINAL_DATE}</td>
237  * <td> Year and day of year </td>
238  * <td>'2012-337'</td>
239  * </tr>
240  * <tr class="rowColor">
241  * <td> {@link #ISO_WEEK_DATE}</td>
242  * <td> Year and Week </td>
243  * <td>2012-W48-6'</td></tr>
244  * <tr class="altColor">
245  * <td> {@link #ISO_INSTANT}</td>
246  * <td> Date and Time of an Instant </td>
247  * <td>'2011-12-03T10:15:30Z' </td>
248  * </tr>
249  * <tr class="rowColor">
250  * <td> {@link #RFC_1123_DATE_TIME}</td>
251  * <td> RFC 1123 / RFC 822 </td>
252  * <td>'Tue, 3 Jun 2008 11:05:30 GMT'</td>
253  * </tr>
254  * </tbody>
255  * </table>
256  *
257  * <h3 id="patterns">Patterns for Formatting and Parsing</h3>
258  * Patterns are based on a simple sequence of letters and symbols.
259  * A pattern is used to create a Formatter using the
260  * {@link #ofPattern(String)} and {@link #ofPattern(String, Locale)} methods.
261  * For example,
262  * {@code "d MMM uuuu"} will format 2011-12-03 as '3&nbsp;Dec&nbsp;2011'.
263  * A formatter created from a pattern can be used as many times as necessary,
264  * it is immutable and is thread-safe.
265  * <p>
266  * For example:
267  * <blockquote><pre>
268  *  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
269  *  String text = date.toString(formatter);
270  *  LocalDate date = LocalDate.parse(text, formatter);
271  * </pre></blockquote>
272  * <p>
273  * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The
274  * following pattern letters are defined:
275  * <pre>
276  *  Symbol  Meaning                     Presentation      Examples
277  *  ------  -------                     ------------      -------
278  *   G       era                         text              AD; Anno Domini; A
279  *   u       year                        year              2004; 04
280  *   y       year-of-era                 year              2004; 04
281  *   D       day-of-year                 number            189
282  *   M/L     month-of-year               number/text       7; 07; Jul; July; J
283  *   d       day-of-month                number            10
284  *
285  *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
286  *   Y       week-based-year             year              1996; 96
287  *   w       week-of-week-based-year     number            27
288  *   W       week-of-month               number            4
289  *   E       day-of-week                 text              Tue; Tuesday; T
290  *   e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
291  *   F       week-of-month               number            3
292  *
293  *   a       am-pm-of-day                text              PM
294  *   h       clock-hour-of-am-pm (1-12)  number            12
295  *   K       hour-of-am-pm (0-11)        number            0
296  *   k       clock-hour-of-am-pm (1-24)  number            0
297  *
298  *   H       hour-of-day (0-23)          number            0
299  *   m       minute-of-hour              number            30
300  *   s       second-of-minute            number            55
301  *   S       fraction-of-second          fraction          978
302  *   A       milli-of-day                number            1234
303  *   n       nano-of-second              number            987654321
304  *   N       nano-of-day                 number            1234000000
305  *
306  *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
307  *   z       time-zone name              zone-name         Pacific Standard Time; PST
308  *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
309  *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
310  *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
311  *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
312  *
313  *   p       pad next                    pad modifier      1
314  *
315  *   '       escape for text             delimiter
316  *   ''      single quote                literal           '
317  *   [       optional section start
318  *   ]       optional section end
319  *   #       reserved for future use
320  *   {       reserved for future use
321  *   }       reserved for future use
322  * </pre>
323  * <p>
324  * The count of pattern letters determines the format.
325  * <p>
326  * <b>Text</b>: The text style is determined based on the number of pattern
327  * letters used. Less than 4 pattern letters will use the
328  * {@link TextStyle#SHORT short form}. Exactly 4 pattern letters will use the
329  * {@link TextStyle#FULL full form}. Exactly 5 pattern letters will use the
330  * {@link TextStyle#NARROW narrow form}.
331  * Pattern letters 'L', 'c', and 'q' specify the stand-alone form of the text styles.
332  * <p>
333  * <b>Number</b>: If the count of letters is one, then the value is output using
334  * the minimum number of digits and without padding. Otherwise, the count of digits
335  * is used as the width of the output field, with the value zero-padded as necessary.
336  * The following pattern letters have constraints on the count of letters.
337  * Only one letter of 'c' and 'F' can be specified.
338  * Up to two letters of 'd', 'H', 'h', 'K', 'k', 'm', and 's' can be specified.
339  * Up to three letters of 'D' can be specified.
340  * <p>
341  * <b>Number/Text</b>: If the count of pattern letters is 3 or greater, use the
342  * Text rules above. Otherwise use the Number rules above.
343  * <p>
344  * <b>Fraction</b>: Outputs the nano-of-second field as a fraction-of-second.
345  * The nano-of-second value has nine digits, thus the count of pattern letters
346  * is from 1 to 9. If it is less than 9, then the nano-of-second value is
347  * truncated, with only the most significant digits being output. When parsing
348  * in strict mode, the number of parsed digits must match the count of pattern
349  * letters. When parsing in lenient mode, the number of parsed digits must be at
350  * least the count of pattern letters, up to 9 digits.
351  * <p>
352  * <b>Year</b>: The count of letters determines the minimum field width below
353  * which padding is used. If the count of letters is two, then a
354  * {@link DateTimeFormatterBuilder#appendValueReduced reduced} two digit form is
355  * used. For printing, this outputs the rightmost two digits. For parsing, this
356  * will parse using the base value of 2000, resulting in a year within the range
357  * 2000 to 2099 inclusive. If the count of letters is less than four (but not
358  * two), then the sign is only output for negative years as per
359  * {@link SignStyle#NORMAL}. Otherwise, the sign is output if the pad width is
360  * exceeded, as per {@link SignStyle#EXCEEDS_PAD}.
361  * <p>
362  * <b>ZoneId</b>: This outputs the time-zone ID, such as 'Europe/Paris'. If the
363  * count of letters is two, then the time-zone ID is output. Any other count of
364  * letters throws {@code IllegalArgumentException}.
365  * <p>
366  * <b>Zone names</b>: This outputs the display name of the time-zone ID. If the
367  * count of letters is one, two or three, then the short name is output. If the
368  * count of letters is four, then the full name is output. Five or more letters
369  * throws {@code IllegalArgumentException}.
370  * <p>
371  * <b>Offset X and x</b>: This formats the offset based on the number of pattern
372  * letters. One letter outputs just the hour, such as '+01', unless the minute
373  * is non-zero in which case the minute is also output, such as '+0130'. Two
374  * letters outputs the hour and minute, without a colon, such as '+0130'. Three
375  * letters outputs the hour and minute, with a colon, such as '+01:30'. Four
376  * letters outputs the hour and minute and optional second, without a colon,
377  * such as '+013015'. Five letters outputs the hour and minute and optional
378  * second, with a colon, such as '+01:30:15'. Six or more letters throws
379  * {@code IllegalArgumentException}. Pattern letter 'X' (upper case) will output
380  * 'Z' when the offset to be output would be zero, whereas pattern letter 'x'
381  * (lower case) will output '+00', '+0000', or '+00:00'.
382  * <p>
383  * <b>Offset O</b>: This formats the localized offset based on the number of
384  * pattern letters. One letter outputs the {@linkplain TextStyle#SHORT short}
385  * form of the localized offset, which is localized offset text, such as 'GMT',
386  * with hour without leading zero, optional 2-digit minute and second if
387  * non-zero, and colon, for example 'GMT+8'. Four letters outputs the
388  * {@linkplain TextStyle#FULL full} form, which is localized offset text,
389  * such as 'GMT, with 2-digit hour and minute field, optional second field
390  * if non-zero, and colon, for example 'GMT+08:00'. Any other count of letters
391  * throws {@code IllegalArgumentException}.
392  * <p>
393  * <b>Offset Z</b>: This formats the offset based on the number of pattern
394  * letters. One, two or three letters outputs the hour and minute, without a
395  * colon, such as '+0130'. The output will be '+0000' when the offset is zero.
396  * Four letters outputs the {@linkplain TextStyle#FULL full} form of localized
397  * offset, equivalent to four letters of Offset-O. The output will be the
398  * corresponding localized offset text if the offset is zero. Five
399  * letters outputs the hour, minute, with optional second if non-zero, with
400  * colon. It outputs 'Z' if the offset is zero.
401  * Six or more letters throws {@code IllegalArgumentException}.
402  * <p>
403  * <b>Optional section</b>: The optional section markers work exactly like
404  * calling {@link DateTimeFormatterBuilder#optionalStart()} and
405  * {@link DateTimeFormatterBuilder#optionalEnd()}.
406  * <p>
407  * <b>Pad modifier</b>: Modifies the pattern that immediately follows to be
408  * padded with spaces. The pad width is determined by the number of pattern
409  * letters. This is the same as calling
410  * {@link DateTimeFormatterBuilder#padNext(int)}.
411  * <p>
412  * For example, 'ppH' outputs the hour-of-day padded on the left with spaces to
413  * a width of 2.
414  * <p>
415  * Any unrecognized letter is an error. Any non-letter character, other than
416  * '[', ']', '{', '}', '#' and the single quote will be output directly.
417  * Despite this, it is recommended to use single quotes around all characters
418  * that you want to output directly to ensure that future changes do not break
419  * your application.
420  *
421  * <h3 id="resolving">Resolving</h3>
422  * Parsing is implemented as a two-phase operation.
423  * First, the text is parsed using the layout defined by the formatter, producing
424  * a {@code Map} of field to value, a {@code ZoneId} and a {@code Chronology}.
425  * Second, the parsed data is <em>resolved</em>, by validating, combining and
426  * simplifying the various fields into more useful ones.
427  * <p>
428  * Five parsing methods are supplied by this class.
429  * Four of these perform both the parse and resolve phases.
430  * The fifth method, {@link #parseUnresolved(CharSequence, ParsePosition)},
431  * only performs the first phase, leaving the result unresolved.
432  * As such, it is essentially a low-level operation.
433  * <p>
434  * The resolve phase is controlled by two parameters, set on this class.
435  * <p>
436  * The {@link ResolverStyle} is an enum that offers three different approaches,
437  * strict, smart and lenient. The smart option is the default.
438  * It can be set using {@link #withResolverStyle(ResolverStyle)}.
439  * <p>
440  * The {@link #withResolverFields(TemporalField...)} parameter allows the
441  * set of fields that will be resolved to be filtered before resolving starts.
442  * For example, if the formatter has parsed a year, month, day-of-month
443  * and day-of-year, then there are two approaches to resolve a date:
444  * (year + month + day-of-month) and (year + day-of-year).
445  * The resolver fields allows one of the two approaches to be selected.
446  * If no resolver fields are set then both approaches must result in the same date.
447  * <p>
448  * Resolving separate fields to form a complete date and time is a complex
449  * process with behaviour distributed across a number of classes.
450  * It follows these steps:
451  * <ol>
452  * <li>The chronology is determined.
453  * The chronology of the result is either the chronology that was parsed,
454  * or if no chronology was parsed, it is the chronology set on this class,
455  * or if that is null, it is {@code IsoChronology}.
456  * <li>The {@code ChronoField} date fields are resolved.
457  * This is achieved using {@link Chronology#resolveDate(Map, ResolverStyle)}.
458  * Documentation about field resolution is located in the implementation
459  * of {@code Chronology}.
460  * <li>The {@code ChronoField} time fields are resolved.
461  * This is documented on {@link ChronoField} and is the same for all chronologies.
462  * <li>Any fields that are not {@code ChronoField} are processed.
463  * This is achieved using {@link TemporalField#resolve(Map, TemporalAccessor, ResolverStyle)}.
464  * Documentation about field resolution is located in the implementation
465  * of {@code TemporalField}.
466  * <li>The {@code ChronoField} date and time fields are re-resolved.
467  * This allows fields in step four to produce {@code ChronoField} values
468  * and have them be processed into dates and times.
469  * <li>A {@code LocalTime} is formed if there is at least an hour-of-day available.
470  * This involves providing default values for minute, second and fraction of second.
471  * <li>Any remaining unresolved fields are cross-checked against any
472  * date and/or time that was resolved. Thus, an earlier stage would resolve
473  * (year + month + day-of-month) to a date, and this stage would check that
474  * day-of-week was valid for the date.
475  * <li>If an {@linkplain #parsedExcessDays() excess number of days}
476  * was parsed then it is added to the date if a date is available.
477  * </ol>
478  *
479  * @implSpec
480  * This class is immutable and thread-safe.
481  *
482  * @since 1.8
483  */
484 public final class DateTimeFormatter {
485 
486     /**
487      * The printer and/or parser to use, not null.
488      */
489     private final CompositePrinterParser printerParser;
490     /**
491      * The locale to use for formatting, not null.
492      */
493     private final Locale locale;
494     /**
495      * The symbols to use for formatting, not null.
496      */
497     private final DecimalStyle decimalStyle;
498     /**
499      * The resolver style to use, not null.
500      */
501     private final ResolverStyle resolverStyle;
502     /**
503      * The fields to use in resolving, null for all fields.
504      */
505     private final Set<TemporalField> resolverFields;
506     /**
507      * The chronology to use for formatting, null for no override.
508      */
509     private final Chronology chrono;
510     /**
511      * The zone to use for formatting, null for no override.
512      */
513     private final ZoneId zone;
514 
515     //-----------------------------------------------------------------------
516     /**
517      * Creates a formatter using the specified pattern.
518      * <p>
519      * This method will create a formatter based on a simple
520      * <a href="#patterns">pattern of letters and symbols</a>
521      * as described in the class documentation.
522      * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.
523      * <p>
524      * The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
525      * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
526      * Alternatively use the {@link #ofPattern(String, Locale)} variant of this method.
527      * <p>
528      * The returned formatter has no override chronology or zone.
529      * It uses {@link ResolverStyle#SMART SMART} resolver style.
530      *
531      * @param pattern  the pattern to use, not null
532      * @return the formatter based on the pattern, not null
533      * @throws IllegalArgumentException if the pattern is invalid
534      * @see DateTimeFormatterBuilder#appendPattern(String)
535      */
536     public static DateTimeFormatter ofPattern(String pattern) {
537         return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
538     }
539 
540     /**
541      * Creates a formatter using the specified pattern and locale.
542      * <p>
543      * This method will create a formatter based on a simple
544      * <a href="#patterns">pattern of letters and symbols</a>
545      * as described in the class documentation.
546      * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.
547      * <p>
548      * The formatter will use the specified locale.
549      * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
550      * <p>
551      * The returned formatter has no override chronology or zone.
552      * It uses {@link ResolverStyle#SMART SMART} resolver style.
553      *
554      * @param pattern  the pattern to use, not null
555      * @param locale  the locale to use, not null
556      * @return the formatter based on the pattern, not null
557      * @throws IllegalArgumentException if the pattern is invalid
558      * @see DateTimeFormatterBuilder#appendPattern(String)
559      */
560     public static DateTimeFormatter ofPattern(String pattern, Locale locale) {
561         return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
562     }
563 
564     //-----------------------------------------------------------------------
565     /**
566      * Returns a locale specific date format for the ISO chronology.
567      * <p>
568      * This returns a formatter that will format or parse a date.
569      * The exact format pattern used varies by locale.
570      * <p>
571      * The locale is determined from the formatter. The formatter returned directly by
572      * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
573      * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
574      * on the result of this method.
575      * <p>
576      * Note that the localized pattern is looked up lazily.
577      * This {@code DateTimeFormatter} holds the style required and the locale,
578      * looking up the pattern required on demand.
579      * <p>
580      * The returned formatter has a chronology of ISO set to ensure dates in
581      * other calendar systems are correctly converted.
582      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
583      *
584      * @param dateStyle  the formatter style to obtain, not null
585      * @return the date formatter, not null
586      */
587     public static DateTimeFormatter ofLocalizedDate(FormatStyle dateStyle) {
588         Objects.requireNonNull(dateStyle, "dateStyle");
589         return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null)
590                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
591     }
592 
593     /**
594      * Returns a locale specific time format for the ISO chronology.
595      * <p>
596      * This returns a formatter that will format or parse a time.
597      * The exact format pattern used varies by locale.
598      * <p>
599      * The locale is determined from the formatter. The formatter returned directly by
600      * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
601      * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
602      * on the result of this method.
603      * <p>
604      * Note that the localized pattern is looked up lazily.
605      * This {@code DateTimeFormatter} holds the style required and the locale,
606      * looking up the pattern required on demand.
607      * <p>
608      * The returned formatter has a chronology of ISO set to ensure dates in
609      * other calendar systems are correctly converted.
610      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
611      *
612      * @param timeStyle  the formatter style to obtain, not null
613      * @return the time formatter, not null
614      */
615     public static DateTimeFormatter ofLocalizedTime(FormatStyle timeStyle) {
616         Objects.requireNonNull(timeStyle, "timeStyle");
617         return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle)
618                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
619     }
620 
621     /**
622      * Returns a locale specific date-time formatter for the ISO chronology.
623      * <p>
624      * This returns a formatter that will format or parse a date-time.
625      * The exact format pattern used varies by locale.
626      * <p>
627      * The locale is determined from the formatter. The formatter returned directly by
628      * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
629      * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
630      * on the result of this method.
631      * <p>
632      * Note that the localized pattern is looked up lazily.
633      * This {@code DateTimeFormatter} holds the style required and the locale,
634      * looking up the pattern required on demand.
635      * <p>
636      * The returned formatter has a chronology of ISO set to ensure dates in
637      * other calendar systems are correctly converted.
638      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
639      *
640      * @param dateTimeStyle  the formatter style to obtain, not null
641      * @return the date-time formatter, not null
642      */
643     public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateTimeStyle) {
644         Objects.requireNonNull(dateTimeStyle, "dateTimeStyle");
645         return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle)
646                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
647     }
648 
649     /**
650      * Returns a locale specific date and time format for the ISO chronology.
651      * <p>
652      * This returns a formatter that will format or parse a date-time.
653      * The exact format pattern used varies by locale.
654      * <p>
655      * The locale is determined from the formatter. The formatter returned directly by
656      * this method will use the {@link Locale#getDefault() default FORMAT locale}.
657      * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
658      * on the result of this method.
659      * <p>
660      * Note that the localized pattern is looked up lazily.
661      * This {@code DateTimeFormatter} holds the style required and the locale,
662      * looking up the pattern required on demand.
663      * <p>
664      * The returned formatter has a chronology of ISO set to ensure dates in
665      * other calendar systems are correctly converted.
666      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
667      *
668      * @param dateStyle  the date formatter style to obtain, not null
669      * @param timeStyle  the time formatter style to obtain, not null
670      * @return the date, time or date-time formatter, not null
671      */
672     public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateStyle, FormatStyle timeStyle) {
673         Objects.requireNonNull(dateStyle, "dateStyle");
674         Objects.requireNonNull(timeStyle, "timeStyle");
675         return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle)
676                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
677     }
678 
679     //-----------------------------------------------------------------------
680     /**
681      * The ISO date formatter that formats or parses a date without an
682      * offset, such as '2011-12-03'.
683      * <p>
684      * This returns an immutable formatter capable of formatting and parsing
685      * the ISO-8601 extended local date format.
686      * The format consists of:
687      * <ul>
688      * <li>Four digits or more for the {@link ChronoField#YEAR year}.
689      * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
690      * Years outside that range will have a prefixed positive or negative symbol.
691      * <li>A dash
692      * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
693      *  This is pre-padded by zero to ensure two digits.
694      * <li>A dash
695      * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
696      *  This is pre-padded by zero to ensure two digits.
697      * </ul>
698      * <p>
699      * The returned formatter has a chronology of ISO set to ensure dates in
700      * other calendar systems are correctly converted.
701      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
702      */
703     public static final DateTimeFormatter ISO_LOCAL_DATE;
704     static {
705         ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
706                 .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
707                 .appendLiteral('-')
708                 .appendValue(MONTH_OF_YEAR, 2)
709                 .appendLiteral('-')
710                 .appendValue(DAY_OF_MONTH, 2)
711                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
712     }
713 
714     //-----------------------------------------------------------------------
715     /**
716      * The ISO date formatter that formats or parses a date with an
717      * offset, such as '2011-12-03+01:00'.
718      * <p>
719      * This returns an immutable formatter capable of formatting and parsing
720      * the ISO-8601 extended offset date format.
721      * The format consists of:
722      * <ul>
723      * <li>The {@link #ISO_LOCAL_DATE}
724      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
725      *  they will be handled even though this is not part of the ISO-8601 standard.
726      *  Parsing is case insensitive.
727      * </ul>
728      * <p>
729      * The returned formatter has a chronology of ISO set to ensure dates in
730      * other calendar systems are correctly converted.
731      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
732      */
733     public static final DateTimeFormatter ISO_OFFSET_DATE;
734     static {
735         ISO_OFFSET_DATE = new DateTimeFormatterBuilder()
736                 .parseCaseInsensitive()
737                 .append(ISO_LOCAL_DATE)
738                 .appendOffsetId()
739                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
740     }
741 
742     //-----------------------------------------------------------------------
743     /**
744      * The ISO date formatter that formats or parses a date with the
745      * offset if available, such as '2011-12-03' or '2011-12-03+01:00'.
746      * <p>
747      * This returns an immutable formatter capable of formatting and parsing
748      * the ISO-8601 extended date format.
749      * The format consists of:
750      * <ul>
751      * <li>The {@link #ISO_LOCAL_DATE}
752      * <li>If the offset is not available then the format is complete.
753      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
754      *  they will be handled even though this is not part of the ISO-8601 standard.
755      *  Parsing is case insensitive.
756      * </ul>
757      * <p>
758      * As this formatter has an optional element, it may be necessary to parse using
759      * {@link DateTimeFormatter#parseBest}.
760      * <p>
761      * The returned formatter has a chronology of ISO set to ensure dates in
762      * other calendar systems are correctly converted.
763      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
764      */
765     public static final DateTimeFormatter ISO_DATE;
766     static {
767         ISO_DATE = new DateTimeFormatterBuilder()
768                 .parseCaseInsensitive()
769                 .append(ISO_LOCAL_DATE)
770                 .optionalStart()
771                 .appendOffsetId()
772                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
773     }
774 
775     //-----------------------------------------------------------------------
776     /**
777      * The ISO time formatter that formats or parses a time without an
778      * offset, such as '10:15' or '10:15:30'.
779      * <p>
780      * This returns an immutable formatter capable of formatting and parsing
781      * the ISO-8601 extended local time format.
782      * The format consists of:
783      * <ul>
784      * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
785      *  This is pre-padded by zero to ensure two digits.
786      * <li>A colon
787      * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
788      *  This is pre-padded by zero to ensure two digits.
789      * <li>If the second-of-minute is not available then the format is complete.
790      * <li>A colon
791      * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
792      *  This is pre-padded by zero to ensure two digits.
793      * <li>If the nano-of-second is zero or not available then the format is complete.
794      * <li>A decimal point
795      * <li>One to nine digits for the {@link ChronoField#NANO_OF_SECOND nano-of-second}.
796      *  As many digits will be output as required.
797      * </ul>
798      * <p>
799      * The returned formatter has no override chronology or zone.
800      * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
801      */
802     public static final DateTimeFormatter ISO_LOCAL_TIME;
803     static {
804         ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
805                 .appendValue(HOUR_OF_DAY, 2)
806                 .appendLiteral(':')
807                 .appendValue(MINUTE_OF_HOUR, 2)
808                 .optionalStart()
809                 .appendLiteral(':')
810                 .appendValue(SECOND_OF_MINUTE, 2)
811                 .optionalStart()
812                 .appendFraction(NANO_OF_SECOND, 0, 9, true)
813                 .toFormatter(ResolverStyle.STRICT, null);
814     }
815 
816     //-----------------------------------------------------------------------
817     /**
818      * The ISO time formatter that formats or parses a time with an
819      * offset, such as '10:15+01:00' or '10:15:30+01:00'.
820      * <p>
821      * This returns an immutable formatter capable of formatting and parsing
822      * the ISO-8601 extended offset time format.
823      * The format consists of:
824      * <ul>
825      * <li>The {@link #ISO_LOCAL_TIME}
826      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
827      *  they will be handled even though this is not part of the ISO-8601 standard.
828      *  Parsing is case insensitive.
829      * </ul>
830      * <p>
831      * The returned formatter has no override chronology or zone.
832      * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
833      */
834     public static final DateTimeFormatter ISO_OFFSET_TIME;
835     static {
836         ISO_OFFSET_TIME = new DateTimeFormatterBuilder()
837                 .parseCaseInsensitive()
838                 .append(ISO_LOCAL_TIME)
839                 .appendOffsetId()
840                 .toFormatter(ResolverStyle.STRICT, null);
841     }
842 
843     //-----------------------------------------------------------------------
844     /**
845      * The ISO time formatter that formats or parses a time, with the
846      * offset if available, such as '10:15', '10:15:30' or '10:15:30+01:00'.
847      * <p>
848      * This returns an immutable formatter capable of formatting and parsing
849      * the ISO-8601 extended offset time format.
850      * The format consists of:
851      * <ul>
852      * <li>The {@link #ISO_LOCAL_TIME}
853      * <li>If the offset is not available then the format is complete.
854      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
855      *  they will be handled even though this is not part of the ISO-8601 standard.
856      *  Parsing is case insensitive.
857      * </ul>
858      * <p>
859      * As this formatter has an optional element, it may be necessary to parse using
860      * {@link DateTimeFormatter#parseBest}.
861      * <p>
862      * The returned formatter has no override chronology or zone.
863      * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
864      */
865     public static final DateTimeFormatter ISO_TIME;
866     static {
867         ISO_TIME = new DateTimeFormatterBuilder()
868                 .parseCaseInsensitive()
869                 .append(ISO_LOCAL_TIME)
870                 .optionalStart()
871                 .appendOffsetId()
872                 .toFormatter(ResolverStyle.STRICT, null);
873     }
874 
875     //-----------------------------------------------------------------------
876     /**
877      * The ISO date-time formatter that formats or parses a date-time without
878      * an offset, such as '2011-12-03T10:15:30'.
879      * <p>
880      * This returns an immutable formatter capable of formatting and parsing
881      * the ISO-8601 extended offset date-time format.
882      * The format consists of:
883      * <ul>
884      * <li>The {@link #ISO_LOCAL_DATE}
885      * <li>The letter 'T'. Parsing is case insensitive.
886      * <li>The {@link #ISO_LOCAL_TIME}
887      * </ul>
888      * <p>
889      * The returned formatter has a chronology of ISO set to ensure dates in
890      * other calendar systems are correctly converted.
891      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
892      */
893     public static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
894     static {
895         ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
896                 .parseCaseInsensitive()
897                 .append(ISO_LOCAL_DATE)
898                 .appendLiteral('T')
899                 .append(ISO_LOCAL_TIME)
900                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
901     }
902 
903     //-----------------------------------------------------------------------
904     /**
905      * The ISO date-time formatter that formats or parses a date-time with an
906      * offset, such as '2011-12-03T10:15:30+01:00'.
907      * <p>
908      * This returns an immutable formatter capable of formatting and parsing
909      * the ISO-8601 extended offset date-time format.
910      * The format consists of:
911      * <ul>
912      * <li>The {@link #ISO_LOCAL_DATE_TIME}
913      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
914      *  they will be handled even though this is not part of the ISO-8601 standard.
915      *  Parsing is case insensitive.
916      * </ul>
917      * <p>
918      * The returned formatter has a chronology of ISO set to ensure dates in
919      * other calendar systems are correctly converted.
920      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
921      */
922     public static final DateTimeFormatter ISO_OFFSET_DATE_TIME;
923     static {
924         ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
925                 .parseCaseInsensitive()
926                 .append(ISO_LOCAL_DATE_TIME)
927                 .appendOffsetId()
928                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
929     }
930 
931     //-----------------------------------------------------------------------
932     /**
933      * The ISO-like date-time formatter that formats or parses a date-time with
934      * offset and zone, such as '2011-12-03T10:15:30+01:00[Europe/Paris]'.
935      * <p>
936      * This returns an immutable formatter capable of formatting and parsing
937      * a format that extends the ISO-8601 extended offset date-time format
938      * to add the time-zone.
939      * The section in square brackets is not part of the ISO-8601 standard.
940      * The format consists of:
941      * <ul>
942      * <li>The {@link #ISO_OFFSET_DATE_TIME}
943      * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
944      * <li>An open square bracket '['.
945      * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
946      *  Parsing is case sensitive.
947      * <li>A close square bracket ']'.
948      * </ul>
949      * <p>
950      * The returned formatter has a chronology of ISO set to ensure dates in
951      * other calendar systems are correctly converted.
952      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
953      */
954     public static final DateTimeFormatter ISO_ZONED_DATE_TIME;
955     static {
956         ISO_ZONED_DATE_TIME = new DateTimeFormatterBuilder()
957                 .append(ISO_OFFSET_DATE_TIME)
958                 .optionalStart()
959                 .appendLiteral('[')
960                 .parseCaseSensitive()
961                 .appendZoneRegionId()
962                 .appendLiteral(']')
963                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
964     }
965 
966     //-----------------------------------------------------------------------
967     /**
968      * The ISO-like date-time formatter that formats or parses a date-time with
969      * the offset and zone if available, such as '2011-12-03T10:15:30',
970      * '2011-12-03T10:15:30+01:00' or '2011-12-03T10:15:30+01:00[Europe/Paris]'.
971      * <p>
972      * This returns an immutable formatter capable of formatting and parsing
973      * the ISO-8601 extended local or offset date-time format, as well as the
974      * extended non-ISO form specifying the time-zone.
975      * The format consists of:
976      * <ul>
977      * <li>The {@link #ISO_LOCAL_DATE_TIME}
978      * <li>If the offset is not available to format or parse then the format is complete.
979      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
980      *  they will be handled even though this is not part of the ISO-8601 standard.
981      * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
982      * <li>An open square bracket '['.
983      * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
984      *  Parsing is case sensitive.
985      * <li>A close square bracket ']'.
986      * </ul>
987      * <p>
988      * As this formatter has an optional element, it may be necessary to parse using
989      * {@link DateTimeFormatter#parseBest}.
990      * <p>
991      * The returned formatter has a chronology of ISO set to ensure dates in
992      * other calendar systems are correctly converted.
993      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
994      */
995     public static final DateTimeFormatter ISO_DATE_TIME;
996     static {
997         ISO_DATE_TIME = new DateTimeFormatterBuilder()
998                 .append(ISO_LOCAL_DATE_TIME)
999                 .optionalStart()
1000                 .appendOffsetId()
1001                 .optionalStart()
1002                 .appendLiteral('[')
1003                 .parseCaseSensitive()
1004                 .appendZoneRegionId()
1005                 .appendLiteral(']')
1006                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
1007     }
1008 
1009     //-----------------------------------------------------------------------
1010     /**
1011      * The ISO date formatter that formats or parses the ordinal date
1012      * without an offset, such as '2012-337'.
1013      * <p>
1014      * This returns an immutable formatter capable of formatting and parsing
1015      * the ISO-8601 extended ordinal date format.
1016      * The format consists of:
1017      * <ul>
1018      * <li>Four digits or more for the {@link ChronoField#YEAR year}.
1019      * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
1020      * Years outside that range will have a prefixed positive or negative symbol.
1021      * <li>A dash
1022      * <li>Three digits for the {@link ChronoField#DAY_OF_YEAR day-of-year}.
1023      *  This is pre-padded by zero to ensure three digits.
1024      * <li>If the offset is not available to format or parse then the format is complete.
1025      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
1026      *  they will be handled even though this is not part of the ISO-8601 standard.
1027      *  Parsing is case insensitive.
1028      * </ul>
1029      * <p>
1030      * As this formatter has an optional element, it may be necessary to parse using
1031      * {@link DateTimeFormatter#parseBest}.
1032      * <p>
1033      * The returned formatter has a chronology of ISO set to ensure dates in
1034      * other calendar systems are correctly converted.
1035      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
1036      */
1037     public static final DateTimeFormatter ISO_ORDINAL_DATE;
1038     static {
1039         ISO_ORDINAL_DATE = new DateTimeFormatterBuilder()
1040                 .parseCaseInsensitive()
1041                 .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
1042                 .appendLiteral('-')
1043                 .appendValue(DAY_OF_YEAR, 3)
1044                 .optionalStart()
1045                 .appendOffsetId()
1046                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
1047     }
1048 
1049     //-----------------------------------------------------------------------
1050     /**
1051      * The ISO date formatter that formats or parses the week-based date
1052      * without an offset, such as '2012-W48-6'.
1053      * <p>
1054      * This returns an immutable formatter capable of formatting and parsing
1055      * the ISO-8601 extended week-based date format.
1056      * The format consists of:
1057      * <ul>
1058      * <li>Four digits or more for the {@link IsoFields#WEEK_BASED_YEAR week-based-year}.
1059      * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
1060      * Years outside that range will have a prefixed positive or negative symbol.
1061      * <li>A dash
1062      * <li>The letter 'W'. Parsing is case insensitive.
1063      * <li>Two digits for the {@link IsoFields#WEEK_OF_WEEK_BASED_YEAR week-of-week-based-year}.
1064      *  This is pre-padded by zero to ensure three digits.
1065      * <li>A dash
1066      * <li>One digit for the {@link ChronoField#DAY_OF_WEEK day-of-week}.
1067      *  The value run from Monday (1) to Sunday (7).
1068      * <li>If the offset is not available to format or parse then the format is complete.
1069      * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
1070      *  they will be handled even though this is not part of the ISO-8601 standard.
1071      *  Parsing is case insensitive.
1072      * </ul>
1073      * <p>
1074      * As this formatter has an optional element, it may be necessary to parse using
1075      * {@link DateTimeFormatter#parseBest}.
1076      * <p>
1077      * The returned formatter has a chronology of ISO set to ensure dates in
1078      * other calendar systems are correctly converted.
1079      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
1080      */
1081     public static final DateTimeFormatter ISO_WEEK_DATE;
1082     static {
1083         ISO_WEEK_DATE = new DateTimeFormatterBuilder()
1084                 .parseCaseInsensitive()
1085                 .appendValue(IsoFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
1086                 .appendLiteral("-W")
1087                 .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
1088                 .appendLiteral('-')
1089                 .appendValue(DAY_OF_WEEK, 1)
1090                 .optionalStart()
1091                 .appendOffsetId()
1092                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
1093     }
1094 
1095     //-----------------------------------------------------------------------
1096     /**
1097      * The ISO instant formatter that formats or parses an instant in UTC,
1098      * such as '2011-12-03T10:15:30Z'.
1099      * <p>
1100      * This returns an immutable formatter capable of formatting and parsing
1101      * the ISO-8601 instant format.
1102      * When formatting, the second-of-minute is always output.
1103      * The nano-of-second outputs zero, three, six or nine digits digits as necessary.
1104      * When parsing, time to at least the seconds field is required.
1105      * Fractional seconds from zero to nine are parsed.
1106      * The localized decimal style is not used.
1107      * <p>
1108      * This is a special case formatter intended to allow a human readable form
1109      * of an {@link java.time.Instant}. The {@code Instant} class is designed to
1110      * only represent a point in time and internally stores a value in nanoseconds
1111      * from a fixed epoch of 1970-01-01Z. As such, an {@code Instant} cannot be
1112      * formatted as a date or time without providing some form of time-zone.
1113      * This formatter allows the {@code Instant} to be formatted, by providing
1114      * a suitable conversion using {@code ZoneOffset.UTC}.
1115      * <p>
1116      * The format consists of:
1117      * <ul>
1118      * <li>The {@link #ISO_OFFSET_DATE_TIME} where the instant is converted from
1119      *  {@link ChronoField#INSTANT_SECONDS} and {@link ChronoField#NANO_OF_SECOND}
1120      *  using the {@code UTC} offset. Parsing is case insensitive.
1121      * </ul>
1122      * <p>
1123      * The returned formatter has no override chronology or zone.
1124      * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
1125      */
1126     public static final DateTimeFormatter ISO_INSTANT;
1127     static {
1128         ISO_INSTANT = new DateTimeFormatterBuilder()
1129                 .parseCaseInsensitive()
1130                 .appendInstant()
1131                 .toFormatter(ResolverStyle.STRICT, null);
1132     }
1133 
1134     //-----------------------------------------------------------------------
1135     /**
1136      * The ISO date formatter that formats or parses a date without an
1137      * offset, such as '20111203'.
1138      * <p>
1139      * This returns an immutable formatter capable of formatting and parsing
1140      * the ISO-8601 basic local date format.
1141      * The format consists of:
1142      * <ul>
1143      * <li>Four digits for the {@link ChronoField#YEAR year}.
1144      *  Only years in the range 0000 to 9999 are supported.
1145      * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
1146      *  This is pre-padded by zero to ensure two digits.
1147      * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
1148      *  This is pre-padded by zero to ensure two digits.
1149      * <li>If the offset is not available to format or parse then the format is complete.
1150      * <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
1151      *  seconds then they will be handled even though this is not part of the ISO-8601 standard.
1152      *  Parsing is case insensitive.
1153      * </ul>
1154      * <p>
1155      * As this formatter has an optional element, it may be necessary to parse using
1156      * {@link DateTimeFormatter#parseBest}.
1157      * <p>
1158      * The returned formatter has a chronology of ISO set to ensure dates in
1159      * other calendar systems are correctly converted.
1160      * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
1161      */
1162     public static final DateTimeFormatter BASIC_ISO_DATE;
1163     static {
1164         BASIC_ISO_DATE = new DateTimeFormatterBuilder()
1165                 .parseCaseInsensitive()
1166                 .appendValue(YEAR, 4)
1167                 .appendValue(MONTH_OF_YEAR, 2)
1168                 .appendValue(DAY_OF_MONTH, 2)
1169                 .optionalStart()
1170                 .appendOffset("+HHMMss", "Z")
1171                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
1172     }
1173 
1174     //-----------------------------------------------------------------------
1175     /**
1176      * The RFC-1123 date-time formatter, such as 'Tue, 3 Jun 2008 11:05:30 GMT'.
1177      * <p>
1178      * This returns an immutable formatter capable of formatting and parsing
1179      * most of the RFC-1123 format.
1180      * RFC-1123 updates RFC-822 changing the year from two digits to four.
1181      * This implementation requires a four digit year.
1182      * This implementation also does not handle North American or military zone
1183      * names, only 'GMT' and offset amounts.
1184      * <p>
1185      * The format consists of:
1186      * <ul>
1187      * <li>If the day-of-week is not available to format or parse then jump to day-of-month.
1188      * <li>Three letter {@link ChronoField#DAY_OF_WEEK day-of-week} in English.
1189      * <li>A comma
1190      * <li>A space
1191      * <li>One or two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
1192      * <li>A space
1193      * <li>Three letter {@link ChronoField#MONTH_OF_YEAR month-of-year} in English.
1194      * <li>A space
1195      * <li>Four digits for the {@link ChronoField#YEAR year}.
1196      *  Only years in the range 0000 to 9999 are supported.
1197      * <li>A space
1198      * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
1199      *  This is pre-padded by zero to ensure two digits.
1200      * <li>A colon
1201      * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
1202      *  This is pre-padded by zero to ensure two digits.
1203      * <li>If the second-of-minute is not available then jump to the next space.
1204      * <li>A colon
1205      * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
1206      *  This is pre-padded by zero to ensure two digits.
1207      * <li>A space
1208      * <li>The {@link ZoneOffset#getId() offset ID} without colons or seconds.
1209      *  An offset of zero uses "GMT". North American zone names and military zone names are not handled.
1210      * </ul>
1211      * <p>
1212      * Parsing is case insensitive.
1213      * <p>
1214      * The returned formatter has a chronology of ISO set to ensure dates in
1215      * other calendar systems are correctly converted.
1216      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
1217      */
1218     public static final DateTimeFormatter RFC_1123_DATE_TIME;
1219     static {
1220         // manually code maps to ensure correct data always used
1221         // (locale data can be changed by application code)
1222         Map<Long, String> dow = new HashMap<>();
1223         dow.put(1L, "Mon");
1224         dow.put(2L, "Tue");
1225         dow.put(3L, "Wed");
1226         dow.put(4L, "Thu");
1227         dow.put(5L, "Fri");
1228         dow.put(6L, "Sat");
1229         dow.put(7L, "Sun");
1230         Map<Long, String> moy = new HashMap<>();
1231         moy.put(1L, "Jan");
1232         moy.put(2L, "Feb");
1233         moy.put(3L, "Mar");
1234         moy.put(4L, "Apr");
1235         moy.put(5L, "May");
1236         moy.put(6L, "Jun");
1237         moy.put(7L, "Jul");
1238         moy.put(8L, "Aug");
1239         moy.put(9L, "Sep");
1240         moy.put(10L, "Oct");
1241         moy.put(11L, "Nov");
1242         moy.put(12L, "Dec");
1243         RFC_1123_DATE_TIME = new DateTimeFormatterBuilder()
1244                 .parseCaseInsensitive()
1245                 .parseLenient()
1246                 .optionalStart()
1247                 .appendText(DAY_OF_WEEK, dow)
1248                 .appendLiteral(", ")
1249                 .optionalEnd()
1250                 .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
1251                 .appendLiteral(' ')
1252                 .appendText(MONTH_OF_YEAR, moy)
1253                 .appendLiteral(' ')
1254                 .appendValue(YEAR, 4)  // 2 digit year not handled
1255                 .appendLiteral(' ')
1256                 .appendValue(HOUR_OF_DAY, 2)
1257                 .appendLiteral(':')
1258                 .appendValue(MINUTE_OF_HOUR, 2)
1259                 .optionalStart()
1260                 .appendLiteral(':')
1261                 .appendValue(SECOND_OF_MINUTE, 2)
1262                 .optionalEnd()
1263                 .appendLiteral(' ')
1264                 .appendOffset("+HHMM", "GMT")  // should handle UT/Z/EST/EDT/CST/CDT/MST/MDT/PST/MDT
1265                 .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
1266     }
1267 
1268     //-----------------------------------------------------------------------
1269     /**
1270      * A query that provides access to the excess days that were parsed.
1271      * <p>
1272      * This returns a singleton {@linkplain TemporalQuery query} that provides
1273      * access to additional information from the parse. The query always returns
1274      * a non-null period, with a zero period returned instead of null.
1275      * <p>
1276      * There are two situations where this query may return a non-zero period.
1277      * <ul>
1278      * <li>If the {@code ResolverStyle} is {@code LENIENT} and a time is parsed
1279      *  without a date, then the complete result of the parse consists of a
1280      *  {@code LocalTime} and an excess {@code Period} in days.
1281      *
1282      * <li>If the {@code ResolverStyle} is {@code SMART} and a time is parsed
1283      *  without a date where the time is 24:00:00, then the complete result of
1284      *  the parse consists of a {@code LocalTime} of 00:00:00 and an excess
1285      *  {@code Period} of one day.
1286      * </ul>
1287      * <p>
1288      * In both cases, if a complete {@code ChronoLocalDateTime} or {@code Instant}
1289      * is parsed, then the excess days are added to the date part.
1290      * As a result, this query will return a zero period.
1291      * <p>
1292      * The {@code SMART} behaviour handles the common "end of day" 24:00 value.
1293      * Processing in {@code LENIENT} mode also produces the same result:
1294      * <pre>
1295      *  Text to parse        Parsed object                         Excess days
1296      *  "2012-12-03T00:00"   LocalDateTime.of(2012, 12, 3, 0, 0)   ZERO
1297      *  "2012-12-03T24:00"   LocalDateTime.of(2012, 12, 4, 0, 0)   ZERO
1298      *  "00:00"              LocalTime.of(0, 0)                    ZERO
1299      *  "24:00"              LocalTime.of(0, 0)                    Period.ofDays(1)
1300      * </pre>
1301      * The query can be used as follows:
1302      * <pre>
1303      *  TemporalAccessor parsed = formatter.parse(str);
1304      *  LocalTime time = parsed.query(LocalTime::from);
1305      *  Period extraDays = parsed.query(DateTimeFormatter.parsedExcessDays());
1306      * </pre>
1307      * @return a query that provides access to the excess days that were parsed
1308      */
1309     public static final TemporalQuery<Period> parsedExcessDays() {
1310         return PARSED_EXCESS_DAYS;
1311     }
1312     private static final TemporalQuery<Period> PARSED_EXCESS_DAYS = t -> {
1313         if (t instanceof Parsed) {
1314             return ((Parsed) t).excessDays;
1315         } else {
1316             return Period.ZERO;
1317         }
1318     };
1319 
1320     /**
1321      * A query that provides access to whether a leap-second was parsed.
1322      * <p>
1323      * This returns a singleton {@linkplain TemporalQuery query} that provides
1324      * access to additional information from the parse. The query always returns
1325      * a non-null boolean, true if parsing saw a leap-second, false if not.
1326      * <p>
1327      * Instant parsing handles the special "leap second" time of '23:59:60'.
1328      * Leap seconds occur at '23:59:60' in the UTC time-zone, but at other
1329      * local times in different time-zones. To avoid this potential ambiguity,
1330      * the handling of leap-seconds is limited to
1331      * {@link DateTimeFormatterBuilder#appendInstant()}, as that method
1332      * always parses the instant with the UTC zone offset.
1333      * <p>
1334      * If the time '23:59:60' is received, then a simple conversion is applied,
1335      * replacing the second-of-minute of 60 with 59. This query can be used
1336      * on the parse result to determine if the leap-second adjustment was made.
1337      * The query will return one second of excess if it did adjust to remove
1338      * the leap-second, and zero if not. Note that applying a leap-second
1339      * smoothing mechanism, such as UTC-SLS, is the responsibility of the
1340      * application, as follows:
1341      * <pre>
1342      *  TemporalAccessor parsed = formatter.parse(str);
1343      *  Instant instant = parsed.query(Instant::from);
1344      *  if (parsed.query(DateTimeFormatter.parsedLeapSecond())) {
1345      *    // validate leap-second is correct and apply correct smoothing
1346      *  }
1347      * </pre>
1348      * @return a query that provides access to whether a leap-second was parsed
1349      */
1350     public static final TemporalQuery<Boolean> parsedLeapSecond() {
1351         return PARSED_LEAP_SECOND;
1352     }
1353     private static final TemporalQuery<Boolean> PARSED_LEAP_SECOND = t -> {
1354         if (t instanceof Parsed) {
1355             return ((Parsed) t).leapSecond;
1356         } else {
1357             return Boolean.FALSE;
1358         }
1359     };
1360 
1361     //-----------------------------------------------------------------------
1362     /**
1363      * Constructor.
1364      *
1365      * @param printerParser  the printer/parser to use, not null
1366      * @param locale  the locale to use, not null
1367      * @param decimalStyle  the DecimalStyle to use, not null
1368      * @param resolverStyle  the resolver style to use, not null
1369      * @param resolverFields  the fields to use during resolving, null for all fields
1370      * @param chrono  the chronology to use, null for no override
1371      * @param zone  the zone to use, null for no override
1372      */
1373     DateTimeFormatter(CompositePrinterParser printerParser,
1374             Locale locale, DecimalStyle decimalStyle,
1375             ResolverStyle resolverStyle, Set<TemporalField> resolverFields,
1376             Chronology chrono, ZoneId zone) {
1377         this.printerParser = Objects.requireNonNull(printerParser, "printerParser");
1378         this.resolverFields = resolverFields;
1379         this.locale = Objects.requireNonNull(locale, "locale");
1380         this.decimalStyle = Objects.requireNonNull(decimalStyle, "decimalStyle");
1381         this.resolverStyle = Objects.requireNonNull(resolverStyle, "resolverStyle");
1382         this.chrono = chrono;
1383         this.zone = zone;
1384     }
1385 
1386     //-----------------------------------------------------------------------
1387     /**
1388      * Gets the locale to be used during formatting.
1389      * <p>
1390      * This is used to lookup any part of the formatter needing specific
1391      * localization, such as the text or localized pattern.
1392      *
1393      * @return the locale of this formatter, not null
1394      */
1395     public Locale getLocale() {
1396         return locale;
1397     }
1398 
1399     /**
1400      * Returns a copy of this formatter with a new locale.
1401      * <p>
1402      * This is used to lookup any part of the formatter needing specific
1403      * localization, such as the text or localized pattern.
1404      * <p>
1405      * This instance is immutable and unaffected by this method call.
1406      *
1407      * @param locale  the new locale, not null
1408      * @return a formatter based on this formatter with the requested locale, not null
1409      */
1410     public DateTimeFormatter withLocale(Locale locale) {
1411         if (this.locale.equals(locale)) {
1412             return this;
1413         }
1414         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1415     }
1416 
1417     //-----------------------------------------------------------------------
1418     /**
1419      * Gets the DecimalStyle to be used during formatting.
1420      *
1421      * @return the locale of this formatter, not null
1422      */
1423     public DecimalStyle getDecimalStyle() {
1424         return decimalStyle;
1425     }
1426 
1427     /**
1428      * Returns a copy of this formatter with a new DecimalStyle.
1429      * <p>
1430      * This instance is immutable and unaffected by this method call.
1431      *
1432      * @param decimalStyle  the new DecimalStyle, not null
1433      * @return a formatter based on this formatter with the requested DecimalStyle, not null
1434      */
1435     public DateTimeFormatter withDecimalStyle(DecimalStyle decimalStyle) {
1436         if (this.decimalStyle.equals(decimalStyle)) {
1437             return this;
1438         }
1439         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1440     }
1441 
1442     //-----------------------------------------------------------------------
1443     /**
1444      * Gets the overriding chronology to be used during formatting.
1445      * <p>
1446      * This returns the override chronology, used to convert dates.
1447      * By default, a formatter has no override chronology, returning null.
1448      * See {@link #withChronology(Chronology)} for more details on overriding.
1449      *
1450      * @return the override chronology of this formatter, null if no override
1451      */
1452     public Chronology getChronology() {
1453         return chrono;
1454     }
1455 
1456     /**
1457      * Returns a copy of this formatter with a new override chronology.
1458      * <p>
1459      * This returns a formatter with similar state to this formatter but
1460      * with the override chronology set.
1461      * By default, a formatter has no override chronology, returning null.
1462      * <p>
1463      * If an override is added, then any date that is formatted or parsed will be affected.
1464      * <p>
1465      * When formatting, if the temporal object contains a date, then it will
1466      * be converted to a date in the override chronology.
1467      * Whether the temporal contains a date is determined by querying the
1468      * {@link ChronoField#EPOCH_DAY EPOCH_DAY} field.
1469      * Any time or zone will be retained unaltered unless overridden.
1470      * <p>
1471      * If the temporal object does not contain a date, but does contain one
1472      * or more {@code ChronoField} date fields, then a {@code DateTimeException}
1473      * is thrown. In all other cases, the override chronology is added to the temporal,
1474      * replacing any previous chronology, but without changing the date/time.
1475      * <p>
1476      * When parsing, there are two distinct cases to consider.
1477      * If a chronology has been parsed directly from the text, perhaps because
1478      * {@link DateTimeFormatterBuilder#appendChronologyId()} was used, then
1479      * this override chronology has no effect.
1480      * If no zone has been parsed, then this override chronology will be used
1481      * to interpret the {@code ChronoField} values into a date according to the
1482      * date resolving rules of the chronology.
1483      * <p>
1484      * This instance is immutable and unaffected by this method call.
1485      *
1486      * @param chrono  the new chronology, null if no override
1487      * @return a formatter based on this formatter with the requested override chronology, not null
1488      */
1489     public DateTimeFormatter withChronology(Chronology chrono) {
1490         if (Objects.equals(this.chrono, chrono)) {
1491             return this;
1492         }
1493         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1494     }
1495 
1496     //-----------------------------------------------------------------------
1497     /**
1498      * Gets the overriding zone to be used during formatting.
1499      * <p>
1500      * This returns the override zone, used to convert instants.
1501      * By default, a formatter has no override zone, returning null.
1502      * See {@link #withZone(ZoneId)} for more details on overriding.
1503      *
1504      * @return the override zone of this formatter, null if no override
1505      */
1506     public ZoneId getZone() {
1507         return zone;
1508     }
1509 
1510     /**
1511      * Returns a copy of this formatter with a new override zone.
1512      * <p>
1513      * This returns a formatter with similar state to this formatter but
1514      * with the override zone set.
1515      * By default, a formatter has no override zone, returning null.
1516      * <p>
1517      * If an override is added, then any instant that is formatted or parsed will be affected.
1518      * <p>
1519      * When formatting, if the temporal object contains an instant, then it will
1520      * be converted to a zoned date-time using the override zone.
1521      * Whether the temporal is an instant is determined by querying the
1522      * {@link ChronoField#INSTANT_SECONDS INSTANT_SECONDS} field.
1523      * If the input has a chronology then it will be retained unless overridden.
1524      * If the input does not have a chronology, such as {@code Instant}, then
1525      * the ISO chronology will be used.
1526      * <p>
1527      * If the temporal object does not contain an instant, but does contain
1528      * an offset then an additional check is made. If the normalized override
1529      * zone is an offset that differs from the offset of the temporal, then
1530      * a {@code DateTimeException} is thrown. In all other cases, the override
1531      * zone is added to the temporal, replacing any previous zone, but without
1532      * changing the date/time.
1533      * <p>
1534      * When parsing, there are two distinct cases to consider.
1535      * If a zone has been parsed directly from the text, perhaps because
1536      * {@link DateTimeFormatterBuilder#appendZoneId()} was used, then
1537      * this override zone has no effect.
1538      * If no zone has been parsed, then this override zone will be included in
1539      * the result of the parse where it can be used to build instants and date-times.
1540      * <p>
1541      * This instance is immutable and unaffected by this method call.
1542      *
1543      * @param zone  the new override zone, null if no override
1544      * @return a formatter based on this formatter with the requested override zone, not null
1545      */
1546     public DateTimeFormatter withZone(ZoneId zone) {
1547         if (Objects.equals(this.zone, zone)) {
1548             return this;
1549         }
1550         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1551     }
1552 
1553     //-----------------------------------------------------------------------
1554     /**
1555      * Gets the resolver style to use during parsing.
1556      * <p>
1557      * This returns the resolver style, used during the second phase of parsing
1558      * when fields are resolved into dates and times.
1559      * By default, a formatter has the {@link ResolverStyle#SMART SMART} resolver style.
1560      * See {@link #withResolverStyle(ResolverStyle)} for more details.
1561      *
1562      * @return the resolver style of this formatter, not null
1563      */
1564     public ResolverStyle getResolverStyle() {
1565         return resolverStyle;
1566     }
1567 
1568     /**
1569      * Returns a copy of this formatter with a new resolver style.
1570      * <p>
1571      * This returns a formatter with similar state to this formatter but
1572      * with the resolver style set. By default, a formatter has the
1573      * {@link ResolverStyle#SMART SMART} resolver style.
1574      * <p>
1575      * Changing the resolver style only has an effect during parsing.
1576      * Parsing a text string occurs in two phases.
1577      * Phase 1 is a basic text parse according to the fields added to the builder.
1578      * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
1579      * The resolver style is used to control how phase 2, resolving, happens.
1580      * See {@code ResolverStyle} for more information on the options available.
1581      * <p>
1582      * This instance is immutable and unaffected by this method call.
1583      *
1584      * @param resolverStyle  the new resolver style, not null
1585      * @return a formatter based on this formatter with the requested resolver style, not null
1586      */
1587     public DateTimeFormatter withResolverStyle(ResolverStyle resolverStyle) {
1588         Objects.requireNonNull(resolverStyle, "resolverStyle");
1589         if (Objects.equals(this.resolverStyle, resolverStyle)) {
1590             return this;
1591         }
1592         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1593     }
1594 
1595     //-----------------------------------------------------------------------
1596     /**
1597      * Gets the resolver fields to use during parsing.
1598      * <p>
1599      * This returns the resolver fields, used during the second phase of parsing
1600      * when fields are resolved into dates and times.
1601      * By default, a formatter has no resolver fields, and thus returns null.
1602      * See {@link #withResolverFields(Set)} for more details.
1603      *
1604      * @return the immutable set of resolver fields of this formatter, null if no fields
1605      */
1606     public Set<TemporalField> getResolverFields() {
1607         return resolverFields;
1608     }
1609 
1610     /**
1611      * Returns a copy of this formatter with a new set of resolver fields.
1612      * <p>
1613      * This returns a formatter with similar state to this formatter but with
1614      * the resolver fields set. By default, a formatter has no resolver fields.
1615      * <p>
1616      * Changing the resolver fields only has an effect during parsing.
1617      * Parsing a text string occurs in two phases.
1618      * Phase 1 is a basic text parse according to the fields added to the builder.
1619      * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
1620      * The resolver fields are used to filter the field-value pairs between phase 1 and 2.
1621      * <p>
1622      * This can be used to select between two or more ways that a date or time might
1623      * be resolved. For example, if the formatter consists of year, month, day-of-month
1624      * and day-of-year, then there are two ways to resolve a date.
1625      * Calling this method with the arguments {@link ChronoField#YEAR YEAR} and
1626      * {@link ChronoField#DAY_OF_YEAR DAY_OF_YEAR} will ensure that the date is
1627      * resolved using the year and day-of-year, effectively meaning that the month
1628      * and day-of-month are ignored during the resolving phase.
1629      * <p>
1630      * In a similar manner, this method can be used to ignore secondary fields that
1631      * would otherwise be cross-checked. For example, if the formatter consists of year,
1632      * month, day-of-month and day-of-week, then there is only one way to resolve a
1633      * date, but the parsed value for day-of-week will be cross-checked against the
1634      * resolved date. Calling this method with the arguments {@link ChronoField#YEAR YEAR},
1635      * {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and
1636      * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} will ensure that the date is
1637      * resolved correctly, but without any cross-check for the day-of-week.
1638      * <p>
1639      * In implementation terms, this method behaves as follows. The result of the
1640      * parsing phase can be considered to be a map of field to value. The behavior
1641      * of this method is to cause that map to be filtered between phase 1 and 2,
1642      * removing all fields other than those specified as arguments to this method.
1643      * <p>
1644      * This instance is immutable and unaffected by this method call.
1645      *
1646      * @param resolverFields  the new set of resolver fields, null if no fields
1647      * @return a formatter based on this formatter with the requested resolver style, not null
1648      */
1649     public DateTimeFormatter withResolverFields(TemporalField... resolverFields) {
1650         Objects.requireNonNull(resolverFields, "resolverFields");
1651         Set<TemporalField> fields = new HashSet<>(Arrays.asList(resolverFields));
1652         if (Objects.equals(this.resolverFields, fields)) {
1653             return this;
1654         }
1655         fields = Collections.unmodifiableSet(fields);
1656         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, fields, chrono, zone);
1657     }
1658 
1659     /**
1660      * Returns a copy of this formatter with a new set of resolver fields.
1661      * <p>
1662      * This returns a formatter with similar state to this formatter but with
1663      * the resolver fields set. By default, a formatter has no resolver fields.
1664      * <p>
1665      * Changing the resolver fields only has an effect during parsing.
1666      * Parsing a text string occurs in two phases.
1667      * Phase 1 is a basic text parse according to the fields added to the builder.
1668      * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
1669      * The resolver fields are used to filter the field-value pairs between phase 1 and 2.
1670      * <p>
1671      * This can be used to select between two or more ways that a date or time might
1672      * be resolved. For example, if the formatter consists of year, month, day-of-month
1673      * and day-of-year, then there are two ways to resolve a date.
1674      * Calling this method with the arguments {@link ChronoField#YEAR YEAR} and
1675      * {@link ChronoField#DAY_OF_YEAR DAY_OF_YEAR} will ensure that the date is
1676      * resolved using the year and day-of-year, effectively meaning that the month
1677      * and day-of-month are ignored during the resolving phase.
1678      * <p>
1679      * In a similar manner, this method can be used to ignore secondary fields that
1680      * would otherwise be cross-checked. For example, if the formatter consists of year,
1681      * month, day-of-month and day-of-week, then there is only one way to resolve a
1682      * date, but the parsed value for day-of-week will be cross-checked against the
1683      * resolved date. Calling this method with the arguments {@link ChronoField#YEAR YEAR},
1684      * {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and
1685      * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} will ensure that the date is
1686      * resolved correctly, but without any cross-check for the day-of-week.
1687      * <p>
1688      * In implementation terms, this method behaves as follows. The result of the
1689      * parsing phase can be considered to be a map of field to value. The behavior
1690      * of this method is to cause that map to be filtered between phase 1 and 2,
1691      * removing all fields other than those specified as arguments to this method.
1692      * <p>
1693      * This instance is immutable and unaffected by this method call.
1694      *
1695      * @param resolverFields  the new set of resolver fields, null if no fields
1696      * @return a formatter based on this formatter with the requested resolver style, not null
1697      */
1698     public DateTimeFormatter withResolverFields(Set<TemporalField> resolverFields) {
1699         Objects.requireNonNull(resolverFields, "resolverFields");
1700         if (Objects.equals(this.resolverFields, resolverFields)) {
1701             return this;
1702         }
1703         resolverFields = Collections.unmodifiableSet(new HashSet<>(resolverFields));
1704         return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone);
1705     }
1706 
1707     //-----------------------------------------------------------------------
1708     /**
1709      * Formats a date-time object using this formatter.
1710      * <p>
1711      * This formats the date-time to a String using the rules of the formatter.
1712      *
1713      * @param temporal  the temporal object to format, not null
1714      * @return the formatted string, not null
1715      * @throws DateTimeException if an error occurs during formatting
1716      */
1717     public String format(TemporalAccessor temporal) {
1718         StringBuilder buf = new StringBuilder(32);
1719         formatTo(temporal, buf);
1720         return buf.toString();
1721     }
1722 
1723     //-----------------------------------------------------------------------
1724     /**
1725      * Formats a date-time object to an {@code Appendable} using this formatter.
1726      * <p>
1727      * This outputs the formatted date-time to the specified destination.
1728      * {@link Appendable} is a general purpose interface that is implemented by all
1729      * key character output classes including {@code StringBuffer}, {@code StringBuilder},
1730      * {@code PrintStream} and {@code Writer}.
1731      * <p>
1732      * Although {@code Appendable} methods throw an {@code IOException}, this method does not.
1733      * Instead, any {@code IOException} is wrapped in a runtime exception.
1734      *
1735      * @param temporal  the temporal object to format, not null
1736      * @param appendable  the appendable to format to, not null
1737      * @throws DateTimeException if an error occurs during formatting
1738      */
1739     public void formatTo(TemporalAccessor temporal, Appendable appendable) {
1740         Objects.requireNonNull(temporal, "temporal");
1741         Objects.requireNonNull(appendable, "appendable");
1742         try {
1743             DateTimePrintContext context = new DateTimePrintContext(temporal, this);
1744             if (appendable instanceof StringBuilder) {
1745                 printerParser.format(context, (StringBuilder) appendable);
1746             } else {
1747                 // buffer output to avoid writing to appendable in case of error
1748                 StringBuilder buf = new StringBuilder(32);
1749                 printerParser.format(context, buf);
1750                 appendable.append(buf);
1751             }
1752         } catch (IOException ex) {
1753             throw new DateTimeException(ex.getMessage(), ex);
1754         }
1755     }
1756 
1757     //-----------------------------------------------------------------------
1758     /**
1759      * Fully parses the text producing a temporal object.
1760      * <p>
1761      * This parses the entire text producing a temporal object.
1762      * It is typically more useful to use {@link #parse(CharSequence, TemporalQuery)}.
1763      * The result of this method is {@code TemporalAccessor} which has been resolved,
1764      * applying basic validation checks to help ensure a valid date-time.
1765      * <p>
1766      * If the parse completes without reading the entire length of the text,
1767      * or a problem occurs during parsing or merging, then an exception is thrown.
1768      *
1769      * @param text  the text to parse, not null
1770      * @return the parsed temporal object, not null
1771      * @throws DateTimeParseException if unable to parse the requested result
1772      */
1773     public TemporalAccessor parse(CharSequence text) {
1774         Objects.requireNonNull(text, "text");
1775         try {
1776             return parseResolved0(text, null);
1777         } catch (DateTimeParseException ex) {
1778             throw ex;
1779         } catch (RuntimeException ex) {
1780             throw createError(text, ex);
1781         }
1782     }
1783 
1784     /**
1785      * Parses the text using this formatter, providing control over the text position.
1786      * <p>
1787      * This parses the text without requiring the parse to start from the beginning
1788      * of the string or finish at the end.
1789      * The result of this method is {@code TemporalAccessor} which has been resolved,
1790      * applying basic validation checks to help ensure a valid date-time.
1791      * <p>
1792      * The text will be parsed from the specified start {@code ParsePosition}.
1793      * The entire length of the text does not have to be parsed, the {@code ParsePosition}
1794      * will be updated with the index at the end of parsing.
1795      * <p>
1796      * The operation of this method is slightly different to similar methods using
1797      * {@code ParsePosition} on {@code java.text.Format}. That class will return
1798      * errors using the error index on the {@code ParsePosition}. By contrast, this
1799      * method will throw a {@link DateTimeParseException} if an error occurs, with
1800      * the exception containing the error index.
1801      * This change in behavior is necessary due to the increased complexity of
1802      * parsing and resolving dates/times in this API.
1803      * <p>
1804      * If the formatter parses the same field more than once with different values,
1805      * the result will be an error.
1806      *
1807      * @param text  the text to parse, not null
1808      * @param position  the position to parse from, updated with length parsed
1809      *  and the index of any error, not null
1810      * @return the parsed temporal object, not null
1811      * @throws DateTimeParseException if unable to parse the requested result
1812      * @throws IndexOutOfBoundsException if the position is invalid
1813      */
1814     public TemporalAccessor parse(CharSequence text, ParsePosition position) {
1815         Objects.requireNonNull(text, "text");
1816         Objects.requireNonNull(position, "position");
1817         try {
1818             return parseResolved0(text, position);
1819         } catch (DateTimeParseException | IndexOutOfBoundsException ex) {
1820             throw ex;
1821         } catch (RuntimeException ex) {
1822             throw createError(text, ex);
1823         }
1824     }
1825 
1826     //-----------------------------------------------------------------------
1827     /**
1828      * Fully parses the text producing an object of the specified type.
1829      * <p>
1830      * Most applications should use this method for parsing.
1831      * It parses the entire text to produce the required date-time.
1832      * The query is typically a method reference to a {@code from(TemporalAccessor)} method.
1833      * For example:
1834      * <pre>
1835      *  LocalDateTime dt = parser.parse(str, LocalDateTime::from);
1836      * </pre>
1837      * If the parse completes without reading the entire length of the text,
1838      * or a problem occurs during parsing or merging, then an exception is thrown.
1839      *
1840      * @param <T> the type of the parsed date-time
1841      * @param text  the text to parse, not null
1842      * @param query  the query defining the type to parse to, not null
1843      * @return the parsed date-time, not null
1844      * @throws DateTimeParseException if unable to parse the requested result
1845      */
1846     public <T> T parse(CharSequence text, TemporalQuery<T> query) {
1847         Objects.requireNonNull(text, "text");
1848         Objects.requireNonNull(query, "query");
1849         try {
1850             return parseResolved0(text, null).query(query);
1851         } catch (DateTimeParseException ex) {
1852             throw ex;
1853         } catch (RuntimeException ex) {
1854             throw createError(text, ex);
1855         }
1856     }
1857 
1858     /**
1859      * Fully parses the text producing an object of one of the specified types.
1860      * <p>
1861      * This parse method is convenient for use when the parser can handle optional elements.
1862      * For example, a pattern of 'uuuu-MM-dd HH.mm[ VV]' can be fully parsed to a {@code ZonedDateTime},
1863      * or partially parsed to a {@code LocalDateTime}.
1864      * The queries must be specified in order, starting from the best matching full-parse option
1865      * and ending with the worst matching minimal parse option.
1866      * The query is typically a method reference to a {@code from(TemporalAccessor)} method.
1867      * <p>
1868      * The result is associated with the first type that successfully parses.
1869      * Normally, applications will use {@code instanceof} to check the result.
1870      * For example:
1871      * <pre>
1872      *  TemporalAccessor dt = parser.parseBest(str, ZonedDateTime::from, LocalDateTime::from);
1873      *  if (dt instanceof ZonedDateTime) {
1874      *   ...
1875      *  } else {
1876      *   ...
1877      *  }
1878      * </pre>
1879      * If the parse completes without reading the entire length of the text,
1880      * or a problem occurs during parsing or merging, then an exception is thrown.
1881      *
1882      * @param text  the text to parse, not null
1883      * @param queries  the queries defining the types to attempt to parse to,
1884      *  must implement {@code TemporalAccessor}, not null
1885      * @return the parsed date-time, not null
1886      * @throws IllegalArgumentException if less than 2 types are specified
1887      * @throws DateTimeParseException if unable to parse the requested result
1888      */
1889     public TemporalAccessor parseBest(CharSequence text, TemporalQuery<?>... queries) {
1890         Objects.requireNonNull(text, "text");
1891         Objects.requireNonNull(queries, "queries");
1892         if (queries.length < 2) {
1893             throw new IllegalArgumentException("At least two queries must be specified");
1894         }
1895         try {
1896             TemporalAccessor resolved = parseResolved0(text, null);
1897             for (TemporalQuery<?> query : queries) {
1898                 try {
1899                     return (TemporalAccessor) resolved.query(query);
1900                 } catch (RuntimeException ex) {
1901                     // continue
1902                 }
1903             }
1904             throw new DateTimeException("Unable to convert parsed text using any of the specified queries");
1905         } catch (DateTimeParseException ex) {
1906             throw ex;
1907         } catch (RuntimeException ex) {
1908             throw createError(text, ex);
1909         }
1910     }
1911 
1912     private DateTimeParseException createError(CharSequence text, RuntimeException ex) {
1913         String abbr;
1914         if (text.length() > 64) {
1915             abbr = text.subSequence(0, 64).toString() + "...";
1916         } else {
1917             abbr = text.toString();
1918         }
1919         return new DateTimeParseException("Text '" + abbr + "' could not be parsed: " + ex.getMessage(), text, 0, ex);
1920     }
1921 
1922     //-----------------------------------------------------------------------
1923     /**
1924      * Parses and resolves the specified text.
1925      * <p>
1926      * This parses to a {@code TemporalAccessor} ensuring that the text is fully parsed.
1927      *
1928      * @param text  the text to parse, not null
1929      * @param position  the position to parse from, updated with length parsed
1930      *  and the index of any error, null if parsing whole string
1931      * @return the resolved result of the parse, not null
1932      * @throws DateTimeParseException if the parse fails
1933      * @throws DateTimeException if an error occurs while resolving the date or time
1934      * @throws IndexOutOfBoundsException if the position is invalid
1935      */
1936     private TemporalAccessor parseResolved0(final CharSequence text, final ParsePosition position) {
1937         ParsePosition pos = (position != null ? position : new ParsePosition(0));
1938         Parsed unresolved = parseUnresolved0(text, pos);
1939         if (unresolved == null || pos.getErrorIndex() >= 0 || (position == null && pos.getIndex() < text.length())) {
1940             String abbr;
1941             if (text.length() > 64) {
1942                 abbr = text.subSequence(0, 64).toString() + "...";
1943             } else {
1944                 abbr = text.toString();
1945             }
1946             if (pos.getErrorIndex() >= 0) {
1947                 throw new DateTimeParseException("Text '" + abbr + "' could not be parsed at index " +
1948                         pos.getErrorIndex(), text, pos.getErrorIndex());
1949             } else {
1950                 throw new DateTimeParseException("Text '" + abbr + "' could not be parsed, unparsed text found at index " +
1951                         pos.getIndex(), text, pos.getIndex());
1952             }
1953         }
1954         return unresolved.resolve(resolverStyle, resolverFields);
1955     }
1956 
1957     /**
1958      * Parses the text using this formatter, without resolving the result, intended
1959      * for advanced use cases.
1960      * <p>
1961      * Parsing is implemented as a two-phase operation.
1962      * First, the text is parsed using the layout defined by the formatter, producing
1963      * a {@code Map} of field to value, a {@code ZoneId} and a {@code Chronology}.
1964      * Second, the parsed data is <em>resolved</em>, by validating, combining and
1965      * simplifying the various fields into more useful ones.
1966      * This method performs the parsing stage but not the resolving stage.
1967      * <p>
1968      * The result of this method is {@code TemporalAccessor} which represents the
1969      * data as seen in the input. Values are not validated, thus parsing a date string
1970      * of '2012-00-65' would result in a temporal with three fields - year of '2012',
1971      * month of '0' and day-of-month of '65'.
1972      * <p>
1973      * The text will be parsed from the specified start {@code ParsePosition}.
1974      * The entire length of the text does not have to be parsed, the {@code ParsePosition}
1975      * will be updated with the index at the end of parsing.
1976      * <p>
1977      * Errors are returned using the error index field of the {@code ParsePosition}
1978      * instead of {@code DateTimeParseException}.
1979      * The returned error index will be set to an index indicative of the error.
1980      * Callers must check for errors before using the context.
1981      * <p>
1982      * If the formatter parses the same field more than once with different values,
1983      * the result will be an error.
1984      * <p>
1985      * This method is intended for advanced use cases that need access to the
1986      * internal state during parsing. Typical application code should use
1987      * {@link #parse(CharSequence, TemporalQuery)} or the parse method on the target type.
1988      *
1989      * @param text  the text to parse, not null
1990      * @param position  the position to parse from, updated with length parsed
1991      *  and the index of any error, not null
1992      * @return the parsed text, null if the parse results in an error
1993      * @throws DateTimeException if some problem occurs during parsing
1994      * @throws IndexOutOfBoundsException if the position is invalid
1995      */
1996     public TemporalAccessor parseUnresolved(CharSequence text, ParsePosition position) {
1997         return parseUnresolved0(text, position);
1998     }
1999 
2000     private Parsed parseUnresolved0(CharSequence text, ParsePosition position) {
2001         Objects.requireNonNull(text, "text");
2002         Objects.requireNonNull(position, "position");
2003         DateTimeParseContext context = new DateTimeParseContext(this);
2004         int pos = position.getIndex();
2005         pos = printerParser.parse(context, text, pos);
2006         if (pos < 0) {
2007             position.setErrorIndex(~pos);  // index not updated from input
2008             return null;
2009         }
2010         position.setIndex(pos);  // errorIndex not updated from input
2011         return context.toParsed();
2012     }
2013 
2014     //-----------------------------------------------------------------------
2015     /**
2016      * Returns the formatter as a composite printer parser.
2017      *
2018      * @param optional  whether the printer/parser should be optional
2019      * @return the printer/parser, not null
2020      */
2021     CompositePrinterParser toPrinterParser(boolean optional) {
2022         return printerParser.withOptional(optional);
2023     }
2024 
2025     /**
2026      * Returns this formatter as a {@code java.text.Format} instance.
2027      * <p>
2028      * The returned {@link Format} instance will format any {@link TemporalAccessor}
2029      * and parses to a resolved {@link TemporalAccessor}.
2030      * <p>
2031      * Exceptions will follow the definitions of {@code Format}, see those methods
2032      * for details about {@code IllegalArgumentException} during formatting and
2033      * {@code ParseException} or null during parsing.
2034      * The format does not support attributing of the returned format string.
2035      *
2036      * @return this formatter as a classic format instance, not null
2037      */
2038     public Format toFormat() {
2039         return new ClassicFormat(this, null);
2040     }
2041 
2042     /**
2043      * Returns this formatter as a {@code java.text.Format} instance that will
2044      * parse using the specified query.
2045      * <p>
2046      * The returned {@link Format} instance will format any {@link TemporalAccessor}
2047      * and parses to the type specified.
2048      * The type must be one that is supported by {@link #parse}.
2049      * <p>
2050      * Exceptions will follow the definitions of {@code Format}, see those methods
2051      * for details about {@code IllegalArgumentException} during formatting and
2052      * {@code ParseException} or null during parsing.
2053      * The format does not support attributing of the returned format string.
2054      *
2055      * @param parseQuery  the query defining the type to parse to, not null
2056      * @return this formatter as a classic format instance, not null
2057      */
2058     public Format toFormat(TemporalQuery<?> parseQuery) {
2059         Objects.requireNonNull(parseQuery, "parseQuery");
2060         return new ClassicFormat(this, parseQuery);
2061     }
2062 
2063     //-----------------------------------------------------------------------
2064     /**
2065      * Returns a description of the underlying formatters.
2066      *
2067      * @return a description of this formatter, not null
2068      */
2069     @Override
2070     public String toString() {
2071         String pattern = printerParser.toString();
2072         pattern = pattern.startsWith("[") ? pattern : pattern.substring(1, pattern.length() - 1);
2073         return pattern;
2074         // TODO: Fix tests to not depend on toString()
2075 //        return "DateTimeFormatter[" + locale +
2076 //                (chrono != null ? "," + chrono : "") +
2077 //                (zone != null ? "," + zone : "") +
2078 //                pattern + "]";
2079     }
2080 
2081     //-----------------------------------------------------------------------
2082     /**
2083      * Implements the classic Java Format API.
2084      * @serial exclude
2085      */
2086     @SuppressWarnings("serial")  // not actually serializable
2087     static class ClassicFormat extends Format {
2088         /** The formatter. */
2089         private final DateTimeFormatter formatter;
2090         /** The type to be parsed. */
2091         private final TemporalQuery<?> parseType;
2092         /** Constructor. */
2093         public ClassicFormat(DateTimeFormatter formatter, TemporalQuery<?> parseType) {
2094             this.formatter = formatter;
2095             this.parseType = parseType;
2096         }
2097 
2098         @Override
2099         public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
2100             Objects.requireNonNull(obj, "obj");
2101             Objects.requireNonNull(toAppendTo, "toAppendTo");
2102             Objects.requireNonNull(pos, "pos");
2103             if (obj instanceof TemporalAccessor == false) {
2104                 throw new IllegalArgumentException("Format target must implement TemporalAccessor");
2105             }
2106             pos.setBeginIndex(0);
2107             pos.setEndIndex(0);
2108             try {
2109                 formatter.formatTo((TemporalAccessor) obj, toAppendTo);
2110             } catch (RuntimeException ex) {
2111                 throw new IllegalArgumentException(ex.getMessage(), ex);
2112             }
2113             return toAppendTo;
2114         }
2115         @Override
2116         public Object parseObject(String text) throws ParseException {
2117             Objects.requireNonNull(text, "text");
2118             try {
2119                 if (parseType == null) {
2120                     return formatter.parseResolved0(text, null);
2121                 }
2122                 return formatter.parse(text, parseType);
2123             } catch (DateTimeParseException ex) {
2124                 throw new ParseException(ex.getMessage(), ex.getErrorIndex());
2125             } catch (RuntimeException ex) {
2126                 throw (ParseException) new ParseException(ex.getMessage(), 0).initCause(ex);
2127             }
2128         }
2129         @Override
2130         public Object parseObject(String text, ParsePosition pos) {
2131             Objects.requireNonNull(text, "text");
2132             Parsed unresolved;
2133             try {
2134                 unresolved = formatter.parseUnresolved0(text, pos);
2135             } catch (IndexOutOfBoundsException ex) {
2136                 if (pos.getErrorIndex() < 0) {
2137                     pos.setErrorIndex(0);
2138                 }
2139                 return null;
2140             }
2141             if (unresolved == null) {
2142                 if (pos.getErrorIndex() < 0) {
2143                     pos.setErrorIndex(0);
2144                 }
2145                 return null;
2146             }
2147             try {
2148                 TemporalAccessor resolved = unresolved.resolve(formatter.resolverStyle, formatter.resolverFields);
2149                 if (parseType == null) {
2150                     return resolved;
2151                 }
2152                 return resolved.query(parseType);
2153             } catch (RuntimeException ex) {
2154                 pos.setErrorIndex(0);
2155                 return null;
2156             }
2157         }
2158     }
2159 
2160 }