springspring-bootlocaldatezoneddatetime

Spring boot error while passing time of format (yyyy-MM-dd'T'HH:mm:ss Z) in request parameter


I am trying to pass zoned date time of format "2020-02-26T11:02:41 +0000" as request parameter to my spring boot controller.

  public ResponseEntity<?> getStatistics(
  @ApiParam(value = "startDate", example = "2020-02-26T11:02:41 +0000")
  @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss 'Z'") @RequestParam(value = "startDate",
      required = false) ZonedDateTime startDate)

I am getting this exception while hitting the api

Caused by: java.lang.IllegalArgumentException: Parse attempt failed for value [2020-02-26T11:02:41  0000]
at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:206)
at org.springframework.format.support.FormattingConversionService$AnnotationParserConverter.convert(FormattingConversionService.java:321)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)


Caused by: java.time.format.DateTimeParseException: Text '2020-02-26T11:02:41  0000' could not be parsed at index 20
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)

What exactly am I missing here? It seems spring is unable to parse the string to datetime


Solution

  • Four suggestions:

    1. You are trying to use ISO 8601 format, which is a very good idea. You’ve got one error in doing that: ISO 8601 does not accept a space between the time and the UTC offset. I suggest to remove that.
    2. Since your string has got a UTC offset, +0000, and no time zone, you don’t need to use ZonedDateTime for it in Java, and OffsetDateTime is more correct, which I suggest that you use.
    3. One reason for your error seems to be that your string has been URL decoded. I don’t know the fix for this problem in your setting, but either make sure that the string is URL encoded at the source so that URL decoding restores the correct string, or avoid URL decoding.
    4. The other reason for your error is the one that has already been identified in the answer by 夢のの夢. Your format pattern string specifies a literal Z since you have enclosed it in single quotes. Instead I suggest xx in the format pattern for four digit offset (if you’ve got no colon between hours and minutes of the offset).

    URL encoding, also known an percent encoding, is used for encoding strings for URL parameters to fit URL or URI syntax and make sure that they are transmitted correctly even in a limited character set. Among other things, since a URL is not allowed to contain a space, URL encoding changes a space to a +, a plus sign. So URL decoding converts all plus signs back to spaces. This is what happened to your string. Only your plus sign was meant to be there as part of your offset, +0000. So it could no longer be parsed. Your exception message refers to index 20, which is exactly where the plus sign should have been.

    Links