Class DateTimeFormatterXSD
- java.lang.Object
-
- com.addicticks.texttime.formatters.DateTimeFormatterXSD
-
public class DateTimeFormatterXSD extends Object
Formatter-Parsers for XML Schema typesxs:date,xs:dateTimeandxs:time.Predefined Formatter-Parsers for these value types are not included in the JDK.
It it not uncommon that XML documents (or JSON documents) use a format for date and time values which is aligned with ISO-8601, but do not (strictly) conform to the XML Schema Specification. The former allows much more freedom than the latter. Freedom in the case of data interchange between two parties is a really bad idea. This is why the XML Schema Specification in this respect is superior to the ISO-8601 specification.
While it is sad that the XML Schema Specification is sometimes not strictly followed in XML and JSON documents it is nevertheless a reality. For this reason, this class has predefined parsers which are lenient and therefore strictly speaking do not conform to the XML Schema Specification. However, only unambiguous deviations are accepted while parsing.
The closest JDK equivalent to
xs:dateTime,xs:dateandxs:timeareOffsetDateTimeandOffsetTime. However, the XML Schema data types do not mandate the presence of the timezone offset and therefore they have no direct equivalent in the JDK.Predefined Formatters-Parsers overview
Formatter Usage Description Examples XSD_DATETIME_PARSERParsing For xs:dateTimelenient parsing'2018-12-03T10:15:30+01:00''2018-12-03 10:15:30+01:00''2018-12-03T10:15:30+01''2018-12-03t10:15:30+01''2018-12-03T10:15:30Z''2018-12-03T10:15:30z'XSD_DATETIMEParsing
FormattingFor xs:dateTimeformatting or strict parsing'2018-12-03T10:15:30+01:00'
'2018-12-03T10:15:30Z'XSD_DATE_PARSERParsing For xs:datelenient parsing'2018-12-03+01:00''2018-12-03+01''2018-12-03Z''2018-12-03z'XSD_DATEParsing
FormattingFor xs:dateformatting or strict parsing'2018-12-03+01:00''2018-12-03Z'XSD_TIME_PARSERParsing For xs:timelenient parsing'10:15:30+01:00''10:15:30+01''10:15:30Z''10:15:30z'XSD_TIMEParsing
FormattingFor xs:timeformatting or strict parsing'10:15:30+01:00''10:15:30Z'Parsing
This class also provides convenience methods for parsing XML Schema date/time string values into their best match JDK class.- See Also:
- XML Schema Specification.
-
-
Field Summary
Fields Modifier and Type Field Description static DateTimeFormatterXSD_DATEFor parsing and formatting ofxs:datevalues as defined in XML Schema.static DateTimeFormatterXSD_DATE_PARSERFor lenient parsing values of typexs:date.static DateTimeFormatterXSD_DATETIMEFor parsing and formatting ofxs:dateTimevalues as defined in XML Schema..static DateTimeFormatterXSD_DATETIME_PARSERFor lenient parsing values of typexs:dateTime.static DateTimeFormatterXSD_TIMEFor parsing and formatting ofxs:timevalues as defined in XML Schema.static DateTimeFormatterXSD_TIME_PARSERFor lenient parsing values of typexs:time.
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static OffsetDateparseIntoOffsetDate(String str, ZoneOffset defaultZoneOffset)Parses axs:datestring into anOffsetDate.static OffsetDateparseIntoOffsetDate(String str, Function<LocalDate,ZoneOffset> zoneOffsetProvider)Parses axs:datestring into anOffsetDate.static OffsetDateTimeparseIntoOffsetDateTime(String str, ZoneOffset defaultZoneOffset)Parses axs:dateTimestring into anOffsetDateTime.static OffsetDateTimeparseIntoOffsetDateTime(String str, Function<LocalDateTime,ZoneOffset> zoneOffsetProvider)Parses axs:dateTimestring into anOffsetDateTime.static OffsetDateTimeparseIntoOffsetDateTimeNoTime(String str, ZoneOffset defaultZoneOffset)Parses axs:datestring into anOffsetDateTime.static OffsetDateTimeparseIntoOffsetDateTimeNoTime(String str, Function<LocalDate,ZoneOffset> zoneOffsetProvider)Parses axs:datestring into anOffsetDateTime.static OffsetTimeparseIntoOffsetTime(String str, ZoneOffset defaultZoneOffset)Parses axs:timestring into anOffsetTime.static OffsetTimeparseIntoOffsetTime(String str, Function<LocalTime,ZoneOffset> zoneOffsetProvider)Parses axs:timestring into anOffsetTime.
-
-
-
Field Detail
-
XSD_DATETIME_PARSER
public static final DateTimeFormatter XSD_DATETIME_PARSER
For lenient parsing values of typexs:dateTime.This Formatter-Parser is suitable only for parsing, not for formatting. When used for formatting it may produce values which are not compliant with the specification for
xs:dateTime. InsteadXSD_DATETIMEshould be used for formatting.Lenient parsing is performed, meaning that certain non-compliant formats are accepted. These formats should not be encouraged but are accepted by this parser as a pragmatic compromise. Compared to the formal definition of
xs:dateTimethe following is accepted while parsing:- In the time value the seconds field may be omitted. Hence
"2019-03-12T14:45Z"is an acceptable value. The formal specification mandates that the seconds field is present, even if zero. - The delimiter between the date and the time value may be a
'T'or a' '(space). The formal definition only allows a'T'. - Literals in the string, i.e.
'T'and'Z', are accepted regardless of upper/lower-case. The formal specification mandates that these are in upper-case. - If a time zone offset is specified it doesn't have to include minutes,
meaning that
"+05"is an acceptable value for an offset. The formal definition mandates that the minutes must be specified, i.e."+05:00". - Trailing zeroes in the fractional second is acceptable,
meaning that a value such as
"2019-03-12T14:45:28.340Z"will be accepted. The formal specification says "the fractional second string, if present, must not end in'0'".
Parsing
There are two methods for parsing a string into anOffsetDateTimedepending on your scenario:- Use the static
parse()method on this class. This method gracefully handles the situation where there are more then 9 digits on the seconds fractional value. - Creating a new
DateTimeFormatterbased on this one, but with a default ZoneId which is used during parsing if none is provided in the input.// This only need to be created once and can be re-used // (DateTimeFormatters are immutable and thread-safe) DateTimeFormatter dtf = DateTimeFormatterXSD.XSD_DATETIME_PARSER.withZone(ZoneId.of("America/New_York")); // Parse the string value. Since no offset is given in the input, the New York TZ is assumed. OffsetDateTime value = dtf.parse("2018-03-19:22:35:58", OffsetDateTime::from);
Compliance
- Formatting: Should not be used for formatting.
- Parsing: Compliant with the formal definition for
xs:dateTme, except for:- A number of formally incorrect forms are accepted as explained above.
- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
DateTimeParseExceptionif the input has more than 9 fractional digits. If this is a problem thenparseIntoOffsetDateTime()can be used.
- In the time value the seconds field may be omitted. Hence
-
XSD_DATETIME
public static final DateTimeFormatter XSD_DATETIME
For parsing and formatting ofxs:dateTimevalues as defined in XML Schema..This Formatter-Parser is suitable for both parsing and formatting. When used as a formatter it produces output compliant with the specification for
xs:dateTime. When used as a parser it mandates strict compliance with the specification forxs:dateTime. In most scenarios,XSD_DATETIME_PARSERis probably a better fit for parsing as it is more forgiving.Compliance
- Formatting: Produces output fully compliant with
formal definition for
xs:dateTimeassuming that aOffsetDateTimeorLocalDateTimeis used as input. - Parsing: Compliant with the formal definition for
xs:dateTime, except for:- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
DateTimeParseExceptionif the input has more than 9 fractional digits. - Trailing zeroes in the fractional second is acceptable,
meaning that a value such as
"2019-03-12T14:45:28.340Z"will be accepted. The formal specification says "the fractional second string, if present, must not end in'0'".
- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
- Formatting: Produces output fully compliant with
formal definition for
-
XSD_DATE_PARSER
public static final DateTimeFormatter XSD_DATE_PARSER
For lenient parsing values of typexs:date.This Formatter-Parser is suitable only for parsing, not for formatting. Instead
XSD_DATEshould be used for formatting.Lenient parsing is performed, meaning that certain non-compliant formats are accepted. These formats should not be encouraged but are accepted by this parser as a pragmatic compromise. Compared to the formal definition of
xs:datethe following is accepted while parsing:- The literal
'Z'in a timezone offset is accepted both in upper- and lower-case. - If a time zone offset is specified it doesn't have to include minutes,
meaning that
'+05'is an acceptable value. The formal definition mandates that the minutes must be specified, i.e.'+05:00'.
Parsing
There are two methods for parsing a date string into anOffsetDate/OffsetDateTimedepending on your scenario:- Use either of the static methods: on this class.
- Creating a new
DateTimeFormatterbased on this one, but with a default ZoneId which is used during parsing if none is provided in the input.// This only need to be created once and can be re-used // (DateTimeFormatters are immutable and thread-safe) DateTimeFormatter dtf = DateTimeFormatterXSD.XSD_DATE_PARSER.withZone(ZoneId.of("America/New_York")); // Parse the string value. Since no offset is given in the input, the New York TZ is assumed. OffsetDate value = dtf.parse("2018-03-19", OffsetDate::from);
Compliance
- Formatting: Should not be used for formatting.
- Parsing: Compliant with the formal definition for
xs:date, except for the forms accepted during parsing as listed above.
- See Also:
- https://www.w3.org/TR/xmlschema-2/#date
- The literal
-
XSD_DATE
public static final DateTimeFormatter XSD_DATE
For parsing and formatting ofxs:datevalues as defined in XML Schema.This Formatter-Parser is suitable for both parsing and formatting. When used as a formatter it produces output compliant with the specification for
xs:date. When used as a parser it mandates strict compliance with the specification forxs:date. In most scenarios,XSD_DATE_PARSERis probably a better fit for parsing as it is more forgiving.Compliance
- Formatting: Produces output fully compliant with the formal definition for
xs:dateassuming that aOffsetDateTimeorLocalDateis used as input. - Parsing: Compliant with the formal definition for
xs:date.
- See Also:
- https://www.w3.org/TR/xmlschema-2/#date
- Formatting: Produces output fully compliant with the formal definition for
-
XSD_TIME_PARSER
public static final DateTimeFormatter XSD_TIME_PARSER
For lenient parsing values of typexs:time.This Formatter-Parser is suitable only for parsing, not for formatting. Instead
XSD_TIMEshould be used for formatting.Lenient parsing is performed, meaning that certain non-compliant formats are accepted. These formats should not be encouraged but are accepted by this parser as a pragmatic compromise. Compared to the formal definition of
xs:timethe following is accepted while parsing:- In the time value the seconds field may be omitted. Hence
"14:45Z"is an acceptable value. The formal specification mandates that the seconds field is present, even if zero. - The literal
'Z'in a timezone offset is accepted both in upper- and lower-case. - If a time zone offset is specified it doesn't have to include minutes,
meaning that
'+05'is an acceptable value. The formal definition mandates that the minutes must be specified, i.e.'+05:00'. - Trailing zeroes in the fractional second is acceptable,
meaning that a value such as
"2019-03-12T14:45:28.340Z"will be accepted. The formal specification says "the fractional second string, if present, must not end in'0'".
Parsing
There are two methods for parsing a string into anOffsetTimedepending on your scenario:- Use the static
parse()on this class. This method gracefully handles the situation where there are more then 9 digits on the seconds fractional value. - Creating a new
DateTimeFormatterbased on this one, but with a default ZoneId which is used during parsing if none is provided in the input.// This only need to be created once and can be re-used // (DateTimeFormatters are immutable and thread-safe) DateTimeFormatter dtf = DateTimeFormatterXSD.XSD_TIME_PARSER.withZone(ZoneId.of("America/New_York")); // Parse the string value. Since no offset is given in the input, the New York TZ is assumed. OffsetTime value = dtf.parse("22:33:58", OffsetTime::from);
Compliance
- Formatting: Should not be used for formatting.
- Parsing: Compliant with the formal definition for
xs:time, except for:- A number of formally incorrect forms are accepted as explained above.
- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
DateTimeParseExceptionif the input has more than 9 fractional digits. If this is a problem thenparseIntoOffsetTime()can be used.
- See Also:
- https://www.w3.org/TR/xmlschema-2/#time
- In the time value the seconds field may be omitted. Hence
-
XSD_TIME
public static final DateTimeFormatter XSD_TIME
For parsing and formatting ofxs:timevalues as defined in XML Schema.This Formatter-Parser is suitable for both parsing and formatting. When used as a formatter it produces output compliant with the specification for
xs:time. When used as a parser it mandates strict compliance with the specification forxsdtime. In most scenarios,XSD_TIME_PARSERis probably a better fit for parsing as it is more forgiving.Compliance
- Formatting: Produces output fully compliant with formal definition
for
xs:timeassuming that aOffsetTimeorLocalTimeis used as input. - Parsing: Compliant with the formal definition for
xs:time, except for:- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
DateTimeParseExceptionif the input has more than 9 fractional digits. - Trailing zeroes in the fractional second is acceptable,
meaning that a value such as
"2019-03-12T14:45:28.340Z"will be accepted. The formal specification says "the fractional second string, if present, must not end in'0'".
- The seconds fraction field may contain no more than 9 digits.
In the formal definition, the seconds fractional field has "arbitrary level of precision".
This implementation will throw
- See Also:
- https://www.w3.org/TR/xmlschema-2/#time
- Formatting: Produces output fully compliant with formal definition
for
-
-
Method Detail
-
parseIntoOffsetDateTime
public static OffsetDateTime parseIntoOffsetDateTime(String str, Function<LocalDateTime,ZoneOffset> zoneOffsetProvider)
Parses axs:dateTimestring into anOffsetDateTime. For example a string on the form"2018-12-03T10:15:30+01:00"(value with offset) or"2018-12-03T10:15:30"(value without offset).The string is parsed using
XSD_DATETIME_PARSERwhich is forgiving and accepts minor deviations from the official specification.Furthermore, parsing is attempted in a
two-step procedure: If first parsing attempt fails the method will evaluate if the problem is something which can likely befixedand if so it will "fix" the input value,str, and perform a new parsing attempt.- Parameters:
str- the string to parsezoneOffsetProvider- a function which will be called if no zone offset is present in thetemporal.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetDateTime
public static OffsetDateTime parseIntoOffsetDateTime(String str, ZoneOffset defaultZoneOffset)
Parses axs:dateTimestring into anOffsetDateTime.This is convenience method for the more generalized
parseIntoOffsetDateTime(java.lang.String, java.util.function.Function)method.- Parameters:
str- the string to parsedefaultZoneOffset- the zone offset to use if none is present in the input string.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetDate
public static OffsetDate parseIntoOffsetDate(String str, Function<LocalDate,ZoneOffset> zoneOffsetProvider)
Parses axs:datestring into anOffsetDate. For example a string on the form"2018-12-03+01:00"(value with offset) or"2018-12-03"(value without offset).The string is parsed using
XSD_DATE_PARSERwhich is forgiving and accepts minor deviations from the official specification.- Parameters:
str- the string to parsezoneOffsetProvider- a function which will be called if no zone offset is present in the input string.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetDate
public static OffsetDate parseIntoOffsetDate(String str, ZoneOffset defaultZoneOffset)
Parses axs:datestring into anOffsetDate.This is a convenience method for the more generalized
parseIntoOffsetDate(java.lang.String, java.util.function.Function)method.- Parameters:
str- the string to parsedefaultZoneOffset- the zone offset to use if none is present in the input string.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetDateTimeNoTime
public static OffsetDateTime parseIntoOffsetDateTimeNoTime(String str, Function<LocalDate,ZoneOffset> zoneOffsetProvider)
Parses axs:datestring into anOffsetDateTime. For example a string on the form"2018-12-03+01:00"(value with offset) or"2018-12-03"(value without offset).The string is parsed using
XSD_DATE_PARSERwhich is forgiving and accepts minor deviations from the official specification.- Parameters:
str- the string to parsezoneOffsetProvider- a function which will be called if no zone offset is present in the input string.- Returns:
- parsed value (with "no" time value, meaning time value is set to midnight)
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetDateTimeNoTime
public static OffsetDateTime parseIntoOffsetDateTimeNoTime(String str, ZoneOffset defaultZoneOffset)
Parses axs:datestring into anOffsetDateTime.This is a convenience method for the more generalized
parseIntoOffsetDateTimeNoTime(java.lang.String, java.util.function.Function)method.- Parameters:
str- the string to parsedefaultZoneOffset- the zone offset to use if none is present in the input string.- Returns:
- parsed value (with "no" time value, meaning time value is set to midnight)
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetTime
public static OffsetTime parseIntoOffsetTime(String str, Function<LocalTime,ZoneOffset> zoneOffsetProvider)
Parses axs:timestring into anOffsetTime. For example a string on the form"10:15:30+01:00"(value with offset) or"10:15:30"(value without offset).The string is parsed using
XSD_TIME_PARSERwhich is forgiving and accepts minor deviations from the official specification.Furthermore, parsing is attempted in a
two-step procedure: If first parsing attempt fails the method will evaluate if the problem is something which can likely befixedand if so it will "fix" the input value,str, and perform a new parsing attempt.- Parameters:
str- the string to parsezoneOffsetProvider- a function which will be called if no zone offset is present in the input string.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
parseIntoOffsetTime
public static OffsetTime parseIntoOffsetTime(String str, ZoneOffset defaultZoneOffset)
Parses axs:timestring into anOffsetTime.This is a convenience method for the more generalized
parseIntoOffsetTime(java.lang.String, java.util.function.Function)method.- Parameters:
str- the string to parsedefaultZoneOffset- the zone offset to use if none is present in the input string.- Returns:
- parsed value
- Throws:
DateTimeParseException- if unable to parse the string
-
-