应用程序在日期时间之后崩溃 (日期时间.java) => 无效的日期格式。引发空的错误



我有一个用户出现以下错误:

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";,&quot-0004-12-24"81030-04-01";。

  • 一个可选的时间部分,用T或空格与日期隔开。时间部分是两位数的小时,然后是两位数(可选)的分钟值,然后可选地是两位数的秒值,然后是可选的a"。"或","后接至少一位数字的秒分数。这个分钟和秒可以与前面的部分用":"分隔。示例:";12〃"12:30:24.124"12:30:24124"123010.50";。

  • 可选的时区偏移部分,可能与前面有一个空格。时区是"z"或"z",或者是带符号的两位数小时部分和可选的两位数分钟部分。这个符号必须是"或"+"或"-&";,并且不能被省略。会议记录可能用":"与小时隔开。示例:";Z"&quot-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";&quot-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();

最新更新