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