how to parse output of new Date().toString()

That format is specified in the Date#toString().

Converts this Date object to a String of the form:

dow mon dd hh:mm:ss zzz yyyy

So, in SimpleDateFormat pattern terms:

EEE MMM dd HH:mm:ss zzz yyyy

Unrelated to the problem, I wonder if it wasn't in first place a bad idea to use Date#toString() instead of SimpleDateFormat#format() to output dates. I would consider to fix it straight there.


BalusC gave you the correct format, you I'd say - don't. The toString() method must not be used for anything other than logging.

You can use SimpleDateFormat for both formatting and parsing.


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

  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 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:

  1. 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).
  2. 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).
  3. 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
  4. 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

  • Oracle tutorial: Date Time explaining how to use java.time.
  • Wikipedia article: ISO 8601