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