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

如何在Malli中验证本地日期字符串?引入time模块后验证失败

问题

我尝试使用malli.experimental.time模块,代码如下:

(ns foobar.core
  (:require [malli.core :as m]
            [malli.registry :as mr]
            [malli.experimental.time :as met]))

;; 这应该会添加malli.experimental.time的schema
(mr/set-default-registry!
  (mr/composite-registry
    (m/default-schemas)
    (met/schemas)))

我原本期望以下调用中的某一个返回真值,但实际上都没有:

(m/validate :time/local-date "2024-01-01")
(m/validate [:time/local-date] "2024-01-01")
(m/validate [:time/local-date {:pattern "yyyy-mm-dd"}] "2024-01-01")
(m/validate [:time/local-date {:pattern "yyyy-MM-dd"}] "2024-01-01")
(m/validate [:time/local-date {:pattern "YYYY-MM-DD"}] "2024-01-01")

我遗漏了什么?文档中提到的“transformation”功能是否是必需的?

解答

  • 核心问题::time/local-date 校验的是Java时间对象,而非字符串
    malli.experimental.time提供的:time/local-date这类schema,默认用于校验java.time.LocalDate类型的实例,而非字符串格式的日期。你传入的是字符串"2024-01-01",自然无法通过校验。

  • 关于transformation的作用
    文档提到的transformation功能,是用来将字符串(或其他格式)转换为对应Java时间对象的工具,它不是校验的必需项,但如果想直接用字符串完成校验,需要结合它先做转换,或者使用专门的字符串校验schema。

  • 正确的使用方式
    校验字符串格式日期有两种可行方案:

    1. 先转换再校验:用met/transform把字符串转成LocalDate实例后再校验
      (let [date-str "2024-01-01"
            transformed-date (met/transform :time/local-date date-str)]
        (m/validate :time/local-date transformed-date)) ; 返回true
      
    2. 使用字符串专用schema:malli.experimental.time提供了带-string后缀的schema,专门校验符合格式的字符串,无需转换直接使用:
      (m/validate :time/local-date-string "2024-01-01") ; 返回true
      ;; 自定义格式可传入pattern参数
      (m/validate [:time/local-date-string {:pattern "yyyy/MM/dd"}] "2024/01/01") ; 返回true
      
  • 补充:registry注册的注意事项
    你当前注册registry的方式是正确的,但要确保代码执行顺序——registry必须在校验操作之前完成注册,否则会出现schema找不到的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:12:33