2

I am parsing the date like '2018-04-12 15:12:32.999' using java8 formatter. It works fine when i have a 3 digit milliseconds such as this date '2018-04-12 15:12:32.999', but it fails and throws an exception java.time.format.DateTimeParseException: Text '2018-04-18 15:27:10.77' could not be parsed at index 20, when date is having only 2 digit milliseconds, can you please suggest how to parse this date.

My formatter is using "yyyy-MM-dd HH:mm:ss.SSS" pattern. My code is like this:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime.parse(dateStr,formatter);
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161

3 Answers3

3
String dateStr = "2018-04-12 15:12:32.99";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("yyyy-MM-dd HH:mm:ss")
            .appendFraction(ChronoField.MILLI_OF_SECOND, 2, 3, true)
            .toFormatter();
System.out.println(LocalDateTime.parse(dateStr, formatter));

where 2,3 - the minimum, maximum width of the field

output:

2018-04-12T15:12:32.990

meiskalt7
  • 606
  • 7
  • 13
1

There are a couple of options. I would go for this one:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();
    String dateTimeString = "2018-04-18 15:27:10.77";
    LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
    System.out.println(dateTime);

Output:

2018-04-18T15:27:10.770

DateTimeFormatter.ISO_LOCAL_TIME optionally accepts a decimal point and one to nine digits. I prefer using the builder to combine the predefined formatters rather than building my own from scratch.

There’s a shorter one that some prefer. Personally I find it a bit hacky:

    dateTimeString = dateTimeString.replace(' ', 'T');
    LocalDateTime dateTime = LocalDateTime.parse(dateTimeString);

Output is the same. We’re exploiting two facts: (1) The one-arg LocalDateTime.parse parses ISO 8601 format. (2) Your input string is very close to being in ISO 8601 format, it only lacks the T that denotes the place where the time part begins.

You don’t need the third option, but for the sake of completeness I would like to mention: If building a formatter from scratch and needing a variable number of decimals, use DateTimeFormatterBuilder (the class I used in the first snippet) and its appendFraction method. It gives you control over the minimum and maximum number of decimals.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

15:12:32:999 contains a colon :. Your pattern HH:mm:ss.SSS contains a dot . This will not match.

This works.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Playground {

    public static void main(String[] args) throws ParseException {
        String pattern = "yyyy-MM-dd HH:mm:ss.SSS";

        String s1 = "2018-04-12 15:12:32.999";
        String s2 = "2018-04-18 15:27:10.77";

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);

        Date d1 = sdf.parse(s1);
        System.out.println(d1);

        Date d2 = sdf.parse(s2);
        System.out.println(d2);
    }

}

Output:

Thu Apr 12 15:12:32 CEST 2018
Wed Apr 18 15:27:10 CEST 2018
  • Sorry, its a typing mistake, first date also contains . not : and also i am using Java8 DateTimeFormatter not SimpleDateFormat .. code is like this.. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); LocalDateTime.parse(dateStr,formatter); – Prasad Krishnegowda Apr 18 '18 at 15:14
  • 1
    Please edit your question. Don't put code into a comment. –  Apr 18 '18 at 18:45
  • 1
    When the OP says “using java8 formatter”, an answer using the long outdated and notoriously troublesome `SimpleDateFormat` is not appropriate (I have edited the question for the OP). BTW I also think this answer gives incorrect results. – Ole V.V. Apr 19 '18 at 02:46