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