Flutter中DateFormat解析带AM/PM的DateTimePicker值抛FormatException如何解决
问题根因
你遇到的报错有两个核心原因:
- 你当前
DateTimePicker返回给_boardingDate.text的字符串没有包含AM/PM后缀,你在解析格式串中加入a标识后,解析器读取到2021-09-25 04:20(总长度16位)之后没有后续内容,直接触发越界错误。 - 你设置了
locale: Locale('am', 'ET'),即使选择器返回了上午/下午标识,也是阿姆哈拉语的本地化标识,用默认英文Locale的DateFormat也无法识别对应标识。
另外你当前的转换逻辑也有问题:把字符串解析为DateTime对象后直接调用toString(),得到的是Dart默认的24小时制格式,不会带AM/PM,完全不符合你需要的输出要求。
解决方案
步骤1:修正DateTimePicker配置,确保返回内容包含AM/PM
调整配置,补充时间部分的格式规则,确保返回的字符串带AM/PM标识:
DateTimePicker( type: DateTimePickerType.dateTimeSeparate, // 日期部分格式改为年-月-日,和你需要的格式对齐 dateMask: 'yyyy-MM-dd', initialValue: "Enter Boarding date", firstDate: DateTime(2000), lastDate: DateTime(2100), icon: Icon(Icons.event), dateLabelText: 'Date', timeLabelText: "Hour", // 如果需要显示英文AM/PM,把locale改为英文即可:locale: Locale('en', 'US'), locale: Locale('am', 'ET'), use24HourFormat: false, onChanged: (val) { // 先打印确认返回的字符串已经带AM/PM标识 print("选择器返回值:$val"); _boardingDate.text = val; }, validator: (val) { print(val); return null; }, onSaved: (val) => print(val), ), TextEditingController _boardingDate = TextEditingController();
步骤2:正确解析和格式化日期
解析日期时必须传入和选择器相同的Locale,避免无法识别本地化的AM/PM标识:
// 构造DateFormat时传入和选择器一致的locale,才能正确识别对应语言的AM/PM标识 DateFormat dateFormat = DateFormat('yyyy-MM-dd hh:mm a', 'am_ET'); // 先把字符串解析为DateTime对象 DateTime boardingDateTime = dateFormat.parse(_boardingDate.text); // 格式化得到你需要的「YEAR-MONTH-DATE HOUR:MINUTE AM/PM」格式字符串 String formattedBoarding = dateFormat.format(boardingDateTime); // 传给Node.js后端的最优方案:直接转ISO 8601标准格式,Node.js的Date对象可以直接解析,不需要额外处理 String backendBoardingValue = boardingDateTime.toIso8601String();
更稳妥的替代方案
优先使用DateTimePicker提供的DateTime对象回调(多数第三方日期选择组件都支持直接返回选中的DateTime对象,不需要自行解析字符串),可以完全避免格式匹配、本地化标识识别的问题,拿到DateTime对象后再按需格式化即可。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

