I have code that looks like this:
String PROPER_DATE_FORMAT = "yyyy-MM-dd";
String format = "yyyy-MM-dd'T'HH:mm:ss.SSSX";
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(Instant.now().toString());
SimpleDateFormat properFormat = new SimpleDateFormat(PROPER_DATE_FORMAT);
String formatterDate = properFormat.format(d);
Now, most of the time, this code works but every now and then, I'll Instant.now() returning 2018-05-25T18:56:09Z
and then it will throw an exception bc the format doesn't match.
Why is it sometimes inconsistent?
The exception is java.lang.RuntimeException: java.text.ParseException: Unparseable date: "2018-05-25T18:56:09Z"
Normally, when Instant.now().toString()
does return a String with the above format. Again, this code works most of the time but there are a few times when it doesn't and I'm puzzled as to why.
I thought about whether it was because there's a zero at the end but just wasn't displayed but I'm not convinced because I was able to get a value of 2018-05-25T20:06:58.900Z as a result of Instant.now().toString()
Instance.now().toString()
call returns a value with only two digits in the ms (while theformat
expects three digits) ? – GallPROPER_DATE_FORMAT
does not seem to be relevant in this case – GallInstant.now().toString()
, it returns a value with 3 digits, like this: 2018-05-25T20:06:58.905Z – Clemenciaclemency2018-05-25T20:06:58.900Z
as a result ofInstant.now().toString()
– ClemenciaclemencyDate d = new Date(Instant.now().toEpochMilli());
– Wagram2018-05-25T20:06:58.90Z
with the same formatter – Gall2018-05-25T20:06:58.90Z
with the same formatter will return the exception above as it should. – ClemenciaclemencyInstance.now().toString()
returns only 1 or 2 digits in the ms (and not 3) as expected? – GallInstant.toString()
outputs digits for millis only if necessary (if they are not000
). So you have a one in thousand chance of hitting exactly the second (with all milliseconds digits zero) where your code will fail – Wagramjava.time
, the modern Java date and time API, don’t useDate
too, it’s long outdated and poorly designed. Only if you need aDate
for a legacy API that you cannot change. Only in this case, useDate.from(Instant)
for conversion. And under no circumstances at all use the notoriously troublesomeSimpleDateFormat
. – Polyurethaneyyyy-MM-dd
format, you can useLocalDate.now(yourZoneId).toString()
. – PolyurethaneInstant.now().toString()
yields something like2018-05-26T05:56:50.294304Z
, which your code converts to aDate
of Sat May 26 08:01:44 CEST 2018. CEST is at offset +02:00, so you notice the time is not correct. – Polyurethane