Unable to obtain ZonedDateTime from TemporalAccessor using DateTimeFormatter and ZonedDateTime in Java 8

JavaTimezoneJava 8Datetime FormatJava Time

Java Problem Overview


I recently moved to Java 8 to, hopefully, deal with local and zoned times more easily.

However, I'm facing an, in my opinion, simple problem when parsing a simple date.

public static ZonedDateTime convertirAFecha(String fecha) throws Exception {
	DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
			ConstantesFechas.FORMATO_DIA).withZone(
			obtenerZonaHorariaServidor());

	ZonedDateTime resultado = ZonedDateTime.parse(fecha, formatter);
	return resultado;
}

In my case:

  • fecha is '15/06/2014'
  • ConstantesFechas.FORMATO_DIA is 'dd/MM/yyyy'
  • obtenerZonaHorariaServidor returns ZoneId.systemDefault()

So, this is a simple example. However, the parse throws this exception:

> java.time.format.DateTimeParseException: Text '15/06/2014' could not > be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: > {},ISO resolved to 2014-06-15 of type java.time.format.Parsed

Any tips? I've been trying different combinations of parsing and using TemporalAccesor, but without any luck so far.

Java Solutions


Solution 1 - Java

This does not work because your input (and your Formatter) do not have time zone information. A simple way is to parse your date as a LocalDate first (without time or time zone information) then create a ZonedDateTime:

public static ZonedDateTime convertirAFecha(String fecha) {
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
  LocalDate date = LocalDate.parse(fecha, formatter);

  ZonedDateTime resultado = date.atStartOfDay(ZoneId.systemDefault());
  return resultado;
}

Solution 2 - Java

This is a bug, see JDK-bug-log. According to that information the problem was solved for Java 9 and Java 8u20. Try to download the latest Java 8 - version. Today on 2014-05-12: There is an early access release 8u20 available.

UPDATE:

Personally I think, since you only have and expect "dd/MM/yyyy" as pattern you should use LocalDate as your primary type as @assylias has already proposed. Regarding your context, it is almost sure a design failure to use ZonedDateTime. What do you want to do with objects of this type? I can only think of specialized timezone calculations as use-case. And you cannot even directly store these ZonedDateTime-objects in a database, so this type is far less useful than many people believe.

What I described as your use-case problem is indeed a new aspect introduced with Java-8 compared with the old GregorianCalendar-class (which is an all-in-one-type). Users have to start thinking about choosing the proper temporal type for their problems and use-cases.

Solution 3 - Java

In simple words, the line

ZonedDateTime.parse('2014-04-23', DateTimeFormatter.ISO_OFFSET_DATE_TIME)

throws an exception:

Text '2014-04-23' could not be parsed at index 10
java.time.format.DateTimeParseException: Text '2014-04-23' could not be parsed at index 10

It looks like a bug for me.

I used this workaround:

String dateAsStr = '2014-04-23';
if (dateAsStr.length() == 10) {
    dateAsStr += 'T00:00:00';
}
ZonedDateTime.parse(dateAsStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));

Solution 4 - Java

If coming from Google:

Instead of doing:

ZonedDateTime.from(new Date().toInstant());

Try this:

ZonedDateTime.ofInstant(new Date(), ZoneId.of("UTC")); 

Solution 5 - Java

Just an example conversions, I believe some folks will get the exception below

(java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 2014-10-24T18:22:09.800Z of type java.time.Instant)

if they try

LocalDateTime localDateTime = LocalDateTime.from(new Date().toInstant());

to resolve the issue, please pass in Zone -

LocalDateTime localDateTime = LocalDateTime.from(new Date()
        .toInstant().atZone(ZoneId.of("UTC")));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFaliornView Question on Stackoverflow
Solution 1 - JavaassyliasView Answer on Stackoverflow
Solution 2 - JavaMeno HochschildView Answer on Stackoverflow
Solution 3 - JavaSergey PonomarevView Answer on Stackoverflow
Solution 4 - JavafIwJlxSzApHEZIlView Answer on Stackoverflow
Solution 5 - JavaDahar YoussefView Answer on Stackoverflow