为Flutter的日期TextFormField添加合法性验证方案求助
Flutter日期输入验证解决方案(针对dd.mm.yyyy格式)
当然可行,下面给你两种实用的验证方案,可直接结合你已使用的flutter_multi_formatter掩码工具一起使用:
方案一:手动数值校验(自定义规则灵活)
通过拆分日期字符串,分别校验日、月、年的合法性,适合需要定制校验范围的场景。
实现代码
// 日期验证器函数 String? dateValidator(String? value) { if (value == null || value.isEmpty) { return '请输入日期'; } // 按分隔符拆分日期部分 final parts = value.split('.'); if (parts.length != 3) { return '日期格式应为dd.mm.yyyy'; } // 转换为整数(处理非数字输入) final day = int.tryParse(parts[0]); final month = int.tryParse(parts[1]); final year = int.tryParse(parts[2]); if (day == null || month == null || year == null) { return '日期格式错误'; } // 校验年份范围(可根据业务调整) final currentYear = DateTime.now().year; if (year < 1900 || year > currentYear + 1) { return '年份无效'; } // 校验月份范围 if (month < 1 || month > 12) { return '月份必须在1-12之间'; } // 校验当月最大天数(含闰年判断) final maxDays = _getMaxDaysInMonth(year, month); if (day < 1 || day > maxDays) { return '日期无效,该月份最多$maxDays天'; } return null; // 验证通过 } // 获取指定月份的最大天数 int _getMaxDaysInMonth(int year, int month) { switch (month) { case 2: bool isLeap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); return isLeap ? 29 : 28; case 4: case 6: case 9: case 11: return 30; default: return 31; } }
方案二:利用DateTime解析校验(简洁高效)
将输入的dd.mm.yyyy格式转换为yyyy-mm-dd(DateTime默认支持的格式),通过解析结果判断日期合法性,同时校验解析后的日期是否与原输入一致(避免32.01.2023被自动修正为2023-02-01的情况)。
实现代码
String? dateValidator(String? value) { if (value == null || value.isEmpty) { return '请输入日期'; } final parts = value.split('.'); if (parts.length != 3) { return '日期格式应为dd.mm.yyyy'; } // 转换为DateTime可识别的格式 final formattedDate = '${parts[2]}-${parts[1]}-${parts[0]}'; final date = DateTime.tryParse(formattedDate); if (date == null) { return '日期无效'; } // 校验解析结果与原输入是否匹配 if (date.day != int.parse(parts[0]) || date.month != int.parse(parts[1]) || date.year != int.parse(parts[2])) { return '日期无效'; } return null; // 验证通过 }
整合到TextFormField
将上面的验证器函数直接传入TextFormField的validator参数即可:
TextFormField( decoration: const InputDecoration( labelText: '日期(dd.mm.yyyy)', border: OutlineInputBorder(), errorStyle: TextStyle(color: Colors.red), ), inputFormatters: [ MaskedInputFormatter('##.##.####'), ], validator: dateValidator, // 选择上面任意一个验证器 keyboardType: TextInputType.datetime, )
内容的提问来源于stack exchange,提问作者Heike Heinrich
相关产品推荐
相关产品推荐

