Class DateTimeFormats
Instant and ZonedDateTime parsing for all common date
time strings, without needing a DateTimeFormatter:
Instant timestamp = DateTimeFormats.parseToInstant(timestampString);
ZonedDateTime dateTime = DateTimeFormats.parseZonedDateTime(dateTimeString);
For more flexible use cases, where you might want to reuse or conform to a format known at
compile-time, the DateTimeFormatter can be inferred from an example date/time/datetime
string (similar to the golang time library style).
For example:
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormats.formatOf("2023-12-09 10:00:00.12345 America/Los_Angeles");
private static final DateTimeFormatter USING_ZONE_OFFSET =
DateTimeFormats.formatOf("2023-12-09 10:00:00+08:00");
private static final DateTimeFormatter ISO_FORMATTER =
DateTimeFormats.formatOf("2023-12-09T10:00:00.12345[Europe/Paris]");
private static final DateTimeFormatter WITH_DAY_OF_WEEK =
DateTimeFormats.formatOf("2023/12/09 Sat 10:00+08:00");
Most ISO 8601 formats are supported, except BASIC_ISO_DATE, ISO_WEEK_DATE ('2012-W48-6') and ISO_ORDINAL_DATE ('2012-337'), which are rarely used.
For the date part of custom patterns, ambiguous examples like 10/12/2024 or
1/2/yyyy are not supported. You should use unambiguous examples like 10/30/2024 (which
results in "MM/dd/yyyy"} or 30/1/2024 (which results in "dd/M/yyyy}. In addition,
localized month names such as Jan or March are used, all natural orders (
year month day, month day year or day month year) are supported.
For the time part of custom patterns, only HH:mm, HH:mm:ss and
HH:mm:ss.S variants are supported (the S can be 1 to 9 digits). An AM/PM marker can follow, as
in 1:00 PM or 10:00 PM, in which case a 12-hour clock (h or hh)
is inferred and 24-hour values such as 15:00 PM are rejected.
If the variant of the date time pattern you need exceeds the out-of-box support, you can
explicitly mix the DateTimeFormatter specifiers with example placeholders (between a pair
of pointy brackets) to be translated.
For example the following code uses the dd, MM and yyyy specifiers as
is but translates the Tue and America/New_York example snippets into E
and VV specifiers respectively. It will then parse and format to datetime strings like
"Fri, 20 Oct 2023 10:30:59.123 Europe/Paris".
private static final DateTimeFormatter FORMATTER =
formatOf("<Tue>, dd MM yyyy HH:mm:ss.SSS <America/New_York>");
Warning: zone abbreviations are lossy across timezones. An abbreviation such
as AST, CST or PST is shared by a group of zones. formatOf(java.lang.String) can
only translate it to the "zzz" format specifier, preferring ZoneId.systemDefault() when it belongs to that group (which also claims the group's daylight or
standard counterpart name, even if the host zone never observes it), and otherwise resolving
through CLDR to the group's canonical zone, which may not be the zone that produced the
string! Such strings usually come from Date.toString(),
which prints an abbreviation whenever CLDR has one for the host's zone. For example, when parsed
on a host outside those zones (such as in UTC or America/Los_Angeles):
// Written by a host in Barbados, which stays on AST (-04:00) year round.
// The string denotes 2011-07-15T12:00:00Z.
parseToInstant("Fri Jul 15 08:00:00 AST 2011");
// => 2011-07-15T11:00:00Z. "AST" resolves to America/Halifax, which is on ADT (-03:00) in July.
// Written by a host in Shanghai, which also prints CST.
// The string denotes 2026-09-17T00:00:00Z.
parseToInstant("Thu Sep 17 08:00:00 CST 2026");
// => 2026-09-17T13:00:00Z. "CST" resolves to America/Chicago: 13 hours off.
The canonical zone of the most common abbreviations:
PST,PDT:America/Los_AngelesMST,MDT:America/DenverCST,CDT:America/ChicagoEST,EDT:America/New_YorkAST,ADT:America/Halifax
The drift is an hour where the group differs only in daylight saving (AEST spans
Sydney and Brisbane; CET spans Paris and Algiers), and can exceed half a day where the
same letters are used on different continents (CST spans Chicago, Havana and Shanghai;
PST spans Los Angeles and Manila; AST spans Halifax, Barbados and Riyadh).
Nothing in the string identifies the writer's zone, so this is not recoverable when the reader's
ZoneId.systemDefault() differs from the writer's.
Prefer a zone id (2011-07-15 08:00:00 America/Barbados) or a numeric offset (
2011-07-15 08:00:00 -04:00); both round-trip exactly. Use an abbreviation only when the producer
is known to run in the same ZoneId.systemDefault(), in the canonical zone, or in a zone
that follows the same rules (America/Toronto round-trips through
America/New_York). GMT, UTC, UT and GMT±hh:mm are unambiguous
and always exact.
i18n isn't supported.
- Since:
- 7.1
-
Method Summary
Modifier and TypeMethodDescriptionstatic DateTimeFormatterInfers and returns theDateTimeFormatterbased onexample.static LocalDateparseLocalDate(String dateString) ParsesdateStringasLocalDate.static OffsetDateTimeparseOffsetDateTime(String dateTimeString) ParsesdateTimeStringtoOffsetDateTimeusing heuristics in this class to infer theDateTimeFormatterfor common formats.static InstantparseToInstant(String dateTimeString) ParsesdateTimeStringtoInstant.static ZonedDateTimeparseZonedDateTime(String dateTimeString) ParsesdateTimeStringtoZonedDateTimeusing heuristics in this class to infer theDateTimeFormatterfor common formats.
-
Method Details
-
formatOf
Infers and returns theDateTimeFormatterbased onexample.- Throws:
DateTimeException- ifexampleis invalid or the pattern isn't supported.
-
parseLocalDate
ParsesdateStringasLocalDate.Acceptable formats include dates like "2024/04/11", "2024-04-11", "2024 April 11", "Apr 11 2024", "11 April 2024", "20240401", or even with "10/30/2024", "30/01/2024" etc. as long as it's not ambiguous.
Prefer to pre-construct a
DateTimeFormatterusingformatOf(java.lang.String)to get better performance and earlier error report in case the format cannot be inferred.- Throws:
DateTimeException- ifdateTimeStringcannot be parsed toLocalDate- Since:
- 8.0
-
parseToInstant
ParsesdateTimeStringtoInstant.dateTimeStringcould be in the format ofDateTimeFormatter.ISO_INSTANT, which is fromInstant.toString(); or it could be any valid date time with zone name or zone offset.Prefer to pre-construct a
DateTimeFormatterusingformatOf(java.lang.String)to get better performance and earlier error report in case the format cannot be inferred.If
dateTimeStringcarries a zone abbreviation such asPSTorCST, see the class-level warning: whenZoneId.systemDefault()is not in that abbreviation's group, it resolves to CLDR's canonical zone, which may not be the zone that produced the string.- Parameters:
dateTimeString- can be the result ofInstant.toString(), or any other valid date time with either zone name or UTC offset.- Throws:
DateTimeException- ifdateTimeStringcannot be parsed asInstant- Since:
- 8.0
-
parseZonedDateTime
ParsesdateTimeStringtoZonedDateTimeusing heuristics in this class to infer theDateTimeFormatterfor common formats.Prefer to pre-construct a
DateTimeFormatterusingformatOf(java.lang.String)to get better performance and earlier error report in case the format cannot be inferred.If
dateTimeStringcarries a zone abbreviation such asPSTorCST, see the class-level warning: whenZoneId.systemDefault()is not in that abbreviation's group, it resolves to CLDR's canonical zone, which may not be the zone that produced the string.- Parameters:
dateTimeString- must be a string with valid date, time, and zone name or UTC offset- Throws:
DateTimeException- ifdateTimeStringcannot be parsed asZonedDateTime- Since:
- 8.0
-
parseOffsetDateTime
ParsesdateTimeStringtoOffsetDateTimeusing heuristics in this class to infer theDateTimeFormatterfor common formats.Prefer to pre-construct a
DateTimeFormatterusingformatOf(java.lang.String)to get better performance and earlier error report in case the format cannot be inferred.- Parameters:
dateTimeString- must be a string with valid date, time, and UTC offset (cannot be zone name)- Throws:
DateTimeException- ifdateTimeStringcannot be parsed asOffsetDateTime- Since:
- 8.0
-