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

如何在Malli Schema中验证日期?遇正则转义及验证失败问题

在Malli中正确验证日期的解决方案

一、使用Malli原生日期类型:local-date

Malli的:local-date类型验证的是**java.time.LocalDate实例**,而非日期字符串。如果你的输入是字符串,需先解析为LocalDate,或自定义验证器直接校验字符串格式:

  1. 解析字符串为LocalDate后验证
(require '[malli.core :as m])
(require '[clojure.java-time :as time])

(def schema [:map [:a :int] [:b :local-date]])

; 将字符串转成LocalDate实例后验证
(m/validate schema {:a 1 :b (time/local-date "2022-07-28")}) ; 返回true
  1. 自定义字符串日期验证器(兼顾格式与有效性)
    正则只能校验格式,无法识别无效日期(如2022-13-01),用:fn结合日期解析更可靠:
(def date-string-schema
  [:map
   [:a :int]
   [:b [:and string?
        [:fn (fn [s]
               (try
                 (time/local-date s)
                 true
                 (catch Exception _ false)))]]]])

(m/validate date-string-schema {:a 1 :b "2022-07-28"}) ; 返回true
(m/validate date-string-schema {:a 1 :b "2022-13-01"}) ; 返回false(无效日期)

二、解决正则验证的转义与失败问题

你遇到的问题核心是字符串转义错误和Schema键与验证数据不匹配:

1. 正则的正确写法

  • 用正则字面量(无需转义):
(def s2 [:map [:orderId string?] [:OrderDate :re #"\d{4}-\d{2}-\d{2}"]])
  • 用字符串形式(需双重转义,Clojure字符串中\是转义字符):
(def s2 [:map [:orderId string?] [:OrderDate :re "\\d{4}-\\d{2}-\\d{2}"]])

2. 验证失败的关键原因

你的Schema定义的键是:orderId和:OrderDate,但验证时传入的是:a和:b,键名完全不匹配,导致验证失败。正确验证代码:

(m/validate s2 {:orderId "123" :OrderDate "2022-07-28"}) ; 返回true

3. JSON Schema转换问题

只要正则写法正确(字面量或转义后的字符串),Malli可正常转换为JSON Schema:

(require '[malli.json-schema :as mjs])

(mjs/transform s2)
; 生成的JSON Schema会包含"pattern": "^\\d{4}-\\d{2}-\\d{2}$"

三、推荐方案

  • 若需处理日期逻辑(如计算、比较),优先用:local-date类型,提前将字符串解析为LocalDate实例。
  • 若仅需验证字符串格式,用自定义:fn验证更可靠(避免正则漏过无效日期)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:24:21