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

Dart/Flutter表单校验时如何对比当前输入值与上一次输入的日期值

Flutter 日期先后校验实现方案

你现有代码只做了输入长度校验,要实现「当前输入日期晚于上一次成功录入日期才通过校验」的逻辑,按以下步骤修改即可:

  • 首先在表单对应的State类中新增一个可空的DateTime类型变量,持久化存储上一次成功保存的日期,初始值为null(首次录入无历史值时不触发对比)。
  • 新增适配当前JJ-MM-AAAA(日-月-年)格式的日期解析方法,把输入字符串转为可直接比较大小的DateTime对象,同时拦截长度达标但实际非法的日期值(比如32-13-2024、31-04-2024这类不符合日历规则的输入)。
  • 扩展原有validator逻辑,在长度校验之后追加日期合法性校验、历史日期对比校验。
  • 修改onSaved回调,在保存输入值的同时同步更新存储上一次日期的变量,供下一次校验使用。

关键代码实现

1. 新增状态变量与日期解析工具方法

在表单组件的State类中添加以下代码:

// 存储上一次成功录入的日期
DateTime? _lastSavedDate;

/// 解析日-月-年格式的日期字符串,非法格式返回null
DateTime? _parseDDMMYYYY(String input) {
  try {
    final parts = input.split('-');
    if (parts.length != 3) return null;
    final day = int.parse(parts[0]);
    final month = int.parse(parts[1]);
    final year = int.parse(parts[2]);
    final parsedDate = DateTime(year, month, day);
    // 反向校验,避免DateTime自动进位非法日期(比如31-04自动转成01-05)
    if (parsedDate.day != day || parsedDate.month != month || parsedDate.year != year) {
      return null;
    }
    return parsedDate;
  } catch (_) {
    return null;
  }
}

2. 修改TextFormField的校验与保存逻辑

替换原有TextFormField的validator和onSaved部分代码:

TextFormField(
  autofocus: true,
  keyboardType: TextInputType.datetime,
  controller: _controller,
  decoration: const InputDecoration(
    hintText: 'JJ-MM-AAAA',
    counterText: '',
  ),
  inputFormatters: [
    FilteringTextInputFormatter.allow(RegExp(r'[0-9-]')),
    LengthLimitingTextInputFormatter(10),
  ],
  onSaved: (val) {
    final validDate = _parseDDMMYYYY(val!);
    taskItems.addItem(val);
    // 保存成功后更新上一次录入的日期
    _lastSavedDate = validDate;
  },
  validator: (val) {
    // 原有长度校验
    if (val == null || val.length < 10) {
      return 'Entre une date valide';
    }
    // 校验日期本身是否符合日历规则
    final inputDate = _parseDDMMYYYY(val);
    if (inputDate == null) {
      return 'Entre une date valide';
    }
    // 存在历史录入值时,校验当前日期是否晚于历史值
    if (_lastSavedDate != null && !inputDate.isAfter(_lastSavedDate!)) {
      return 'La date doit être postérieure à la dernière date enregistrée';
    }
    return null;
  },
)

3. 提交按钮逻辑无需调整

原有ElevatedButton的提交逻辑可以直接复用,校验通过后会自动执行保存、重置表单的流程。

实现说明

  • 日期对比直接用DateTime内置的isAfter方法,会自动处理闰年、大小月、跨年跨月的计算逻辑,比手动拆分数字对比可靠性高很多。
  • 日期解析加了反向校验,避免Dart的DateTime构造函数自动把非法日期进位为合法日期,导致非法输入漏过校验。
  • 首次录入时_lastSavedDate为null,不会触发日期对比逻辑,符合首次录入无参考值的使用场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:21:27