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

Flutter中DateFormat解析带AM/PM的DateTimePicker值抛FormatException如何解决

问题根因

你遇到的报错有两个核心原因:

  1. 你当前DateTimePicker返回给_boardingDate.text的字符串没有包含AM/PM后缀,你在解析格式串中加入a标识后,解析器读取到2021-09-25 04:20(总长度16位)之后没有后续内容,直接触发越界错误。
  2. 你设置了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:30:00