Valibot isoTimestamp 通过,new Date 却是 Invalid Date
isoTimestamp 接受的时区文本比 ECMAScript Date 格式更宽。后续确实需要 Date 时,应把转换有效性纳入管道,保留原文本和时区含义。
时间字符串已经通过 v.isoTimestamp(),后面的 new Date(value) 却返回 Invalid Date。如果值含有 T 分隔符、只有小时的时区偏移,或者偏移前有空格,应先看这两个API接受的格式是否相同。
具体例子包括 2026-06-12T10:00:00.000+05 和 2026-06-12T10:00:00 +05:00。Valibot 1.4.2有此报告,1.5.0的isoTimestamp规则同样允许短偏移及相关空格。Node 24.18的Date解析不接受这两种组合。
ISO语法检查不承诺Date构造成功
isoTimestamp检查自身定义的字符串规则,时区分钟在该规则里可以省略。ECMAScript标准日期时间字符串的偏移则使用Z或带分钟的形式;标准之外的解析还可能受引擎影响。
因此,同一个非标准文本在某个平台可读,不代表浏览器、Worker和Node都能读。仅把空格替换成T,反而可能从某个引擎的宽松解析路径切进另一条拒绝路径。
业务需要Date时,校验转换结果
在已经决定输出应为Date的入口,可以将toDate放进管道:
import * as v from 'valibot';
const TimestampDate = v.pipe(
v.string(),
v.isoTimestamp(),
v.toDate(),
);
const result = v.safeParse(TimestampDate, input);
if (!result.success) {
handleInvalidTimestamp(result.issues);
} else {
useDate(result.output);
}
input、handleInvalidTimestamp和useDate属于应用代码。只有成功分支才使用output;不能在失败后又把原文本交给new Date继续运行业务。toDate会将有效输入转换为Date,并对Invalid Date报告问题,因而输出类型已不再是字符串。
若接口必须保留字符串,可以在原管道增加针对实际目标运行时的Date可解析检查,并保留原值;但这仍不等于跨引擎统一格式。跨系统协议最好明确约定带完整偏移的规范表示,在生产方正确输出,而非由消费方猜测缺失信息。
不要直接删除时区、默认加Z,或把本地时间当作UTC。这些操作即使不再报错,也可能把真实时间点移走。输入原本允许微秒精度时,还要明确转换为Date后的毫秒精度是否符合业务要求。
可解析还不等于业务日期一定正确
Date对部分日历输入可能做归一化,有限时间值也不代表预约范围、时区或原始字段全部正确。需要严格日历契约的接口,应在已有日期解析层验证各项边界,不能只依赖一个NaN检查。
回归应同时覆盖Z、完整正负偏移、两种失败组合和业务使用的精度。保留输入原文、解析成功与否及最终时间点的对照;将不合法值明确交给错误处理,而不是让Invalid Date流到数据库或格式化器后才暴露。


