/* * 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}. *
* This utility class provides three different ways to obtain a formatter. *
* *
* 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'. *
* The returned formatter will use the default locale, but this can be changed * using {@link DateTimeFormatter#withLocale(Locale)}. *
* All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. * The following pattern letters are defined: *
* 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 **
* The count of pattern letters determine the format. *
* Text: 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}. *
* Number: 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)}. *
* Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. * Otherwise use the Number rules above. *
* Fraction: 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. *
* Year: 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} *
* ZoneId: 'I' outputs the zone ID, such as 'Europe/Paris'. *
* Offset X: 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'. *
* Offset Z: 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'. *
* Zone names: Time zone names ('z') cannot be parsed. *
* Optional section: The optional section markers work exactly like calling * {@link DateTimeFormatterBuilder#optionalStart()} and {@link DateTimeFormatterBuilder#optionalEnd()}. *
* Pad modifier: 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)}. *
* For example, 'ppH' outputs the hour-of-day padded on the left with spaces to a width of 2. *
* 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. *
* 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. *
* 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'. *
* See {@link #pattern(String)} for details of the pattern. *
* 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. *
* This returns a formatter that will print/parse a date. * The exact format pattern used varies by locale. *
* 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. *
* 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. *
* This returns a formatter that will print/parse a time. * The exact format pattern used varies by locale. *
* 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. *
* 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. *
* This returns a formatter that will print/parse a date-time. * The exact format pattern used varies by locale. *
* 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. *
* 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. *
* This returns a formatter that will print/parse a date-time. * The exact format pattern used varies by locale. *
* 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. *
* 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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended local date format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset date format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended date format. * The format consists of: *
* 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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended local time format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset time format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset time format. * The format consists of: *
* 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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset date-time format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset date-time format. * The format consists of: *
* * @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]'. *
* 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: *
* * @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]'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended offset date-time format. * The format consists of: *
* 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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended ordinal date format. * The format consists of: *
* 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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 extended week-based date format. * The format consists of: *
* 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. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 instant format. * The format consists of: *
* * @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'. *
* This returns an immutable formatter capable of printing and parsing * the ISO-8601 basic local date format. * The format consists of: *
* 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'. *
* 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. *
* The format consists of: *
* 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