1

I am trying to parse following date time string

2018-01-30T23:59:59.000

I am not able to understand which standard format it is like UTC or ISO_8601

while parsing in the following manner:

SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD'T'HH:MM:SS:MS");
        Date date = null;
        try {
            date = sdf.parse("2018-01-30T23:59:59.000");
        } catch (ParseException e) {
            e.printStackTrace();
        }

But It is throwing following exception:

java.text.ParseException: Unparseable date: "2018-01-30T23:59:59.000"

Any help is appreciated.

Awadesh
  • 3,530
  • 2
  • 20
  • 32
  • I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). Your string is ISO 8601, and `LocalDateTime` from `java.time` will parse it without any explicit formatter, so you’ll have no trouble with a format pattern string. – Ole V.V. May 10 '18 at 12:55
  • Possible duplicate of [SimpleDateFormat ignoring month when parsing](https://stackoverflow.com/questions/3056703/simpledateformat-ignoring-month-when-parsing). Or as you see it, possible duplicate of [Parsing a string to date format in java defaults date to 1 and month to January](https://stackoverflow.com/questions/33427670/parsing-a-string-to-date-format-in-java-defaults-date-to-1-and-month-to-january). – Ole V.V. May 10 '18 at 13:04

3 Answers3

3

See the doc of SimpleDateFormat and try this:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
xingbin
  • 27,410
  • 9
  • 53
  • 103
  • for minutes it should be "yyyy-MM-dd'T'hh:mm:ss.SSS", i dont know it is upvoted :), please correct it. – Awadesh May 10 '18 at 16:48
  • FYI, the terribly troublesome date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 06 '19 at 06:00
2
    LocalDateTime dateTime = LocalDateTime.parse("2018-01-30T23:59:59.000");
    System.out.println(dateTime);

This prints:

2018-01-30T23:59:59

Your string is in ISO 8601 format. UTC or Coordinated Universal Time is not a format, it is a standard time used to define the time the rest of use in our respective time zones.

The date-time classes you were using, SimpleDateFormat and Date, are long outdated and the former in particular notoriously troublesome. I recommend that you instead use java.time, the modern Java date and time API. It is so much nicer to work with.

A LocalDateTime is a date with time of day and without time zone or offset from UTC. Its one-argument parse method parses ISO 8601, which is why no explicit formatter is needed.

What went wrong in your code

Your format pattern string has a number of issues to it. Which is one reason why you should appreciate the above solution without any explicit formatter. The first thing that goes wrong is: Your format pattern string has a colon, :, between seconds and milliseconds, whereas your date-time string has a dot, .. This is why you get the exception.

However, fixing this, your code yields the following Date:

Sun Dec 31 23:00:00 CET 2017

It’s one month off from the expected, and the minutes and seconds are missing. Because:

  • Uppercase YYYY is for week-based year and only useful with a week number. You need lowercase yyyy for year.
  • Uppercase DD is for day of year. You need lowercase dd for day of month.
  • You correctly used uppercase MM for month. Trying the same again for minutes won’t work. Maybe you can guess by now: it’s lowercase mm.
  • Not surprising you need lowercase ss for seconds.
  • UsingMS for milliseconds is interesting. SimpleDateFormat takes it as M for month (which we’ve already had twice before) and uppercase S for millisecond. Instead you needed uppercase SSS for the three digits of milliseconds.

Links

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

You need to escape the literal T:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:SS");

See This SO Answer for more examples

Update: Your string is in the format

yyyy-MM-dd'T'HH:mm:ss.SSS

but you are trying to parse it with a completely uppercase format string.

This does not do what you want it to do and you should read the documentation on SimpleDateFormat and the format string placeholders

mcfinnigan
  • 11,442
  • 35
  • 28