如何在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。正确的使用方式
校验字符串格式日期有两种可行方案:- 先转换再校验:用
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 - 使用字符串专用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
相关产品推荐
相关产品推荐

