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