TL;DR
Instant parsedBack = Instant.parse(Instant.now().toString());
System.out.println(parsedBack);
2019-05-30T08:36:47.966274Z
Use ISO 8601 and java.time
- If your real goal is to serialize and deserialize a date and time (for data transfer or for persistence, for example), serialize to ISO 8601, the standard format for date and time data.
- Skip the long outdated
Date
class. The modern Java date and time API known as java.time
is so much nicer to work with. The class you need from it is probably Instant
(this depends on your more exact requirements).
The two points go nicely hand in hand:
Instant i = Instant.now();
String s = i.toString();
Instant theSameInstant = Instant.parse(s);
The modern classes’ toString
methods produce ISO 8601 format (e.g., 2018-01-11T10:59:45.036Z
), and their parse
methods read the same format back. So this snippet is all you need, and you get an instant equal to the first, with nanosecond precision.
If you cannot control the string you get, and you get the result from Date.toString()
, the format pattern string in BalusC’s answer works with java.time
too:
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
Date d = new Date();
String s = d.toString();
Instant nearlyTheSameInstant = ZonedDateTime.parse(s, dtf).toInstant();
Some warnings, though:
- Milliseconds from the original
Date
are lost since they are not in the string, leading to an inaccuracy of up to 999 milliseconds (which was why I named the variable nearlyTheSameInstant
).
- The era from the original
Date
is not in the string either. So if your original Date
was in year 44 BCE, you will get the corresponding date in year 44 CE (AD) (in which case the variable name nearlyTheSameInstant
was a lie anyway).
- The time zone abbreviation in the string is often (most often?) ambiguous, so there is a great risk of getting the wrong time zone and hence a wrong time. To make matters worse, an ambiguous time zone abbreviation will be interpreted differently on different JVMs
- It’s essential to provide a locale. Otherwise the JVM’s default locale will be used, and if it’s not English, parsing will fail. In the worst case you will see your code running fine for many years and suddenly it will break when one day someone runs it on a computer or device with a different locale setting. I use
Locale.ROOT
for “the locale neutral locale” or “don’t apply any locale specific processing”. It seems to be the correct approach here.
Links