我有一个用户出现以下错误:
Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: FormatException: Invalid date format
. Error thrown null.
at DateTime.parse(DateTime.java)
错误来自我的代码的这一部分
String myString ="";
void myfunction() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
String myString = prefs.getString("key")??"";
_variable = myString!=null||myString!="" ? DateTime.parse("$myString") : DateTime.now();
}
_variable = myString!=null||myString!="" ? DateTime.parse("$myString") : DateTime.now();
我不明白,因为这个错误似乎找到了一个null,但我的原因是通过强制null为DateTime.now()来阻止null;
我错了?
在这种情况下,Null条件为TRUE,因此转换日期格式的结果为空。所以请检查一次
// here always empty data will assign.
String myString = prefs.getString("key")??"";
DateTime _variable = myString != "" ? DateTime.parse(myString) : DateTime.now();
print(_variable);
当传递给DateTime.parse
的字符串无效时,会发生此异常。您可以考虑使用DateTime.tryParse
,它将返回null
,而不是在字符串无效时抛出FormatException
。
final String myString = prefs.getString("key") ?? "";
final DateTime _variable = DateTime.tryParse(myString) ?? DateTime.now();
很可能您在该代码中的字符串包含无效/空字符串。并且您使用了错误的操作"||"也
_variable = myString!=null||myString!="" ? DateTime.parse("$myString") : DateTime.now();
但为了获得更好的方法,如果您的意图只是将日期替换为当前日期,而不考虑解析异常,我建议您执行DateTime.tryParse
_variable = DateTime.tryParse(myString) ?? DateTime.now();
DateTime parse(String formattedString)
基于formattedString构造一个新的DateTime实例。如果无法解析输入字符串,则引发FormatException。若要检测并拒绝无效的组件值,请使用intl包中的DateFormat.parseStrict。
有关文档的更多详细信息
也许你可以试试下面的方法:
// convert data to string
_variable = data!=null ? DateTime.parse('$data') : DateTime.now();
例如,值为空,但条件不为空
myString!=null||myString!=""
为true,因为它满足不为null的条件。你必须检查是否为非空和非空,所以使用&;应该解决问题
_variable = myString!=null && myString!="" ? DateTime.parse("$myString") : DateTime.now();
此外,最好写
_variable = DateTime.tryParse('$myString') ?? DateTime.now();
这将尝试解析字符串,如果返回null,则将分配日期时间。现在
DateTime.parse方法接受字符串作为输入,但传递给该方法的输入必须是有效的。如果输入无效,则抛出FormatException。
来自文档:
当前接受的输入为:
日期:一个有符号的四到六位数的年份、两位数的月份和两位数天,可以选择用-个字符分隔。示例:";19700101";,"-0004-12-24"81030-04-01";。
一个可选的时间部分,用T或空格与日期隔开。时间部分是两位数的小时,然后是两位数(可选)的分钟值,然后可选地是两位数的秒值,然后是可选的a"。"或","后接至少一位数字的秒分数。这个分钟和秒可以与前面的部分用":"分隔。示例:";12〃"12:30:24.124"12:30:24124"123010.50";。
可选的时区偏移部分,可能与前面有一个空格。时区是"z"或"z",或者是带符号的两位数小时部分和可选的两位数分钟部分。这个符号必须是"或"+"或"-&";,并且不能被省略。会议记录可能用":"与小时隔开。示例:";Z""-10〃"01:30";,"1130";。
这包括toString和toIso8601String的输出将被解析回与起初的
结果总是以当地时间或UTC表示。如果时区如果指定了UTC以外的偏移,则时间转换为等效UTC时间。
可接受字符串示例:
"2012-02-27"2012-02-27 13:27:00"2012-02-27 13:27:00.123456789z";"2012-02-27 13:27:00123456789z"20120227 13:27:00"20120227T132700";"20120227"20120227"2012-02-27T14Z"2012-02-27T14+00:00";"-123450101 00:00:00 Z":年-12345。"2002-02-27T14:00:00-0500":与";2002-02-27T19:00:000Z";
检查来自api的字符串的格式,看看它是否与上面给定的格式匹配。你能发布一个从firebase得到的示例字符串吗,以便进一步检查
错误来自对可能的NULL值的错误处理。
在代码的这一部分中,您正在从SharedPreferences
读取一个值,并实现了一个检查该值是否为null的功能。如果该值为null,则myString
等于空字符串。这意味着无论发生什么情况,myString都不能为null。
String myString = prefs.getString("key")??"";
然后,您需要加载带有日期值的_variable
。
- 如果
myString
具有日期值,则_variable
应包含解析的值 - 如果
myString
为空或包含空字符串值""
,则_variable
应包含DateTime.now()
_variable = myString!=null||myString!="" ? DateTime.parse("$myString") : DateTime.now();
错误在三元运算符条件下:
myString!=null||myString!=""
正如我之前所写:myString
不能为null。
这意味着条件myString!=null
内的第一个检查将始终是True
,并且由于检查处于OR
关系中,因此整个条件将是True
。如果myString!=""
。
这在执行三元运算符DateTime.parse("$myString")
的正分支时解决。
因此,如果myString
等于""
,则执行DateTime.parse("")
并抛出错误。
这里有一个可能的解决方案:
String myString = prefs.getString("key")??"";
_variable = myString!="" ? DateTime.parse("$myString") : DateTime.now();