How can I convert Date.toString back to Date?

Solution 1:

If your real goal is to serialize a Date object for some kind of custom made persistence or data transfer, a simple solution would be:

Date d = new Date();
long l = d.getTime();
Date theSameDate = new Date(l);

Solution 2:

You could do it like this

Date d = new Date();
String s = d.toString;
Date theSameDate = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").parse(s);

Solution 3:

  1. 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.
  2. 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 Sedalb’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();

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.

The point from jambjo’s answer still applies: The three and four letter time zone abbreviations used in Date.toString() are very often ambiguous, so there is no guarantee that the time zone is interpreted correctly, and again, it will be interpreted differently on different JVMs.

Finally, Date.toString() does not render the milliseconds that the Date holds, which leads to an inaccuracy of up to 999 milliseconds. If using the string from Date.toString(), there is nothing we can do about it (which was why I named the variable nearlyTheSameInstant).

Solution 4:

Take a look at SimpleDateFormat#parse(). It should provide the functionality you're looking for.