jdk/src/share/classes/java/time/format/DateTimeFormatters.java
changeset 15658 55b829ca2334
parent 15657 c588664d547e
child 15659 e575dab44ff5
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatters.java	Tue Feb 12 16:02:14 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,972 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file:
- *
- * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  * Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- *  * Neither the name of JSR-310 nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package java.time.format;
-
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.DAY_OF_WEEK;
-import static java.time.temporal.ChronoField.DAY_OF_YEAR;
-import static java.time.temporal.ChronoField.HOUR_OF_DAY;
-import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.NANO_OF_SECOND;
-import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
-import static java.time.temporal.ChronoField.YEAR;
-
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ISOFields;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Provides common implementations of {@code DateTimeFormatter}.
- * <p>
- * This utility class provides three different ways to obtain a formatter.
- * <p><ul>
- * <li>Using pattern letters, such as {@code yyyy-MMM-dd}
- * <li>Using localized styles, such as {@code long} or {@code medium}
- * <li>Using predefined constants, such as {@code isoLocalDate()}
- * </ul><p>
- *
- * <h3>Specification for implementors</h3>
- * This is a thread-safe utility class.
- * All returned formatters are immutable and thread-safe.
- *
- * @since 1.8
- */
-public final class DateTimeFormatters {
-
-    /**
-     * Private constructor since this is a utility class.
-     */
-    private DateTimeFormatters() {
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates a formatter using the specified pattern.
-     * <p>
-     * This method will create a formatter based on a simple pattern of letters and symbols.
-     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
-     * <p>
-     * The returned formatter will use the default locale, but this can be changed
-     * using {@link DateTimeFormatter#withLocale(Locale)}.
-     * <p>
-     * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
-     * The following pattern letters are defined:
-     * <pre>
-     *  Symbol  Meaning                     Presentation      Examples
-     *  ------  -------                     ------------      -------
-     *   G       era                         number/text       1; 01; AD; Anno Domini
-     *   y       year                        year              2004; 04
-     *   D       day-of-year                 number            189
-     *   M       month-of-year               number/text       7; 07; Jul; July; J
-     *   d       day-of-month                number            10
-     *
-     *   Q       quarter-of-year             number/text       3; 03; Q3
-     *   Y       week-based-year             year              1996; 96
-     *   w       week-of-year                number            27
-     *   W       week-of-month               number            27
-     *   e       localized day-of-week       number            2; Tue; Tuesday; T
-     *   E       day-of-week                 number/text       2; Tue; Tuesday; T
-     *   F       week-of-month               number            3
-     *
-     *   a       am-pm-of-day                text              PM
-     *   h       clock-hour-of-am-pm (1-12)  number            12
-     *   K       hour-of-am-pm (0-11)        number            0
-     *   k       clock-hour-of-am-pm (1-24)  number            0
-     *
-     *   H       hour-of-day (0-23)          number            0
-     *   m       minute-of-hour              number            30
-     *   s       second-of-minute            number            55
-     *   S       fraction-of-second          fraction          978
-     *   A       milli-of-day                number            1234
-     *   n       nano-of-second              number            987654321
-     *   N       nano-of-day                 number            1234000000
-     *
-     *   I       time-zone ID                zoneId            America/Los_Angeles
-     *   z       time-zone name              text              Pacific Standard Time; PST
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
-     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
-     *
-     *   p       pad next                    pad modifier      1
-     *
-     *   '       escape for text             delimiter
-     *   ''      single quote                literal           '
-     *   [       optional section start
-     *   ]       optional section end
-     *   {}      reserved for future use
-     * </pre>
-     * <p>
-     * The count of pattern letters determine the format.
-     * <p>
-     * <b>Text</b>: The text style is determined based on the number of pattern letters used.
-     * Less than 4 pattern letters will use the {@link TextStyle#SHORT short form}.
-     * Exactly 4 pattern letters will use the {@link TextStyle#FULL full form}.
-     * Exactly 5 pattern letters will use the {@link TextStyle#NARROW narrow form}.
-     * <p>
-     * <b>Number</b>: If the count of letters is one, then the value is printed using the minimum number
-     * of digits and without padding as per {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField)}.
-     * Otherwise, the count of digits is used as the width of the output field as per
-     * {@link DateTimeFormatterBuilder#appendValue(java.time.temporal.TemporalField, int)}.
-     * <p>
-     * <b>Number/Text</b>: If the count of pattern letters is 3 or greater, use the Text rules above.
-     * Otherwise use the Number rules above.
-     * <p>
-     * <b>Fraction</b>: Outputs the nano-of-second field as a fraction-of-second.
-     * The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9.
-     * If it is less than 9, then the nano-of-second value is truncated, with only the most
-     * significant digits being output.
-     * When parsing in strict mode, the number of parsed digits must match the count of pattern letters.
-     * When parsing in lenient mode, the number of parsed digits must be at least the count of pattern
-     * letters, up to 9 digits.
-     * <p>
-     * <b>Year</b>: The count of letters determines the minimum field width below which padding is used.
-     * If the count of letters is two, then a {@link DateTimeFormatterBuilder#appendValueReduced reduced}
-     * two digit form is used.
-     * For printing, this outputs the rightmost two digits. For parsing, this will parse using the
-     * base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
-     * If the count of letters is less than four (but not two), then the sign is only output for negative
-     * years as per {@link SignStyle#NORMAL}.
-     * Otherwise, the sign is output if the pad width is exceeded, as per {@link SignStyle#EXCEEDS_PAD}
-     * <p>
-     * <b>ZoneId</b>: 'I' outputs the zone ID, such as 'Europe/Paris'.
-     * <p>
-     * <b>Offset X</b>: This formats the offset using 'Z' when the offset is zero.
-     * One letter outputs just the hour', such as '+01'
-     * Two letters outputs the hour and minute, without a colon, such as '+0130'.
-     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
-     * Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'.
-     * Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'.
-     * <p>
-     * <b>Offset Z</b>: This formats the offset using '+0000' or '+00:00' when the offset is zero.
-     * One or two letters outputs the hour and minute, without a colon, such as '+0130'.
-     * Three letters outputs the hour and minute, with a colon, such as '+01:30'.
-     * <p>
-     * <b>Zone names</b>: Time zone names ('z') cannot be parsed.
-     * <p>
-     * <b>Optional section</b>: The optional section markers work exactly like calling
-     * {@link DateTimeFormatterBuilder#optionalStart()} and {@link DateTimeFormatterBuilder#optionalEnd()}.
-     * <p>
-     * <b>Pad modifier</b>: Modifies the pattern that immediately follows to be padded with spaces.
-     * The pad width is determined by the number of pattern letters.
-     * This is the same as calling {@link DateTimeFormatterBuilder#padNext(int)}.
-     * <p>
-     * For example, 'ppH' outputs the hour-of-day padded on the left with spaces to a width of 2.
-     * <p>
-     * Any unrecognized letter is an error.
-     * Any non-letter character, other than '[', ']', '{', '}' and the single quote will be output directly.
-     * Despite this, it is recommended to use single quotes around all characters that you want to
-     * output directly to ensure that future changes do not break your application.
-     * <p>
-     * The pattern string is similar, but not identical, to {@link java.text.SimpleDateFormat SimpleDateFormat}.
-     * Pattern letters 'E' and 'u' are merged, which changes the meaning of "E" and "EE" to be numeric.
-     * Pattern letters 'Z' and 'X' are extended.
-     * Pattern letter 'y' and 'Y' parse years of two digits and more than 4 digits differently.
-     * Pattern letters 'n', 'A', 'N', 'I' and 'p' are added.
-     * Number types will reject large numbers.
-     * The pattern string is also similar, but not identical, to that defined by the
-     * Unicode Common Locale Data Repository (CLDR).
-     *
-     * @param pattern  the pattern to use, not null
-     * @return the formatter based on the pattern, not null
-     * @throws IllegalArgumentException if the pattern is invalid
-     * @see DateTimeFormatterBuilder#appendPattern(String)
-     */
-    public static DateTimeFormatter pattern(String pattern) {
-        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
-    }
-
-    /**
-     * Creates a formatter using the specified pattern.
-     * <p>
-     * This method will create a formatter based on a simple pattern of letters and symbols.
-     * For example, {@code d MMM yyyy} will format 2011-12-03 as '3 Dec 2011'.
-     * <p>
-     * See {@link #pattern(String)} for details of the pattern.
-     * <p>
-     * The returned formatter will use the specified locale, but this can be changed
-     * using {@link DateTimeFormatter#withLocale(Locale)}.
-     *
-     * @param pattern  the pattern to use, not null
-     * @param locale  the locale to use, not null
-     * @return the formatter based on the pattern, not null
-     * @throws IllegalArgumentException if the pattern is invalid
-     * @see DateTimeFormatterBuilder#appendPattern(String)
-     */
-    public static DateTimeFormatter pattern(String pattern, Locale locale) {
-        return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a locale specific date format.
-     * <p>
-     * This returns a formatter that will print/parse a date.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateStyle  the formatter style to obtain, not null
-     * @return the date formatter, not null
-     */
-    public static DateTimeFormatter localizedDate(FormatStyle dateStyle) {
-        Objects.requireNonNull(dateStyle, "dateStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific time format.
-     * <p>
-     * This returns a formatter that will print/parse a time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param timeStyle  the formatter style to obtain, not null
-     * @return the time formatter, not null
-     */
-    public static DateTimeFormatter localizedTime(FormatStyle timeStyle) {
-        Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific date-time format, which is typically of short length.
-     * <p>
-     * This returns a formatter that will print/parse a date-time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateTimeStyle  the formatter style to obtain, not null
-     * @return the date-time formatter, not null
-     */
-    public static DateTimeFormatter localizedDateTime(FormatStyle dateTimeStyle) {
-        Objects.requireNonNull(dateTimeStyle, "dateTimeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle).toFormatter();
-    }
-
-    /**
-     * Returns a locale specific date and time format.
-     * <p>
-     * This returns a formatter that will print/parse a date-time.
-     * The exact format pattern used varies by locale.
-     * <p>
-     * The locale is determined from the formatter. The formatter returned directly by
-     * this method will use the {@link Locale#getDefault() default FORMAT locale}.
-     * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)}
-     * on the result of this method.
-     * <p>
-     * Note that the localized pattern is looked up lazily.
-     * This {@code DateTimeFormatter} holds the style required and the locale,
-     * looking up the pattern required on demand.
-     *
-     * @param dateStyle  the date formatter style to obtain, not null
-     * @param timeStyle  the time formatter style to obtain, not null
-     * @return the date, time or date-time formatter, not null
-     */
-    public static DateTimeFormatter localizedDateTime(FormatStyle dateStyle, FormatStyle timeStyle) {
-        Objects.requireNonNull(dateStyle, "dateStyle");
-        Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle).toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date without an offset,
-     * such as '2011-12-03'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended local date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A dash
-     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     *  This is pre-padded by zero to ensure two digits.
-     * </ul><p>
-     *
-     * @return the ISO local date formatter, not null
-     */
-    public static DateTimeFormatter isoLocalDate() {
-        return ISO_LOCAL_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_DATE;
-    static {
-        ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
-            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral('-')
-            .appendValue(MONTH_OF_YEAR, 2)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_MONTH, 2)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date with an offset,
-     * such as '2011-12-03+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset date formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetDate() {
-        return ISO_OFFSET_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_DATE;
-    static {
-        ISO_OFFSET_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date with the
-     * offset if available, such as '2011-12-03' or '2011-12-03+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO date formatter, not null
-     */
-    public static DateTimeFormatter isoDate() {
-        return ISO_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_DATE;
-    static {
-        ISO_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time without an offset,
-     * such as '10:15' or '10:15:30'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended local time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the second-of-minute is not available to print/parse then the format is complete.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the nano-of-second is zero or not available to print/parse then the format is complete.
-     * <li>A decimal point
-     * <li>One to nine digits for the {@link ChronoField#NANO_OF_SECOND nano-of-second}.
-     *  As many digits will be printed as required.
-     * </ul><p>
-     *
-     * @return the ISO local time formatter, not null
-     */
-    public static DateTimeFormatter isoLocalTime() {
-        return ISO_LOCAL_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_TIME;
-    static {
-        ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
-            .appendValue(HOUR_OF_DAY, 2)
-            .appendLiteral(':')
-            .appendValue(MINUTE_OF_HOUR, 2)
-            .optionalStart()
-            .appendLiteral(':')
-            .appendValue(SECOND_OF_MINUTE, 2)
-            .optionalStart()
-            .appendFraction(NANO_OF_SECOND, 0, 9, true)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time with an offset,
-     * such as '10:15+01:00' or '10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalTime()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset time formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetTime() {
-        return ISO_OFFSET_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_TIME;
-    static {
-        ISO_OFFSET_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_TIME)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO time formatter that prints/parses a time, with the
-     * offset if available, such as '10:15', '10:15:30' or '10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalTime()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO time formatter, not null
-     */
-    public static DateTimeFormatter isoTime() {
-        return ISO_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_TIME;
-    static {
-        ISO_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_TIME)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * without an offset, such as '2011-12-03T10:15:30'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDate()}
-     * <li>The letter 'T'. Parsing is case insensitive.
-     * <li>The {@link #isoLocalTime()}
-     * </ul><p>
-     *
-     * @return the ISO local date-time formatter, not null
-     */
-    public static DateTimeFormatter isoLocalDateTime() {
-        return ISO_LOCAL_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
-    static {
-        ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE)
-            .appendLiteral('T')
-            .append(ISO_LOCAL_TIME)
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * with an offset, such as '2011-12-03T10:15:30+01:00'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDateTime()}
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO offset date-time formatter, not null
-     */
-    public static DateTimeFormatter isoOffsetDateTime() {
-        return ISO_OFFSET_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_OFFSET_DATE_TIME;
-    static {
-        ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .append(ISO_LOCAL_DATE_TIME)
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time with
-     * offset and zone, such as '2011-12-03T10:15:30+01:00[Europe/Paris]'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * a format that extends the ISO-8601 extended offset date-time format
-     * to add the time-zone.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoOffsetDateTime()}
-     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
-     * <li>An open square bracket '['.
-     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
-     *  Parsing is case sensitive.
-     * <li>A close square bracket ']'.
-     * </ul><p>
-     *
-     * @return the ISO zoned date-time formatter, not null
-     */
-    public static DateTimeFormatter isoZonedDateTime() {
-        return ISO_ZONED_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_ZONED_DATE_TIME;
-    static {
-        ISO_ZONED_DATE_TIME = new DateTimeFormatterBuilder()
-            .append(ISO_OFFSET_DATE_TIME)
-            .optionalStart()
-            .appendLiteral('[')
-            .parseCaseSensitive()
-            .appendZoneRegionId()
-            .appendLiteral(']')
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date-time
-     * with the offset and zone if available, such as '2011-12-03T10:15:30',
-     * '2011-12-03T10:15:30+01:00' or '2011-12-03T10:15:30+01:00[Europe/Paris]'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended offset date-time format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoLocalDateTime()}
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     * <li>If the zone ID is not available or is a {@code ZoneOffset} then the format is complete.
-     * <li>An open square bracket '['.
-     * <li>The {@link ZoneId#getId() zone ID}. This is not part of the ISO-8601 standard.
-     *  Parsing is case sensitive.
-     * <li>A close square bracket ']'.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO date-time formatter, not null
-     */
-    public static DateTimeFormatter isoDateTime() {
-        return ISO_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_DATE_TIME;
-    static {
-        ISO_DATE_TIME = new DateTimeFormatterBuilder()
-            .append(ISO_LOCAL_DATE_TIME)
-            .optionalStart()
-            .appendOffsetId()
-            .optionalStart()
-            .appendLiteral('[')
-            .parseCaseSensitive()
-            .appendZoneRegionId()
-            .appendLiteral(']')
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses the ordinal date
-     * without an offset, such as '2012-337'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended ordinal date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ChronoField#YEAR year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>Three digits for the {@link ChronoField#DAY_OF_YEAR day-of-year}.
-     *  This is pre-padded by zero to ensure three digits.
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO ordinal date formatter, not null
-     */
-    public static DateTimeFormatter isoOrdinalDate() {
-        return ISO_ORDINAL_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_ORDINAL_DATE;
-    static {
-        ISO_ORDINAL_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_YEAR, 3)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses the week-based date
-     * without an offset, such as '2012-W48-6'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 extended week-based date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits or more for the {@link ISOFields#WEEK_BASED_YEAR week-based-year}.
-     * Years in the range 0000 to 9999 will be pre-padded by zero to ensure four digits.
-     * Years outside that range will have a prefixed positive or negative symbol.
-     * <li>A dash
-     * <li>The letter 'W'. Parsing is case insensitive.
-     * <li>Two digits for the {@link ISOFields#WEEK_OF_WEEK_BASED_YEAR week-of-week-based-year}.
-     *  This is pre-padded by zero to ensure three digits.
-     * <li>A dash
-     * <li>One digit for the {@link ChronoField#DAY_OF_WEEK day-of-week}.
-     *  The value run from Monday (1) to Sunday (7).
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
-     *  they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO week-based date formatter, not null
-     */
-    public static DateTimeFormatter isoWeekDate() {
-        return ISO_WEEK_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter ISO_WEEK_DATE;
-    static {
-        ISO_WEEK_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(ISOFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
-            .appendLiteral("-W")
-            .appendValue(ISOFields.WEEK_OF_WEEK_BASED_YEAR, 2)
-            .appendLiteral('-')
-            .appendValue(DAY_OF_WEEK, 1)
-            .optionalStart()
-            .appendOffsetId()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO instant formatter that prints/parses an instant in UTC.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 instant format.
-     * The format consists of:
-     * <p><ul>
-     * <li>The {@link #isoOffsetDateTime()} where the instant is converted from
-     *  {@link ChronoField#INSTANT_SECONDS} and {@link ChronoField#NANO_OF_SECOND}
-     *  using the {@code UTC} offset. Parsing is case insensitive.
-     * </ul><p>
-     *
-     * @return the ISO instant formatter, not null
-     */
-    public static DateTimeFormatter isoInstant() {
-        return ISO_INSTANT;
-    }
-
-    /** Singleton formatter. */
-    private static final DateTimeFormatter ISO_INSTANT;
-    static {
-        ISO_INSTANT = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendInstant()
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the ISO date formatter that prints/parses a date without an offset,
-     * such as '20111203'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * the ISO-8601 basic local date format.
-     * The format consists of:
-     * <p><ul>
-     * <li>Four digits for the {@link ChronoField#YEAR year}.
-     *  Only years in the range 0000 to 9999 are supported.
-     * <li>Two digits for the {@link ChronoField#MONTH_OF_YEAR month-of-year}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>Two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the offset is not available to print/parse then the format is complete.
-     * <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
-     *  seconds then they will be handled even though this is not part of the ISO-8601 standard.
-     *  Parsing is case insensitive.
-     * </ul><p>
-     * As this formatter has an optional element, it may be necessary to parse using
-     * {@link DateTimeFormatter#parseBest}.
-     *
-     * @return the ISO basic local date formatter, not null
-     */
-    public static DateTimeFormatter basicIsoDate() {
-        return BASIC_ISO_DATE;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter BASIC_ISO_DATE;
-    static {
-        BASIC_ISO_DATE = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .appendValue(YEAR, 4)
-            .appendValue(MONTH_OF_YEAR, 2)
-            .appendValue(DAY_OF_MONTH, 2)
-            .optionalStart()
-            .appendOffset("+HHMMss", "Z")
-            .toFormatter();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the RFC-1123 date-time formatter, such as 'Tue, 3 Jun 2008 11:05:30 GMT'.
-     * <p>
-     * This returns an immutable formatter capable of printing and parsing
-     * most of the RFC-1123 format.
-     * RFC-1123 updates RFC-822 changing the year from two digits to four.
-     * This implementation requires a four digit year.
-     * This implementation also does not handle North American or military zone
-     * names, only 'GMT' and offset amounts.
-     * <p>
-     * The format consists of:
-     * <p><ul>
-     * <li>If the day-of-week is not available to print/parse then jump to day-of-month.
-     * <li>Three letter {@link ChronoField#DAY_OF_WEEK day-of-week} in English.
-     * <li>A comma
-     * <li>A space
-     * <li>One or two digits for the {@link ChronoField#DAY_OF_MONTH day-of-month}.
-     * <li>A space
-     * <li>Three letter {@link ChronoField#MONTH_OF_YEAR month-of-year} in English.
-     * <li>A space
-     * <li>Four digits for the {@link ChronoField#YEAR year}.
-     *  Only years in the range 0000 to 9999 are supported.
-     * <li>A space
-     * <li>Two digits for the {@link ChronoField#HOUR_OF_DAY hour-of-day}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#MINUTE_OF_HOUR minute-of-hour}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>If the second-of-minute is not available to print/parse then jump to the next space.
-     * <li>A colon
-     * <li>Two digits for the {@link ChronoField#SECOND_OF_MINUTE second-of-minute}.
-     *  This is pre-padded by zero to ensure two digits.
-     * <li>A space
-     * <li>The {@link ZoneOffset#getId() offset ID} without colons or seconds.
-     *  An offset of zero uses "GMT". North American zone names and military zone names are not handled.
-     * </ul><p>
-     * Parsing is case insensitive.
-     *
-     * @return the RFC-1123 formatter, not null
-     */
-    public static DateTimeFormatter rfc1123() {
-        return RFC_1123_DATE_TIME;
-    }
-
-    /** Singleton date formatter. */
-    private static final DateTimeFormatter RFC_1123_DATE_TIME;
-    static {
-        // manually code maps to ensure correct data always used
-        // (locale data can be changed by application code)
-        Map<Long, String> dow = new HashMap<>();
-        dow.put(1L, "Mon");
-        dow.put(2L, "Tue");
-        dow.put(3L, "Wed");
-        dow.put(4L, "Thu");
-        dow.put(5L, "Fri");
-        dow.put(6L, "Sat");
-        dow.put(7L, "Sun");
-        Map<Long, String> moy = new HashMap<>();
-        moy.put(1L, "Jan");
-        moy.put(2L, "Feb");
-        moy.put(3L, "Mar");
-        moy.put(4L, "Apr");
-        moy.put(5L, "May");
-        moy.put(6L, "Jun");
-        moy.put(7L, "Jul");
-        moy.put(8L, "Aug");
-        moy.put(9L, "Sep");
-        moy.put(10L, "Oct");
-        moy.put(11L, "Nov");
-        moy.put(12L, "Dec");
-        RFC_1123_DATE_TIME = new DateTimeFormatterBuilder()
-            .parseCaseInsensitive()
-            .parseLenient()
-            .optionalStart()
-            .appendText(DAY_OF_WEEK, dow)
-            .appendLiteral(", ")
-            .optionalEnd()
-            .appendValue(DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
-            .appendLiteral(' ')
-            .appendText(MONTH_OF_YEAR, moy)
-            .appendLiteral(' ')
-            .appendValue(YEAR, 4)  // 2 digit year not handled
-            .appendLiteral(' ')
-            .appendValue(HOUR_OF_DAY, 2)
-            .appendLiteral(':')
-            .appendValue(MINUTE_OF_HOUR, 2)
-            .optionalStart()
-            .appendLiteral(':')
-            .appendValue(SECOND_OF_MINUTE, 2)
-            .optionalEnd()
-            .appendLiteral(' ')
-            .appendOffset("+HHMM", "GMT")  // should handle UT/Z/EST/EDT/CST/CDT/MST/MDT/PST/MDT
-            .toFormatter();
-    }
-
-}