You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring MVC中用@RequestParam解析不同ISO日期时间格式

处理多种类ISO格式的日期时间解析方案

嘿,这个问题我之前在对接第三方API的时候也遇到过!Spring默认的日期解析规则确实没法覆盖这些五花八门的ISO变种格式,不过咱们可以通过自定义格式化逻辑轻松搞定,给你两种实用的方案:

方案一:控制器级别的局部绑定(针对单个控制器)

如果只需要在某个特定控制器里处理这些格式,可以用@InitBinder来注册自定义的日期编辑器:

@RestController
class SomeApiController {

    @InitBinder
    fun initBinder(binder: WebDataBinder) {
        // 构建支持所有目标格式的DateTimeFormatter
        val customFormatter = DateTimeFormatterBuilder()
            // 基础的日期时间部分:yyyy-MM-dd'T'HH:mm:ss
            .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
            // 可选的毫秒部分(0-3位,比如.410、.41或者无)
            .optionalStart()
            .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
            .optionalEnd()
            // 可选的时区偏移部分,支持三种格式:XXX(+00:00)、XX(+0000)、X(+00/Z)
            .optionalStart()
            .appendPattern("[XXX][XX][X]")
            .optionalEnd()
            .toFormatter()

        // 注册自定义编辑器,绑定到OffsetDateTime类型
        binder.registerCustomEditor(OffsetDateTime::class.java, object : PropertyEditorSupport() {
            override fun setAsText(text: String?) {
                value = text?.takeIf { it.isNotBlank() }?.let {
                    OffsetDateTime.parse(it, customFormatter)
                }
            }
        })
    }

    @RequestMapping(value = ["/some/api/call"], method = [RequestMethod.GET])
    fun someApiCall(@RequestParam("from") from: OffsetDateTime): ResponseEntity<String> {
        // 业务逻辑处理
        return ResponseEntity.ok("Parsed date: $from")
    }
}

方案二:全局配置(全应用生效)

如果多个控制器都需要处理这些格式,推荐全局配置,一劳永逸:

@Configuration
class GlobalDateTimeConfig : WebMvcConfigurer {

    override fun addFormatters(registry: FormatterRegistry) {
        val customFormatter = DateTimeFormatterBuilder()
            .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
            .optionalStart()
            .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
            .optionalEnd()
            .optionalStart()
            .appendPattern("[XXX][XX][X]")
            .optionalEnd()
            .toFormatter()

        // 注册全局的OffsetDateTime格式化器
        registry.addFormatter(object : Formatter<OffsetDateTime> {
            override fun parse(text: String, locale: Locale): OffsetDateTime {
                return OffsetDateTime.parse(text, customFormatter)
            }

            override fun print(obj: OffsetDateTime, locale: Locale): String {
                return obj.format(customFormatter)
            }
        })
    }
}

关键注意点

  • 建议使用OffsetDateTime作为参数类型,因为所有目标格式都带时区偏移,用这个类型能准确保留时区信息,避免时区转换错误。
  • 自定义的DateTimeFormatter通过optionalStart()和optionalEnd()实现了对可选部分(毫秒、时区偏移)的支持,同时用[XXX][XX][X]的模式匹配三种不同的时区偏移格式。

内容的提问来源于stack exchange,提问作者Bastian Voigt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:55:49