How to create Java time instant from pattern?

Cherry picture Cherry · Jun 7, 2016 · Viewed 91.4k times · Source

Consider a code:

TemporalAccessor date = DateTimeFormatter.ofPattern("yyyy-MM-dd").parse("9999-12-31");
Instant.from(date);

The last line throws an exception:

Unable to obtain Instant from TemporalAccessor: {},ISO resolved to 9999-12-31 of type java.time.format.Parsed

How to create Instant from yyyy-MM-dd pattern?

Answer

JodaStephen picture JodaStephen · Jun 7, 2016

The string "9999-12-31" only contains information about a date. It does not contain any information about the time-of-day or offset. As such, there is insufficient information to create an Instant. (Other date and time libraries are more lenient, but java.time avoids defaulting these values)

Your first choice is to use a LocalDate instead of an `Instant:

LocalDate date = LocalDate.parse("9999-12-31");

Your second choice is to post process the date to convert it to an instant, which requires a time-zone, here chosen to be Paris:

LocalDate date = LocalDate.parse("9999-12-31");
Instant instant = date.atStartOfDay(ZoneId.of("Europe/Paris")).toInstant();

Your third choice is to add the time-zone to the formatter, and default the time-of-day:

static final DateTimeFormatter FMT = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd")
    .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
    .toFormatter()
    .withZone(ZoneId.of("Europe/Paris"));
Instant instant = FMT.parse("9999-31-12", Instant::from);

(If this doesn't work, ensure you have the latest JDK 8 release as a bug was fixed in this area).

It is worth noting that none of these possibilities use TemporalAccessor directly, because that type is a low-level framework interface, not one for most application developers to use.