java - 带有 ISO 参数的 DateTimeFormat 无法正确解析时区

标签 java spring datetime datetime-format

我有这个 Controller ,我正在尝试使用 mockMVC 对其进行测试

@RequestMapping(value = "/something/{language}", method = RequestMethod.GET, produces = { "application/json", "application/xml" })
    public ResponseEntity<someEntity> getInfo( 
            @PathVariable String language, 
            @DateTimeFormat(iso= DateTimeFormat.ISO.DATE_TIME) @RequestParam(required = false) Date fromDate
    )

所以我希望能够解析像文档中的日期格式: 约会时间 最常见的 ISO 日期时间格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ,例如

但是我不断得到这样的东西:

处理程序执行导致异常:无法将类型“java.lang.String”的值转换为所需类型“java.util.Date”;嵌套异常是

org.springframework.core.convert.ConversionFailedException: 
Failed to conv ert from type java.lang.String to type 
@org.springframework.format.annotation.DateTimeFormat 
@org.springframework.web.bind.annotation.RequestParam java.util.Date for value '2015-09-26T01:30:00.000Z'; nested exception is
java.lang.IllegalArgumentException: Unable to parse '2015-09-26T01:30:00.000Z'

据我所知,我没有做错任何事,这当然是对的。 任何人都可以照亮我的坏处吗?我认为我不需要发布更多代码,因为异常确实显示了我传递给 API 的正确值,对吗?

最佳答案

工作原理

您收到作为字符串的日期(HTTP 请求是基于文本的)并指示 Spring 如何通过模式将其转换为日期对象。

//Spring controller 
@GetMapping
public List<Foobar> find(
   @RequestParam(name = "startDate", required = false)
   @DateTimeFormat(pattern = "YOUR_DATE_PATTERN" or iso="ISO Enum member") //how to convert the date string
   Date startDate {
  return service.find(startDate); //work with the java.util.Date object
}

Spring 会将此任务委托(delegate)给 java.text.DateTimeFormat,因此模式应该是格式化程序类可以使用的有效模式。

@DateTimeFormat - 模式 VS Iso

  • 模式:指定您的模式。将直接传递给格式化程序。
  • Iso:org.springframework.format.annotation.DateTimeFormat.ISOEnum 的成员,具有预构建的日期字符串模式。来自枚举文档:

DATE The most common ISO Date Format yyyy-MM-dd, e.g.

DATE_TIME The most common ISO DateTime Format yyyy-MM-dd'T'HH:mm:ss.SSSZ, e.g.

NONE Indicates that no ISO-based format pattern should be applied.

TIME The most common ISO Time Format HH:mm:ss.SSSZ, e.g.

  • 请注意,所有 Enum 成员(NONE 除外)都使用“Z”表示时区。

日期模式中的“Z”是什么意思?

  • 查看日期和时间模式的 Javadoc,我们有两种处理时区的选项:

    1. 'Z' 字符:RFC 822 时区语法(Spring 将使用此语法)
zone      =  "UT"  / "GMT"                ; Universal Time
                                        ; North American : UT

        /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4

        /  "CST" / "CDT"                ;  Central:  - 6/ - 5

        /  "MST" / "MDT"                ;  Mountain: - 7/ - 6

        /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7

        /  1ALPHA                       ; Military: Z = UT;
                                        ;  A:-1; (J not used)
                                        ;  M:-12; N:+1; Y:+12

        / ( ("+" / "-") 4DIGIT )        ; Local differential
                                        ;  hours+min. (HHMM)
  1. 'X' 字符:ISO 8601 时区指示符

Time offsets (15:00−03:30) OR 'Z' for UTC/GMT timezone

问题

  • 如果您选择 org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME 枚举成员,它将使用 yyyy-MM-dd'T'HH:mm:ss。 SSSZ 模式与时区的 RFC 822 语法。

修复

  • 使用相同的模式,但时区使用“X”(使用 ISO 8601 语法):

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

关于 Z 时区

  • ISO 8601 规定:

Coordinated Universal Time (UTC)

If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z". "14:45:15 UTC" would be "14:45:15Z" or "144515Z".

The Z suffix in the ISO 8601 time representation is sometimes referred to as "Zulu time" because the same letter is used to designate the Zulu time zone. However the ACP 121 standard that defines the list of military time zones makes no mention of UTC and derives the "Zulu time" from the Greenwich Mean Time[27] which was formerly used as the international civil time standard.

相关链接

关于java - 带有 ISO 参数的 DateTimeFormat 无法正确解析时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37110016/

相关文章:

java - 如何使用java在selenium中将结果输入到excel文件中

java - 在 Spring 3 jUnit 测试的语句中找不到 HSQLDB 表

perl DateTime 和不存在的时间用户输入,因为 DST 时钟向前

mysql - 将值映射到文本 "on the fly"

javascript - Datetimepicker (EONASDAN) 将选择发送为最近四舍五入的纪元时间戳

java - GWT GoogleMaps 使用样式隐藏默认图层

java - 如何在 Joda-Time 中总结岁月

java - Java 中的循环异常

java - SDN4 - 无法通过 id 列表找到ById

spring - 无法让 PropertyPlaceholderConfigurer 工作