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

Flutter日期比较报错:FormatException: Trying to read yyyy from position 0

问题:Flutter日期比较抛出FormatException错误

尝试通过比较两个日期来控制TextField的显示/隐藏,但条件判断时总是抛出错误FormatException: Trying to read yyyy from at position 0,注释该条件则无报错,目标解析日期为2022-10-11。

相关代码

全局变量代码

String validityString = '';

DateTime currentDate = DateUtils.dateOnly(DateTime.now());

DateTime thisValidity =
    Intl.withLocale('en', () => DateFormat("yyyy-MM-dd").parse(validityString));

日期赋值代码

if (response.data["status"] == "success") {
  setState(() {
    name = json.encode(response.data["data"]["name"]);
    credit = json.encode(response.data["data"]["credit"]);
    currency = json.encode(response.data["data"]["currency"]);
    entryCount = json.encode(response.data["data"]["entryCount"]);
    validity = json.encode(response.data["data"]["validity"]);

    validityString = validity.toString().replaceAll(RegExp('"'), '');
  });
}

条件判断代码

if (thisValidity.isBefore(currentDate))
     TextField(
       readOnly: true,
       enabled: false,
       decoration: InputDecoration(
          labelText:
            AppLocalizations.of(context)!.validity +
                                          validity
                                              .toString()
                                              .replaceAll(RegExp('"'), ''),
            border: const OutlineInputBorder(),
            labelStyle: const TextStyle(
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                          filled: true,
                          fillColor: Colors.amberAccent,
         ),
       ),

问题原因

核心问题是全局变量thisValidity初始化时,validityString是空字符串。此时调用DateFormat.parse('')会直接抛出格式异常,因为空字符串无法匹配yyyy-MM-dd的日期格式。注释条件后,thisValidity的初始化代码虽存在,但未被调用,因此不会触发错误。

解决方案

1. 延迟日期解析,避免空值初始化

将thisValidity改为可空变量,在validityString获取到有效数据后再进行解析:

// 全局变量改为可空类型
DateTime? thisValidity;
DateTime currentDate = DateUtils.dateOnly(DateTime.now());
String validityString = '';

// 在接口回调的setState中完成解析
if (response.data["status"] == "success") {
  setState(() {
    // ...其他字段赋值
    validityString = response.data["data"]["validity"] ?? '';
    // 此时validityString已有值,执行解析
    try {
      thisValidity = Intl.withLocale('en', () => DateFormat("yyyy-MM-dd").parse(validityString));
    } catch (e) {
      print("日期解析失败: $e");
      thisValidity = null;
    }
  });
}

2. 条件判断前增加空值校验

使用thisValidity前先确认其不为空,避免调用isBefore时出错:

if (thisValidity != null && thisValidity!.isBefore(currentDate)) {
  TextField(
    // ...TextField配置
  );
}

3. 优化日期赋值逻辑,减少冗余操作

response.data["data"]["validity"]本身就是字符串格式,无需用json.encode转换,直接赋值给validityString即可,省去多余的引号替换:

// 替换原有的validity赋值和validityString处理
validityString = response.data["data"]["validity"] ?? '';

4. 增加异常捕获,提升鲁棒性

即使返回的日期格式不符合预期,也能捕获异常避免应用崩溃:

try {
  thisValidity = Intl.withLocale('en', () => DateFormat("yyyy-MM-dd").parse(validityString));
} catch (e) {
  print("日期解析异常: $e");
  thisValidity = null;
}

总结

确保解析日期时validityString已持有合法的日期字符串,同时通过空值校验和异常捕获处理边界情况,即可解决该格式异常问题。

内容的提问来源于stack exchange,提问作者Tobiáš B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:15:33