0

I am trying to parse the String into simple date format but getting unable to parse date exception.could some one try to help me out on this.

  String dateFormatter ="20190911T14:37:08.7770400";
  SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMDD'T'HH:mm:ss.SSSZZZZ");
  //tried the below commnet also
  //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-d'T'HH:mm:ss.SSSZZZZ");
  System.out.println(sdf.parse(dateFormatter));


 Error: 
       "Exception in thread "main" java.text.ParseException: Unparseable 
       date: "20190911T14:37:08.7770400" at 
       java.text.DateFormat.parse(DateFormat.java:366) at 
      com.sudha.test.sample_boot_example.TestString.main(TestString.java:20)
  • 2
    Is 7770400 the number of nanoseconds or is it milliseconds plus timezone offset? – Karol Dowbecki Sep 12 '19 at 18:45
  • Very good question, @KarolDowbecki! The format looks like [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), and if it is, those 7 digits are 10ths of microseconds(!) But the count of 7 might suggest that either a `+` or a `-` has disappeared and that it should have been either `20190911T14:37:08.777+0400` or `20190911T14:37:08.777-0400`, that is, milliseconds and a UTC offset. – Ole V.V. Sep 13 '19 at 05:31
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use either `LocalDateTime` or `OffsetDateTime` and also `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 13 '19 at 05:34

3 Answers3

2

The timezone portion of your format is expecting a leading + or - character. As such the string you gave it fails. If you try it with "20190911T14:37:08.777+0400" it works.

I don't see any options that will work with a 4-digit timezone offset that doesn't have a sign. https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html

Edit: Also as Andeas has pointed out in a comment, the year and day should be using lowercase, ‘yyyy’ and ‘dd’

swpalmer
  • 3,890
  • 2
  • 23
  • 31
  • 1
    Upvoted for addressing main issue, but it would be good if you also addressed the wrong use of `YYYY` and `DD`, which should be in lowercase. – Andreas Sep 12 '19 at 18:57
2

Use correct formatting codes. Read the Javadoc more carefully.

Input means fractional second in microseconds range?

If the last digits represent a fraction of second, this code works. Your seven digits for a fractional second is unusual; increments of 3 (3, 6, or 9) is more common. But we can make it work.

String input = "20190911T14:37:08.7770400" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HH:mm:ss.SSSSSSS" ) ; 
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

See this code run live at IdeOne.com.

ldt.toString(): 2019-09-11T14:37:08.777040

Input means offset? Faulty input.

If the last digits were intended to be a combination of a fractional second in milliseconds and four digits for an offset-from-UTC (a number of hours and minutes), then your input is faulty. An offset is either ahead of UTC or it is behind UTC. So an offset must include either a plus sign + or a minus sign -. Your input has neither, so such a string cannot be parsed for its offset-from-UTC.

See this Question, Parsing ISO-8601 DateTime in java.

ISO 8601

The format of your input string is terrible, apparently a clumsy mangling of the standard ISO 8601 format. For example: 2013-04-03T17:04:39.9437823+04:00. I strongly suggest you educate the publisher of this data about the ISO 8601 standard. Do not invent new formats, stick with the standard.

The java.time classes use the ISO 8601 formats by default when parsing/generating strings. So, no need to specify a formatting pattern at all!

Another thing: If you are trying to track moments, actual points on the timeline, then you must include an offset or time zone with input. Without that context, we do not know if the input meant 2 PM in Tokyo Japan or 2 PM in Toledo Ohio US — two very different moments, happening several hours apart.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • For the sake of completeness, ISO 8601 does allow omitting the hyphens. The Wikipedia article you link to gives `20190913T014615Z` as an example (when I checked just now). Not that it’s recommended. In any case you are correct, there’s nothing we can do with a four digit offset without sign. – Ole V.V. Sep 13 '19 at 05:42
  • 1
    @OleV.V. Yes, ISO 8601 allows omitting the hyphens as delimiters on the date position, but then you must also omit the colon characters as delimiters on the time-of-day portion. The malformed inputs in the Question do one without the other. Hence my description as “clumsy mangling” of the standard format. – Basil Bourque Sep 13 '19 at 05:49
0
String dateFormatter ="20190911T14:37:08.777+0400";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss.SSSZZZZ");
        try {
            System.out.println(sdf.parse(dateFormatter));
        } catch (Exception ex) {
            System.out.println(ex);
        }

Adding the + should work, plus check that it's 'yyyyMMdd' not 'YYYYMMDD'.

Syrup72
  • 116
  • 1
  • 12
  • Adding the `+` should work — unless a minus was intended. The questioner is in the US, so it’s not unlikely. We cannot know. – Ole V.V. Sep 13 '19 at 05:43