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