org.codelibs.elasticsearch.common.joda.StrictISODateTimeFormat Maven / Gradle / Ivy
package org.codelibs.elasticsearch.common.joda;
/*
* Copyright 2001-2009 Stephen Colebourne
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.joda.time.DateTimeFieldType;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/*
* Elasticsearch Note: This class has been copied almost identically from joda, where the
* class is named ISODatetimeFormat
*
* However there has been done one huge modification in several methods, which forces the date
* year to be at least n digits, so that a year like "5" is invalid and must be "0005"
*
* All methods have been marked with an "// ES change" commentary
*
* In case you compare this with the original ISODateTimeFormat, make sure you use a diff
* call, that ignores whitespaces/tabs/indendetations like 'diff -b'
*/
/**
* Factory that creates instances of DateTimeFormatter based on the ISO8601 standard.
*
* Date-time formatting is performed by the {DateTimeFormatter} class.
* Three classes provide factory methods to create formatters, and this is one.
* The others are {DateTimeFormat} and {DateTimeFormatterBuilder}.
*
* ISO8601 is the international standard for data interchange. It defines a
* framework, rather than an absolute standard. As a result this provider has a
* number of methods that represent common uses of the framework. The most common
* formats are {#date() date}, {#time() time}, and {#dateTime() dateTime}.
*
* For example, to format a date time in ISO format:
*
* DateTime dt = new DateTime();
* DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
* String str = fmt.print(dt);
*
*
* Note that these formatters mostly follow the ISO8601 standard for printing.
* For parsing, the formatters are more lenient and allow formats that are not
* in strict compliance with the standard.
*
* It is important to understand that these formatters are not linked to
* the ISOChronology
. These formatters may be used with any
* chronology, however there may be certain side effects with more unusual
* chronologies. For example, the ISO formatters rely on dayOfWeek being
* single digit, dayOfMonth being two digit and dayOfYear being three digit.
* A chronology with a ten day week would thus cause issues. However, in
* general, it is safe to use these formatters with other chronologies.
*
* ISODateTimeFormat is thread-safe and immutable, and the formatters it
* returns are as well.
*
* @author Brian S O'Neill
* @since 1.0
* @see DateTimeFormatterBuilder
*/
public class StrictISODateTimeFormat {
/**
* Constructor.
*
* @since 1.1 (previously private)
*/
protected StrictISODateTimeFormat() {
super();
}
//-----------------------------------------------------------------------
/**
* Returns a formatter that outputs only those fields specified.
*
* This method examines the fields provided and returns an ISO-style
* formatter that best fits. This can be useful for outputting
* less-common ISO styles, such as YearMonth (YYYY-MM) or MonthDay (--MM-DD).
*
* The list provided may have overlapping fields, such as dayOfWeek and
* dayOfMonth. In this case, the style is chosen based on the following
* list, thus in the example, the calendar style is chosen as dayOfMonth
* is higher in priority than dayOfWeek:
*
* - monthOfYear - calendar date style
*
- dayOfYear - ordinal date style
*
- weekOfWeekYear - week date style
*
- dayOfMonth - calendar date style
*
- dayOfWeek - week date style
*
- year
*
- weekyear
*
* The supported formats are:
*
* Extended Basic Fields
* 2005-03-25 20050325 year/monthOfYear/dayOfMonth
* 2005-03 2005-03 year/monthOfYear
* 2005--25 2005--25 year/dayOfMonth *
* 2005 2005 year
* --03-25 --0325 monthOfYear/dayOfMonth
* --03 --03 monthOfYear
* ---03 ---03 dayOfMonth
* 2005-084 2005084 year/dayOfYear
* -084 -084 dayOfYear
* 2005-W12-5 2005W125 weekyear/weekOfWeekyear/dayOfWeek
* 2005-W-5 2005W-5 weekyear/dayOfWeek *
* 2005-W12 2005W12 weekyear/weekOfWeekyear
* -W12-5 -W125 weekOfWeekyear/dayOfWeek
* -W12 -W12 weekOfWeekyear
* -W-5 -W-5 dayOfWeek
* 10:20:30.040 102030.040 hour/minute/second/milli
* 10:20:30 102030 hour/minute/second
* 10:20 1020 hour/minute
* 10 10 hour
* -20:30.040 -2030.040 minute/second/milli
* -20:30 -2030 minute/second
* -20 -20 minute
* --30.040 --30.040 second/milli
* --30 --30 second
* ---.040 ---.040 milli *
* 10-30.040 10-30.040 hour/second/milli *
* 10:20-.040 1020-.040 hour/minute/milli *
* 10-30 10-30 hour/second *
* 10--.040 10--.040 hour/milli *
* -20-.040 -20-.040 minute/milli *
* plus datetime formats like {date}T{time}
*
* * indiates that this is not an official ISO format and can be excluded
* by passing in strictISO
as true
.
*
* This method can side effect the input collection of fields.
* If the input collection is modifiable, then each field that was added to
* the formatter will be removed from the collection, including any duplicates.
* If the input collection is unmodifiable then no side effect occurs.
*
* This side effect processing is useful if you need to know whether all
* the fields were converted into the formatter or not. To achieve this,
* pass in a modifiable list, and check that it is empty on exit.
*
* @param fields the fields to get a formatter for, not null,
* updated by the method call unless unmodifiable,
* removing those fields built in the formatter
* @param extended true to use the extended format (with separators)
* @param strictISO true to stick exactly to ISO8601, false to include additional formats
* @return a suitable formatter
* @throws IllegalArgumentException if there is no format for the fields
* @since 1.1
*/
public static DateTimeFormatter forFields(
Collection fields,
boolean extended,
boolean strictISO) {
if (fields == null || fields.size() == 0) {
throw new IllegalArgumentException("The fields must not be null or empty");
}
Set workingFields = new HashSet<>(fields);
int inputSize = workingFields.size();
boolean reducedPrec = false;
DateTimeFormatterBuilder bld = new DateTimeFormatterBuilder();
// date
if (workingFields.contains(DateTimeFieldType.monthOfYear())) {
reducedPrec = dateByMonth(bld, workingFields, extended, strictISO);
} else if (workingFields.contains(DateTimeFieldType.dayOfYear())) {
reducedPrec = dateByOrdinal(bld, workingFields, extended);
} else if (workingFields.contains(DateTimeFieldType.weekOfWeekyear())) {
reducedPrec = dateByWeek(bld, workingFields, extended, strictISO);
} else if (workingFields.contains(DateTimeFieldType.dayOfMonth())) {
reducedPrec = dateByMonth(bld, workingFields, extended, strictISO);
} else if (workingFields.contains(DateTimeFieldType.dayOfWeek())) {
reducedPrec = dateByWeek(bld, workingFields, extended, strictISO);
} else if (workingFields.remove(DateTimeFieldType.year())) {
bld.append(Constants.ye);
reducedPrec = true;
} else if (workingFields.remove(DateTimeFieldType.weekyear())) {
bld.append(Constants.we);
reducedPrec = true;
}
boolean datePresent = (workingFields.size() < inputSize);
// time
time(bld, workingFields, extended, strictISO, reducedPrec, datePresent);
// result
if (bld.canBuildFormatter() == false) {
throw new IllegalArgumentException("No valid format for fields: " + fields);
}
// side effect the input collection to indicate the processed fields
// handling unmodifiable collections with no side effect
try {
fields.retainAll(workingFields);
} catch (UnsupportedOperationException ex) {
// ignore, so we can handle unmodifiable collections
}
return bld.toFormatter();
}
//-----------------------------------------------------------------------
/**
* Creates a date using the calendar date format.
* Specification reference: 5.2.1.
*
* @param bld the builder
* @param fields the fields
* @param extended true to use extended format
* @param strictISO true to only allow ISO formats
* @return true if reduced precision
* @since 1.1
*/
private static boolean dateByMonth(
DateTimeFormatterBuilder bld,
Collection fields,
boolean extended,
boolean strictISO) {
boolean reducedPrec = false;
if (fields.remove(DateTimeFieldType.year())) {
bld.append(Constants.ye);
if (fields.remove(DateTimeFieldType.monthOfYear())) {
if (fields.remove(DateTimeFieldType.dayOfMonth())) {
// YYYY-MM-DD/YYYYMMDD
appendSeparator(bld, extended);
bld.appendMonthOfYear(2);
appendSeparator(bld, extended);
bld.appendDayOfMonth(2);
} else {
// YYYY-MM/YYYY-MM
bld.appendLiteral('-');
bld.appendMonthOfYear(2);
reducedPrec = true;
}
} else {
if (fields.remove(DateTimeFieldType.dayOfMonth())) {
// YYYY--DD/YYYY--DD (non-iso)
checkNotStrictISO(fields, strictISO);
bld.appendLiteral('-');
bld.appendLiteral('-');
bld.appendDayOfMonth(2);
} else {
// YYYY/YYYY
reducedPrec = true;
}
}
} else if (fields.remove(DateTimeFieldType.monthOfYear())) {
bld.appendLiteral('-');
bld.appendLiteral('-');
bld.appendMonthOfYear(2);
if (fields.remove(DateTimeFieldType.dayOfMonth())) {
// --MM-DD/--MMDD
appendSeparator(bld, extended);
bld.appendDayOfMonth(2);
} else {
// --MM/--MM
reducedPrec = true;
}
} else if (fields.remove(DateTimeFieldType.dayOfMonth())) {
// ---DD/---DD
bld.appendLiteral('-');
bld.appendLiteral('-');
bld.appendLiteral('-');
bld.appendDayOfMonth(2);
}
return reducedPrec;
}
//-----------------------------------------------------------------------
/**
* Creates a date using the ordinal date format.
* Specification reference: 5.2.2.
*
* @param bld the builder
* @param fields the fields
* @param extended true to use extended format
* @since 1.1
*/
private static boolean dateByOrdinal(
DateTimeFormatterBuilder bld,
Collection fields,
boolean extended) {
boolean reducedPrec = false;
if (fields.remove(DateTimeFieldType.year())) {
bld.append(Constants.ye);
if (fields.remove(DateTimeFieldType.dayOfYear())) {
// YYYY-DDD/YYYYDDD
appendSeparator(bld, extended);
bld.appendDayOfYear(3);
} else {
// YYYY/YYYY
reducedPrec = true;
}
} else if (fields.remove(DateTimeFieldType.dayOfYear())) {
// -DDD/-DDD
bld.appendLiteral('-');
bld.appendDayOfYear(3);
}
return reducedPrec;
}
//-----------------------------------------------------------------------
/**
* Creates a date using the calendar date format.
* Specification reference: 5.2.3.
*
* @param bld the builder
* @param fields the fields
* @param extended true to use extended format
* @param strictISO true to only allow ISO formats
* @since 1.1
*/
private static boolean dateByWeek(
DateTimeFormatterBuilder bld,
Collection fields,
boolean extended,
boolean strictISO) {
boolean reducedPrec = false;
if (fields.remove(DateTimeFieldType.weekyear())) {
bld.append(Constants.we);
if (fields.remove(DateTimeFieldType.weekOfWeekyear())) {
appendSeparator(bld, extended);
bld.appendLiteral('W');
bld.appendWeekOfWeekyear(2);
if (fields.remove(DateTimeFieldType.dayOfWeek())) {
// YYYY-WWW-D/YYYYWWWD
appendSeparator(bld, extended);
bld.appendDayOfWeek(1);
} else {
// YYYY-WWW/YYYY-WWW
reducedPrec = true;
}
} else {
if (fields.remove(DateTimeFieldType.dayOfWeek())) {
// YYYY-W-D/YYYYW-D (non-iso)
checkNotStrictISO(fields, strictISO);
appendSeparator(bld, extended);
bld.appendLiteral('W');
bld.appendLiteral('-');
bld.appendDayOfWeek(1);
} else {
// YYYY/YYYY
reducedPrec = true;
}
}
} else if (fields.remove(DateTimeFieldType.weekOfWeekyear())) {
bld.appendLiteral('-');
bld.appendLiteral('W');
bld.appendWeekOfWeekyear(2);
if (fields.remove(DateTimeFieldType.dayOfWeek())) {
// -WWW-D/-WWWD
appendSeparator(bld, extended);
bld.appendDayOfWeek(1);
} else {
// -WWW/-WWW
reducedPrec = true;
}
} else if (fields.remove(DateTimeFieldType.dayOfWeek())) {
// -W-D/-W-D
bld.appendLiteral('-');
bld.appendLiteral('W');
bld.appendLiteral('-');
bld.appendDayOfWeek(1);
}
return reducedPrec;
}
//-----------------------------------------------------------------------
/**
* Adds the time fields to the builder.
* Specification reference: 5.3.1.
*
* @param bld the builder
* @param fields the fields
* @param extended whether to use the extended format
* @param strictISO whether to be strict
* @param reducedPrec whether the date was reduced precision
* @param datePresent whether there was a date
* @since 1.1
*/
private static void time(
DateTimeFormatterBuilder bld,
Collection fields,
boolean extended,
boolean strictISO,
boolean reducedPrec,
boolean datePresent) {
boolean hour = fields.remove(DateTimeFieldType.hourOfDay());
boolean minute = fields.remove(DateTimeFieldType.minuteOfHour());
boolean second = fields.remove(DateTimeFieldType.secondOfMinute());
boolean milli = fields.remove(DateTimeFieldType.millisOfSecond());
if (!hour && !minute && !second && !milli) {
return;
}
if (hour || minute || second || milli) {
if (strictISO && reducedPrec) {
throw new IllegalArgumentException("No valid ISO8601 format for fields because Date was reduced precision: " + fields);
}
if (datePresent) {
bld.appendLiteral('T');
}
}
if (hour && minute && second || (hour && !second && !milli)) {
// OK - HMSm/HMS/HM/H - valid in combination with date
} else {
if (strictISO && datePresent) {
throw new IllegalArgumentException("No valid ISO8601 format for fields because Time was truncated: " + fields);
}
if (!hour && (minute && second || (minute && !milli) || second)) {
// OK - MSm/MS/M/Sm/S - valid ISO formats
} else {
if (strictISO) {
throw new IllegalArgumentException("No valid ISO8601 format for fields: " + fields);
}
}
}
if (hour) {
bld.appendHourOfDay(2);
} else if (minute || second || milli) {
bld.appendLiteral('-');
}
if (extended && hour && minute) {
bld.appendLiteral(':');
}
if (minute) {
bld.appendMinuteOfHour(2);
} else if (second || milli) {
bld.appendLiteral('-');
}
if (extended && minute && second) {
bld.appendLiteral(':');
}
if (second) {
bld.appendSecondOfMinute(2);
} else if (milli) {
bld.appendLiteral('-');
}
if (milli) {
bld.appendLiteral('.');
bld.appendMillisOfSecond(3);
}
}
//-----------------------------------------------------------------------
/**
* Checks that the iso only flag is not set, throwing an exception if it is.
*
* @param fields the fields
* @param strictISO true if only ISO formats allowed
* @since 1.1
*/
private static void checkNotStrictISO(Collection fields, boolean strictISO) {
if (strictISO) {
throw new IllegalArgumentException("No valid ISO8601 format for fields: " + fields);
}
}
/**
* Appends the separator if necessary.
*
* @param bld the builder
* @param extended whether to append the separator
* @since 1.1
*/
private static void appendSeparator(DateTimeFormatterBuilder bld, boolean extended) {
if (extended) {
bld.appendLiteral('-');
}
}
//-----------------------------------------------------------------------
/**
* Returns a generic ISO date parser for parsing dates with a possible zone.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* It accepts formats described by the following syntax:
*
* date = date-element ['T' offset]
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
* offset = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
*
*/
public static DateTimeFormatter dateParser() {
return Constants.dp;
}
/**
* Returns a generic ISO date parser for parsing local dates.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* This parser is initialised with the local (UTC) time zone.
*
* It accepts formats described by the following syntax:
*
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
*
* @since 1.3
*/
public static DateTimeFormatter localDateParser() {
return Constants.ldp;
}
/**
* Returns a generic ISO date parser for parsing dates.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* It accepts formats described by the following syntax:
*
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
*
*/
public static DateTimeFormatter dateElementParser() {
return Constants.dpe;
}
/**
* Returns a generic ISO time parser for parsing times with a possible zone.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* time = ['T'] time-element [offset]
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
* offset = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
*
*/
public static DateTimeFormatter timeParser() {
return Constants.tp;
}
/**
* Returns a generic ISO time parser for parsing local times.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* This parser is initialised with the local (UTC) time zone.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* time = ['T'] time-element
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
*
* @since 1.3
*/
public static DateTimeFormatter localTimeParser() {
return Constants.ltp;
}
/**
* Returns a generic ISO time parser.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
*
*/
public static DateTimeFormatter timeElementParser() {
return Constants.tpe;
}
/**
* Returns a generic ISO datetime parser which parses either a date or a time or both.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* datetime = time | date-opt-time
* time = 'T' time-element [offset]
* date-opt-time = date-element ['T' [time-element] [offset]]
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
* offset = 'Z' | (('+' | '-') HH [':' mm [':' ss [('.' | ',') SSS]]])
*
*/
public static DateTimeFormatter dateTimeParser() {
return Constants.dtp;
}
/**
* Returns a generic ISO datetime parser where the date is mandatory and the time is optional.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* This parser can parse zoned datetimes.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* date-opt-time = date-element ['T' [time-element] [offset]]
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
*
* @since 1.3
*/
public static DateTimeFormatter dateOptionalTimeParser() {
return Constants.dotp;
}
/**
* Returns a generic ISO datetime parser where the date is mandatory and the time is optional.
*
* The returned formatter can only be used for parsing, printing is unsupported.
*
* This parser only parses local datetimes.
* This parser is initialised with the local (UTC) time zone.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* It accepts formats described by the following syntax:
*
* datetime = date-element ['T' time-element]
* date-element = std-date-element | ord-date-element | week-date-element
* std-date-element = yyyy ['-' MM ['-' dd]]
* ord-date-element = yyyy ['-' DDD]
* week-date-element = xxxx '-W' ww ['-' e]
* time-element = HH [minute-element] | [fraction]
* minute-element = ':' mm [second-element] | [fraction]
* second-element = ':' ss [fraction]
* fraction = ('.' | ',') digit+
*
* @since 1.3
*/
public static DateTimeFormatter localDateOptionalTimeParser() {
return Constants.ldotp;
}
//-----------------------------------------------------------------------
/**
* Returns a formatter for a full date as four digit year, two digit month
* of year, and two digit day of month (yyyy-MM-dd).
*
* The returned formatter prints and parses only this format.
* See {#dateParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-MM-dd
*/
public static DateTimeFormatter date() {
return yearMonthDay();
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, three digit fraction of second, and
* time zone offset (HH:mm:ss.SSSZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
* See {#timeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for HH:mm:ss.SSSZZ
*/
public static DateTimeFormatter time() {
return Constants.t;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, and time zone offset (HH:mm:ssZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
* See {#timeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for HH:mm:ssZZ
*/
public static DateTimeFormatter timeNoMillis() {
return Constants.tx;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, three digit fraction of second, and
* time zone offset prefixed by 'T' ('T'HH:mm:ss.SSSZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
* See {#timeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for 'T'HH:mm:ss.SSSZZ
*/
public static DateTimeFormatter tTime() {
return Constants.tt;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, and time zone offset prefixed
* by 'T' ('T'HH:mm:ssZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
* See {#timeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for 'T'HH:mm:ssZZ
*/
public static DateTimeFormatter tTimeNoMillis() {
return Constants.ttx;
}
/**
* Returns a formatter that combines a full date and time, separated by a 'T'
* (yyyy-MM-dd'T'HH:mm:ss.SSSZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSSZZ
*/
public static DateTimeFormatter dateTime() {
return Constants.dt;
}
/**
* Returns a formatter that combines a full date and time without millis,
* separated by a 'T' (yyyy-MM-dd'T'HH:mm:ssZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-MM-dd'T'HH:mm:ssZZ
*/
public static DateTimeFormatter dateTimeNoMillis() {
return Constants.dtx;
}
/**
* Returns a formatter for a full ordinal date, using a four
* digit year and three digit dayOfYear (yyyy-DDD).
*
* The returned formatter prints and parses only this format.
* See {#dateParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-DDD
* @since 1.1
*/
public static DateTimeFormatter ordinalDate() {
return Constants.od;
}
/**
* Returns a formatter for a full ordinal date and time, using a four
* digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ss.SSSZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-DDD'T'HH:mm:ss.SSSZZ
* @since 1.1
*/
public static DateTimeFormatter ordinalDateTime() {
return Constants.odt;
}
/**
* Returns a formatter for a full ordinal date and time without millis,
* using a four digit year and three digit dayOfYear (yyyy-DDD'T'HH:mm:ssZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for yyyy-DDD'T'HH:mm:ssZZ
* @since 1.1
*/
public static DateTimeFormatter ordinalDateTimeNoMillis() {
return Constants.odtx;
}
/**
* Returns a formatter for a full date as four digit weekyear, two digit
* week of weekyear, and one digit day of week (xxxx-'W'ww-e).
*
* The returned formatter prints and parses only this format.
* See {#dateParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for xxxx-'W'ww-e
*/
public static DateTimeFormatter weekDate() {
return Constants.wwd;
}
/**
* Returns a formatter that combines a full weekyear date and time,
* separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ
*/
public static DateTimeFormatter weekDateTime() {
return Constants.wdt;
}
/**
* Returns a formatter that combines a full weekyear date and time without millis,
* separated by a 'T' (xxxx-'W'ww-e'T'HH:mm:ssZZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HH:mm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
* See {#dateTimeParser()} for a more flexible parser that accepts different formats.
*
* @return a formatter for xxxx-'W'ww-e'T'HH:mm:ssZZ
*/
public static DateTimeFormatter weekDateTimeNoMillis() {
return Constants.wdtx;
}
//-----------------------------------------------------------------------
/**
* Returns a basic formatter for a full date as four digit year, two digit
* month of year, and two digit day of month (yyyyMMdd).
*
* The returned formatter prints and parses only this format.
*
* @return a formatter for yyyyMMdd
*/
public static DateTimeFormatter basicDate() {
return Constants.bd;
}
/**
* Returns a basic formatter for a two digit hour of day, two digit minute
* of hour, two digit second of minute, three digit millis, and time zone
* offset (HHmmss.SSSZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
*
* @return a formatter for HHmmss.SSSZ
*/
public static DateTimeFormatter basicTime() {
return Constants.bt;
}
/**
* Returns a basic formatter for a two digit hour of day, two digit minute
* of hour, two digit second of minute, and time zone offset (HHmmssZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
*
* @return a formatter for HHmmssZ
*/
public static DateTimeFormatter basicTimeNoMillis() {
return Constants.btx;
}
/**
* Returns a basic formatter for a two digit hour of day, two digit minute
* of hour, two digit second of minute, three digit millis, and time zone
* offset prefixed by 'T' ('T'HHmmss.SSSZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
*
* @return a formatter for 'T'HHmmss.SSSZ
*/
public static DateTimeFormatter basicTTime() {
return Constants.btt;
}
/**
* Returns a basic formatter for a two digit hour of day, two digit minute
* of hour, two digit second of minute, and time zone offset prefixed by 'T'
* ('T'HHmmssZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
*
* @return a formatter for 'T'HHmmssZ
*/
public static DateTimeFormatter basicTTimeNoMillis() {
return Constants.bttx;
}
/**
* Returns a basic formatter that combines a basic date and time, separated
* by a 'T' (yyyyMMdd'T'HHmmss.SSSZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
*
* @return a formatter for yyyyMMdd'T'HHmmss.SSSZ
*/
public static DateTimeFormatter basicDateTime() {
return Constants.bdt;
}
/**
* Returns a basic formatter that combines a basic date and time without millis,
* separated by a 'T' (yyyyMMdd'T'HHmmssZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
*
* @return a formatter for yyyyMMdd'T'HHmmssZ
*/
public static DateTimeFormatter basicDateTimeNoMillis() {
return Constants.bdtx;
}
/**
* Returns a formatter for a full ordinal date, using a four
* digit year and three digit dayOfYear (yyyyDDD).
*
* The returned formatter prints and parses only this format.
*
* @return a formatter for yyyyDDD
* @since 1.1
*/
public static DateTimeFormatter basicOrdinalDate() {
return Constants.bod;
}
/**
* Returns a formatter for a full ordinal date and time, using a four
* digit year and three digit dayOfYear (yyyyDDD'T'HHmmss.SSSZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
*
* @return a formatter for yyyyDDD'T'HHmmss.SSSZ
* @since 1.1
*/
public static DateTimeFormatter basicOrdinalDateTime() {
return Constants.bodt;
}
/**
* Returns a formatter for a full ordinal date and time without millis,
* using a four digit year and three digit dayOfYear (yyyyDDD'T'HHmmssZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
*
* @return a formatter for yyyyDDD'T'HHmmssZ
* @since 1.1
*/
public static DateTimeFormatter basicOrdinalDateTimeNoMillis() {
return Constants.bodtx;
}
/**
* Returns a basic formatter for a full date as four digit weekyear, two
* digit week of weekyear, and one digit day of week (xxxx'W'wwe).
*
* The returned formatter prints and parses only this format.
*
* @return a formatter for xxxx'W'wwe
*/
public static DateTimeFormatter basicWeekDate() {
return Constants.bwd;
}
/**
* Returns a basic formatter that combines a basic weekyear date and time,
* separated by a 'T' (xxxx'W'wwe'T'HHmmss.SSSZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which includes milliseconds.
*
* @return a formatter for xxxx'W'wwe'T'HHmmss.SSSZ
*/
public static DateTimeFormatter basicWeekDateTime() {
return Constants.bwdt;
}
/**
* Returns a basic formatter that combines a basic weekyear date and time
* without millis, separated by a 'T' (xxxx'W'wwe'T'HHmmssZ).
*
* The time zone offset is 'Z' for zero, and of the form '\u00b1HHmm' for non-zero.
* The parser is strict by default, thus time string {@code 24:00} cannot be parsed.
*
* The returned formatter prints and parses only this format, which excludes milliseconds.
*
* @return a formatter for xxxx'W'wwe'T'HHmmssZ
*/
public static DateTimeFormatter basicWeekDateTimeNoMillis() {
return Constants.bwdtx;
}
//-----------------------------------------------------------------------
/**
* Returns a formatter for a four digit year. (yyyy)
*
* @return a formatter for yyyy
*/
public static DateTimeFormatter year() {
return Constants.ye;
}
/**
* Returns a formatter for a four digit year and two digit month of
* year. (yyyy-MM)
*
* @return a formatter for yyyy-MM
*/
public static DateTimeFormatter yearMonth() {
return Constants.ym;
}
/**
* Returns a formatter for a four digit year, two digit month of year, and
* two digit day of month. (yyyy-MM-dd)
*
* @return a formatter for yyyy-MM-dd
*/
public static DateTimeFormatter yearMonthDay() {
return Constants.ymd;
}
/**
* Returns a formatter for a four digit weekyear. (xxxx)
*
* @return a formatter for xxxx
*/
public static DateTimeFormatter weekyear() {
return Constants.we;
}
/**
* Returns a formatter for a four digit weekyear and two digit week of
* weekyear. (xxxx-'W'ww)
*
* @return a formatter for xxxx-'W'ww
*/
public static DateTimeFormatter weekyearWeek() {
return Constants.ww;
}
/**
* Returns a formatter for a four digit weekyear, two digit week of
* weekyear, and one digit day of week. (xxxx-'W'ww-e)
*
* @return a formatter for xxxx-'W'ww-e
*/
public static DateTimeFormatter weekyearWeekDay() {
return Constants.wwd;
}
/**
* Returns a formatter for a two digit hour of day. (HH)
*
* @return a formatter for HH
*/
public static DateTimeFormatter hour() {
return Constants.hde;
}
/**
* Returns a formatter for a two digit hour of day and two digit minute of
* hour. (HH:mm)
*
* @return a formatter for HH:mm
*/
public static DateTimeFormatter hourMinute() {
return Constants.hm;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, and two digit second of minute. (HH:mm:ss)
*
* @return a formatter for HH:mm:ss
*/
public static DateTimeFormatter hourMinuteSecond() {
return Constants.hms;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, and three digit fraction of
* second (HH:mm:ss.SSS). Parsing will parse up to 3 fractional second
* digits.
*
* @return a formatter for HH:mm:ss.SSS
*/
public static DateTimeFormatter hourMinuteSecondMillis() {
return Constants.hmsl;
}
/**
* Returns a formatter for a two digit hour of day, two digit minute of
* hour, two digit second of minute, and three digit fraction of
* second (HH:mm:ss.SSS). Parsing will parse up to 9 fractional second
* digits, throwing away all except the first three.
*
* @return a formatter for HH:mm:ss.SSS
*/
public static DateTimeFormatter hourMinuteSecondFraction() {
return Constants.hmsf;
}
/**
* Returns a formatter that combines a full date and two digit hour of
* day. (yyyy-MM-dd'T'HH)
*
* @return a formatter for yyyy-MM-dd'T'HH
*/
public static DateTimeFormatter dateHour() {
return Constants.dh;
}
/**
* Returns a formatter that combines a full date, two digit hour of day,
* and two digit minute of hour. (yyyy-MM-dd'T'HH:mm)
*
* @return a formatter for yyyy-MM-dd'T'HH:mm
*/
public static DateTimeFormatter dateHourMinute() {
return Constants.dhm;
}
/**
* Returns a formatter that combines a full date, two digit hour of day,
* two digit minute of hour, and two digit second of
* minute. (yyyy-MM-dd'T'HH:mm:ss)
*
* @return a formatter for yyyy-MM-dd'T'HH:mm:ss
*/
public static DateTimeFormatter dateHourMinuteSecond() {
return Constants.dhms;
}
/**
* Returns a formatter that combines a full date, two digit hour of day,
* two digit minute of hour, two digit second of minute, and three digit
* fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS). Parsing will parse up
* to 3 fractional second digits.
*
* @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSS
*/
public static DateTimeFormatter dateHourMinuteSecondMillis() {
return Constants.dhmsl;
}
/**
* Returns a formatter that combines a full date, two digit hour of day,
* two digit minute of hour, two digit second of minute, and three digit
* fraction of second (yyyy-MM-dd'T'HH:mm:ss.SSS). Parsing will parse up
* to 9 fractional second digits, throwing away all except the first three.
*
* @return a formatter for yyyy-MM-dd'T'HH:mm:ss.SSS
*/
public static DateTimeFormatter dateHourMinuteSecondFraction() {
return Constants.dhmsf;
}
//-----------------------------------------------------------------------
static final class Constants {
private static final DateTimeFormatter
ye = yearElement(), // year element (yyyy)
mye = monthElement(), // monthOfYear element (-MM)
dme = dayOfMonthElement(), // dayOfMonth element (-dd)
we = weekyearElement(), // weekyear element (xxxx)
wwe = weekElement(), // weekOfWeekyear element (-ww)
dwe = dayOfWeekElement(), // dayOfWeek element (-ee)
dye = dayOfYearElement(), // dayOfYear element (-DDD)
hde = hourElement(), // hourOfDay element (HH)
mhe = minuteElement(), // minuteOfHour element (:mm)
sme = secondElement(), // secondOfMinute element (:ss)
fse = fractionElement(), // fractionOfSecond element (.SSSSSSSSS)
ze = offsetElement(), // zone offset element
lte = literalTElement(), // literal 'T' element
//y, // year (same as year element)
ym = yearMonth(), // year month
ymd = yearMonthDay(), // year month day
//w, // weekyear (same as weekyear element)
ww = weekyearWeek(), // weekyear week
wwd = weekyearWeekDay(), // weekyear week day
//h, // hour (same as hour element)
hm = hourMinute(), // hour minute
hms = hourMinuteSecond(), // hour minute second
hmsl = hourMinuteSecondMillis(), // hour minute second millis
hmsf = hourMinuteSecondFraction(), // hour minute second fraction
dh = dateHour(), // date hour
dhm = dateHourMinute(), // date hour minute
dhms = dateHourMinuteSecond(), // date hour minute second
dhmsl = dateHourMinuteSecondMillis(), // date hour minute second millis
dhmsf = dateHourMinuteSecondFraction(), // date hour minute second fraction
//d, // date (same as ymd)
t = time(), // time
tx = timeNoMillis(), // time no millis
tt = tTime(), // Ttime
ttx = tTimeNoMillis(), // Ttime no millis
dt = dateTime(), // date time
dtx = dateTimeNoMillis(), // date time no millis
//wd, // week date (same as wwd)
wdt = weekDateTime(), // week date time
wdtx = weekDateTimeNoMillis(), // week date time no millis
od = ordinalDate(), // ordinal date (same as yd)
odt = ordinalDateTime(), // ordinal date time
odtx = ordinalDateTimeNoMillis(), // ordinal date time no millis
bd = basicDate(), // basic date
bt = basicTime(), // basic time
btx = basicTimeNoMillis(), // basic time no millis
btt = basicTTime(), // basic Ttime
bttx = basicTTimeNoMillis(), // basic Ttime no millis
bdt = basicDateTime(), // basic date time
bdtx = basicDateTimeNoMillis(), // basic date time no millis
bod = basicOrdinalDate(), // basic ordinal date
bodt = basicOrdinalDateTime(), // basic ordinal date time
bodtx = basicOrdinalDateTimeNoMillis(), // basic ordinal date time no millis
bwd = basicWeekDate(), // basic week date
bwdt = basicWeekDateTime(), // basic week date time
bwdtx = basicWeekDateTimeNoMillis(), // basic week date time no millis
dpe = dateElementParser(), // date parser element
tpe = timeElementParser(), // time parser element
dp = dateParser(), // date parser
ldp = localDateParser(), // local date parser
tp = timeParser(), // time parser
ltp = localTimeParser(), // local time parser
dtp = dateTimeParser(), // date time parser
dotp = dateOptionalTimeParser(), // date optional time parser
ldotp = localDateOptionalTimeParser(); // local date optional time parser
//-----------------------------------------------------------------------
private static DateTimeFormatter dateParser() {
if (dp == null) {
DateTimeParser tOffset = new DateTimeFormatterBuilder()
.appendLiteral('T')
.append(offsetElement()).toParser();
return new DateTimeFormatterBuilder()
.append(dateElementParser())
.appendOptional(tOffset)
.toFormatter();
}
return dp;
}
private static DateTimeFormatter localDateParser() {
if (ldp == null) {
return dateElementParser().withZoneUTC();
}
return ldp;
}
private static DateTimeFormatter dateElementParser() {
if (dpe == null) {
return new DateTimeFormatterBuilder()
.append(null, new DateTimeParser[] {
new DateTimeFormatterBuilder()
.append(yearElement())
.appendOptional
(new DateTimeFormatterBuilder()
.append(monthElement())
.appendOptional(dayOfMonthElement().getParser())
.toParser())
.toParser(),
new DateTimeFormatterBuilder()
.append(weekyearElement())
.append(weekElement())
.appendOptional(dayOfWeekElement().getParser())
.toParser(),
new DateTimeFormatterBuilder()
.append(yearElement())
.append(dayOfYearElement())
.toParser()
})
.toFormatter();
}
return dpe;
}
private static DateTimeFormatter timeParser() {
if (tp == null) {
return new DateTimeFormatterBuilder()
.appendOptional(literalTElement().getParser())
.append(timeElementParser())
.appendOptional(offsetElement().getParser())
.toFormatter();
}
return tp;
}
private static DateTimeFormatter localTimeParser() {
if (ltp == null) {
return new DateTimeFormatterBuilder()
.appendOptional(literalTElement().getParser())
.append(timeElementParser())
.toFormatter().withZoneUTC();
}
return ltp;
}
private static DateTimeFormatter timeElementParser() {
if (tpe == null) {
// Decimal point can be either '.' or ','
DateTimeParser decimalPoint = new DateTimeFormatterBuilder()
.append(null, new DateTimeParser[] {
new DateTimeFormatterBuilder()
.appendLiteral('.')
.toParser(),
new DateTimeFormatterBuilder()
.appendLiteral(',')
.toParser()
})
.toParser();
return new DateTimeFormatterBuilder()
// time-element
.append(hourElement())
.append
(null, new DateTimeParser[] {
new DateTimeFormatterBuilder()
// minute-element
.append(minuteElement())
.append
(null, new DateTimeParser[] {
new DateTimeFormatterBuilder()
// second-element
.append(secondElement())
// second fraction
.appendOptional(new DateTimeFormatterBuilder()
.append(decimalPoint)
.appendFractionOfSecond(1, 9)
.toParser())
.toParser(),
// minute fraction
new DateTimeFormatterBuilder()
.append(decimalPoint)
.appendFractionOfMinute(1, 9)
.toParser(),
null
})
.toParser(),
// hour fraction
new DateTimeFormatterBuilder()
.append(decimalPoint)
.appendFractionOfHour(1, 9)
.toParser(),
null
})
.toFormatter();
}
return tpe;
}
private static DateTimeFormatter dateTimeParser() {
if (dtp == null) {
// This is different from the general time parser in that the 'T'
// is required.
DateTimeParser time = new DateTimeFormatterBuilder()
.appendLiteral('T')
.append(timeElementParser())
.appendOptional(offsetElement().getParser())
.toParser();
return new DateTimeFormatterBuilder()
.append(null, new DateTimeParser[] {time, dateOptionalTimeParser().getParser()})
.toFormatter();
}
return dtp;
}
private static DateTimeFormatter dateOptionalTimeParser() {
if (dotp == null) {
DateTimeParser timeOrOffset = new DateTimeFormatterBuilder()
.appendLiteral('T')
.appendOptional(timeElementParser().getParser())
.appendOptional(offsetElement().getParser())
.toParser();
return new DateTimeFormatterBuilder()
.append(dateElementParser())
.appendOptional(timeOrOffset)
.toFormatter();
}
return dotp;
}
private static DateTimeFormatter localDateOptionalTimeParser() {
if (ldotp == null) {
DateTimeParser time = new DateTimeFormatterBuilder()
.appendLiteral('T')
.append(timeElementParser())
.toParser();
return new DateTimeFormatterBuilder()
.append(dateElementParser())
.appendOptional(time)
.toFormatter().withZoneUTC();
}
return ldotp;
}
//-----------------------------------------------------------------------
private static DateTimeFormatter time() {
if (t == null) {
return new DateTimeFormatterBuilder()
.append(hourMinuteSecondFraction())
.append(offsetElement())
.toFormatter();
}
return t;
}
private static DateTimeFormatter timeNoMillis() {
if (tx == null) {
return new DateTimeFormatterBuilder()
.append(hourMinuteSecond())
.append(offsetElement())
.toFormatter();
}
return tx;
}
private static DateTimeFormatter tTime() {
if (tt == null) {
return new DateTimeFormatterBuilder()
.append(literalTElement())
.append(time())
.toFormatter();
}
return tt;
}
private static DateTimeFormatter tTimeNoMillis() {
if (ttx == null) {
return new DateTimeFormatterBuilder()
.append(literalTElement())
.append(timeNoMillis())
.toFormatter();
}
return ttx;
}
private static DateTimeFormatter dateTime() {
if (dt == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(tTime())
.toFormatter();
}
return dt;
}
private static DateTimeFormatter dateTimeNoMillis() {
if (dtx == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(tTimeNoMillis())
.toFormatter();
}
return dtx;
}
private static DateTimeFormatter ordinalDate() {
if (od == null) {
return new DateTimeFormatterBuilder()
.append(yearElement())
.append(dayOfYearElement())
.toFormatter();
}
return od;
}
private static DateTimeFormatter ordinalDateTime() {
if (odt == null) {
return new DateTimeFormatterBuilder()
.append(ordinalDate())
.append(tTime())
.toFormatter();
}
return odt;
}
private static DateTimeFormatter ordinalDateTimeNoMillis() {
if (odtx == null) {
return new DateTimeFormatterBuilder()
.append(ordinalDate())
.append(tTimeNoMillis())
.toFormatter();
}
return odtx;
}
private static DateTimeFormatter weekDateTime() {
if (wdt == null) {
return new DateTimeFormatterBuilder()
.append(weekDate())
.append(tTime())
.toFormatter();
}
return wdt;
}
private static DateTimeFormatter weekDateTimeNoMillis() {
if (wdtx == null) {
return new DateTimeFormatterBuilder()
.append(weekDate())
.append(tTimeNoMillis())
.toFormatter();
}
return wdtx;
}
//-----------------------------------------------------------------------
private static DateTimeFormatter basicDate() {
if (bd == null) {
return new DateTimeFormatterBuilder()
.appendYear(4, 4)
.appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
.appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
.toFormatter();
}
return bd;
}
private static DateTimeFormatter basicTime() {
if (bt == null) {
return new DateTimeFormatterBuilder()
.appendFixedDecimal(DateTimeFieldType.hourOfDay(), 2)
.appendFixedDecimal(DateTimeFieldType.minuteOfHour(), 2)
.appendFixedDecimal(DateTimeFieldType.secondOfMinute(), 2)
.appendLiteral('.')
.appendFractionOfSecond(3, 9)
.appendTimeZoneOffset("Z", false, 2, 2)
.toFormatter();
}
return bt;
}
private static DateTimeFormatter basicTimeNoMillis() {
if (btx == null) {
return new DateTimeFormatterBuilder()
.appendFixedDecimal(DateTimeFieldType.hourOfDay(), 2)
.appendFixedDecimal(DateTimeFieldType.minuteOfHour(), 2)
.appendFixedDecimal(DateTimeFieldType.secondOfMinute(), 2)
.appendTimeZoneOffset("Z", false, 2, 2)
.toFormatter();
}
return btx;
}
private static DateTimeFormatter basicTTime() {
if (btt == null) {
return new DateTimeFormatterBuilder()
.append(literalTElement())
.append(basicTime())
.toFormatter();
}
return btt;
}
private static DateTimeFormatter basicTTimeNoMillis() {
if (bttx == null) {
return new DateTimeFormatterBuilder()
.append(literalTElement())
.append(basicTimeNoMillis())
.toFormatter();
}
return bttx;
}
private static DateTimeFormatter basicDateTime() {
if (bdt == null) {
return new DateTimeFormatterBuilder()
.append(basicDate())
.append(basicTTime())
.toFormatter();
}
return bdt;
}
private static DateTimeFormatter basicDateTimeNoMillis() {
if (bdtx == null) {
return new DateTimeFormatterBuilder()
.append(basicDate())
.append(basicTTimeNoMillis())
.toFormatter();
}
return bdtx;
}
private static DateTimeFormatter basicOrdinalDate() {
if (bod == null) {
return new DateTimeFormatterBuilder()
.appendYear(4, 4)
.appendFixedDecimal(DateTimeFieldType.dayOfYear(), 3)
.toFormatter();
}
return bod;
}
private static DateTimeFormatter basicOrdinalDateTime() {
if (bodt == null) {
return new DateTimeFormatterBuilder()
.append(basicOrdinalDate())
.append(basicTTime())
.toFormatter();
}
return bodt;
}
private static DateTimeFormatter basicOrdinalDateTimeNoMillis() {
if (bodtx == null) {
return new DateTimeFormatterBuilder()
.append(basicOrdinalDate())
.append(basicTTimeNoMillis())
.toFormatter();
}
return bodtx;
}
private static DateTimeFormatter basicWeekDate() {
if (bwd == null) {
return new DateTimeFormatterBuilder()
.appendFixedSignedDecimal(DateTimeFieldType.weekyear(), 4) // ES change, was .appendWeekyear(4, 4)
.appendLiteral('W')
.appendFixedDecimal(DateTimeFieldType.weekOfWeekyear(), 2)
.appendFixedDecimal(DateTimeFieldType.dayOfWeek(), 1)
.toFormatter();
}
return bwd;
}
private static DateTimeFormatter basicWeekDateTime() {
if (bwdt == null) {
return new DateTimeFormatterBuilder()
.append(basicWeekDate())
.append(basicTTime())
.toFormatter();
}
return bwdt;
}
private static DateTimeFormatter basicWeekDateTimeNoMillis() {
if (bwdtx == null) {
return new DateTimeFormatterBuilder()
.append(basicWeekDate())
.append(basicTTimeNoMillis())
.toFormatter();
}
return bwdtx;
}
//-----------------------------------------------------------------------
private static DateTimeFormatter yearMonth() {
if (ym == null) {
return new DateTimeFormatterBuilder()
.append(yearElement())
.append(monthElement())
.toFormatter();
}
return ym;
}
private static DateTimeFormatter yearMonthDay() {
if (ymd == null) {
return new DateTimeFormatterBuilder()
.append(yearElement())
.append(monthElement())
.append(dayOfMonthElement())
.toFormatter();
}
return ymd;
}
private static DateTimeFormatter weekyearWeek() {
if (ww == null) {
return new DateTimeFormatterBuilder()
.append(weekyearElement())
.append(weekElement())
.toFormatter();
}
return ww;
}
private static DateTimeFormatter weekyearWeekDay() {
if (wwd == null) {
return new DateTimeFormatterBuilder()
.append(weekyearElement())
.append(weekElement())
.append(dayOfWeekElement())
.toFormatter();
}
return wwd;
}
private static DateTimeFormatter hourMinute() {
if (hm == null) {
return new DateTimeFormatterBuilder()
.append(hourElement())
.append(minuteElement())
.toFormatter();
}
return hm;
}
private static DateTimeFormatter hourMinuteSecond() {
if (hms == null) {
return new DateTimeFormatterBuilder()
.append(hourElement())
.append(minuteElement())
.append(secondElement())
.toFormatter();
}
return hms;
}
private static DateTimeFormatter hourMinuteSecondMillis() {
if (hmsl == null) {
return new DateTimeFormatterBuilder()
.append(hourElement())
.append(minuteElement())
.append(secondElement())
.appendLiteral('.')
.appendFractionOfSecond(3, 3)
.toFormatter();
}
return hmsl;
}
private static DateTimeFormatter hourMinuteSecondFraction() {
if (hmsf == null) {
return new DateTimeFormatterBuilder()
.append(hourElement())
.append(minuteElement())
.append(secondElement())
.append(fractionElement())
.toFormatter();
}
return hmsf;
}
private static DateTimeFormatter dateHour() {
if (dh == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(literalTElement())
.append(hour())
.toFormatter();
}
return dh;
}
private static DateTimeFormatter dateHourMinute() {
if (dhm == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(literalTElement())
.append(hourMinute())
.toFormatter();
}
return dhm;
}
private static DateTimeFormatter dateHourMinuteSecond() {
if (dhms == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(literalTElement())
.append(hourMinuteSecond())
.toFormatter();
}
return dhms;
}
private static DateTimeFormatter dateHourMinuteSecondMillis() {
if (dhmsl == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(literalTElement())
.append(hourMinuteSecondMillis())
.toFormatter();
}
return dhmsl;
}
private static DateTimeFormatter dateHourMinuteSecondFraction() {
if (dhmsf == null) {
return new DateTimeFormatterBuilder()
.append(date())
.append(literalTElement())
.append(hourMinuteSecondFraction())
.toFormatter();
}
return dhmsf;
}
//-----------------------------------------------------------------------
private static DateTimeFormatter yearElement() {
if (ye == null) {
return new DateTimeFormatterBuilder()
.appendFixedSignedDecimal(DateTimeFieldType.year(), 4) // ES change, was .appendYear(4, 9)
.toFormatter();
}
return ye;
}
private static DateTimeFormatter monthElement() {
if (mye == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('-')
.appendFixedSignedDecimal(DateTimeFieldType.monthOfYear(), 2) // ES change, was .appendMonthOfYear(2)
.toFormatter();
}
return mye;
}
private static DateTimeFormatter dayOfMonthElement() {
if (dme == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('-')
.appendFixedSignedDecimal(DateTimeFieldType.dayOfMonth(), 2) // ES change, was .appendDayOfMonth(2)
.toFormatter();
}
return dme;
}
private static DateTimeFormatter weekyearElement() {
if (we == null) {
return new DateTimeFormatterBuilder()
.appendFixedSignedDecimal(DateTimeFieldType.weekyear(), 4) // ES change, was .appendWeekyear(4, 9)
.toFormatter();
}
return we;
}
private static DateTimeFormatter weekElement() {
if (wwe == null) {
return new DateTimeFormatterBuilder()
.appendLiteral("-W")
.appendFixedSignedDecimal(DateTimeFieldType.weekOfWeekyear(), 2) // ES change, was .appendWeekOfWeekyear(2)
.toFormatter();
}
return wwe;
}
private static DateTimeFormatter dayOfWeekElement() {
if (dwe == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('-')
.appendDayOfWeek(1)
.toFormatter();
}
return dwe;
}
private static DateTimeFormatter dayOfYearElement() {
if (dye == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('-')
.appendFixedSignedDecimal(DateTimeFieldType.dayOfYear(), 3) // ES change, was .appendDayOfYear(3)
.toFormatter();
}
return dye;
}
private static DateTimeFormatter literalTElement() {
if (lte == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('T')
.toFormatter();
}
return lte;
}
private static DateTimeFormatter hourElement() {
if (hde == null) {
return new DateTimeFormatterBuilder()
.appendFixedSignedDecimal(DateTimeFieldType.hourOfDay(), 2) // ES change, was .appendHourOfDay(2)
.toFormatter();
}
return hde;
}
private static DateTimeFormatter minuteElement() {
if (mhe == null) {
return new DateTimeFormatterBuilder()
.appendLiteral(':')
.appendFixedSignedDecimal(DateTimeFieldType.minuteOfHour(), 2) // ES change, was .appendMinuteOfHour(2)
.toFormatter();
}
return mhe;
}
private static DateTimeFormatter secondElement() {
if (sme == null) {
return new DateTimeFormatterBuilder()
.appendLiteral(':')
.appendFixedSignedDecimal(DateTimeFieldType.secondOfMinute(), 2) // ES change, was .appendSecondOfMinute(2)
.toFormatter();
}
return sme;
}
private static DateTimeFormatter fractionElement() {
if (fse == null) {
return new DateTimeFormatterBuilder()
.appendLiteral('.')
// Support parsing up to nanosecond precision even though
// those extra digits will be dropped.
.appendFractionOfSecond(3, 9)
.toFormatter();
}
return fse;
}
private static DateTimeFormatter offsetElement() {
if (ze == null) {
return new DateTimeFormatterBuilder()
.appendTimeZoneOffset("Z", true, 2, 4)
.toFormatter();
}
return ze;
}
}
}