You need to enable JavaScript to run this app. 如何解决Flutter TextField日期场景下的数字输入校验问题
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Flutter TextField日期场景下的数字输入校验问题

问题原因总述

你遇到的两个问题根源都是正则表达式使用错误:方括号[]在正则中是单个字符匹配规则,你写的[1-31]、[1-12]、[1952-2003]写法完全不符合正则语法,只会匹配括号内出现过的单个字符,无法实现范围校验。

1. 日月仅支持带前导零的两位格式解决方案

核心修改点

  • 替换错误的范围正则为正确的两位带前导零匹配规则
  • 增加输入过程校验,禁止第一位输入非0的字符

修改后的月份输入配置

TextFormField(
  textInputAction: TextInputAction.next,
  keyboardType: TextInputType.number,
  maxLength: 2,
  controller: myControllerMonth,
  inputFormatters: <TextInputFormatter>[
    // 兼容输入过程的正则,仅允许输入0开头、后续符合01-12规则的内容
    FilteringTextInputFormatter.allow(RegExp(r'^0?[1-9]?|1[0-2]?$')),
  ],
  onChanged: (valueMonth) {
    // 第一位输入非0直接清空,强制带前导零
    if(valueMonth.length == 1 && valueMonth != '0') {
      myControllerMonth.clear();
      // 可自行添加Toast提示用户输入规则
      return;
    }
    if (valueMonth.length == 2) {
      FocusScope.of(context).nextFocus();
    }
    valueMonthKey = valueMonth;
  }
)

修改后的日期输入配置

TextFormField(
  textInputAction: TextInputAction.next,
  keyboardType: TextInputType.number,
  maxLength: 2,
  controller: myControllerDay,
  inputFormatters: <TextInputFormatter>[
    // 兼容输入过程的正则,仅允许输入0开头、后续符合01-31规则的内容
    FilteringTextInputFormatter.allow(RegExp(r'^0?[1-9]?|[1-2][0-9]?|3[0-1]?$')),
  ],
  onChanged: (valueDay) {
    // 第一位输入非0直接清空,强制带前导零
    if(valueDay.length == 1 && valueDay != '0') {
      myControllerDay.clear();
      // 可自行添加Toast提示用户输入规则
      return;
    }
    if (valueDay.length == 2) {
      FocusScope.of(context).nextFocus();
    }
    valueDayKey = valueDay;
  }
)

2. 年份无法输入部分数字解决方案

核心修改点

替换错误的年份范围正则为正确的4位数字匹配规则,支持1952-2003全范围数字输入

修改后的年份输入配置

TextFormField(
  textInputAction: TextInputAction.done,
  keyboardType: TextInputType.number,
  maxLength: 4,
  controller: myControllerYear,
  inputFormatters: <TextInputFormatter>[
    // 兼容输入过程的正则,覆盖1952-2003全范围
    FilteringTextInputFormatter.allow(RegExp(r'^1?9?5?[2-9]?|1?9?[6-9]?[0-9]?|2?0?0?[0-3]?$')),
  ],
  onChanged: (valueYear) {
    if (valueYear.length == 4) {
      FocusScope.of(context).unfocus();
    }
    valueYearKey = valueYear;
    // 仅当三个输入项都完整时再做日期解析,避免下标越界崩溃
    if(valueDayKey?.length == 2 && valueMonthKey?.length == 2 && valueYear.length == 4) {
      try {
        DateTime _dateTime = DateTime(
          int.parse(valueYearKey),
          int.parse(valueMonthKey),
          int.parse(valueDayKey),
        );
        // 简化年龄计算逻辑,避免原写法的计算误差
        age = DateTime.now().difference(_dateTime).inDays ~/ 365;
        UserAge.age = age;
      } catch(e) {
        // 捕获非法日期异常,比如02月31日这类不存在的日期
        print('日期输入不合法:$e');
      }
    }
  }
)

额外优化建议

可以在用户提交表单前再增加一次全局校验,确认日、月、年都是合法的两位/四位格式,避免极端场景下的非法输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 23:45:04