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:
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.
To convert ZonedDateTime to LocalDate instance, use toLocalDate() method. It returns a LocalDate with the same year, month and day as given date-time. ZonedDateTime zonedDateTime = ZonedDateTime. now(); LocalDate localDate = zonedDateTime.
ZonedDateTime is an immutable representation of a date-time with a time-zone. This class stores all date and time fields, to a precision of nanoseconds, and a time-zone, with a zone offset used to handle ambiguous local date-times.
Use OffsetDateTime to store unique instants in the universal timelines irrespective of the timezones, such as keeping the timestamps in the database or transferring information to remote systems worldwide. Use ZonedDateTime for displaying timestamps to users according to their local timezone rules and offsets.
LocalDateTime – same as LocalDate, but includes time with nanosecond precision. OffsetDateTime – same as LocalDateTime, but with time zone offset. LocalTime – time with nanosecond precision and without date information. ZonedDateTime – same as OffsetDateTime, but includes a time zone ID.
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; }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With