Flutter中Dart日期差函数失效,SharedPreferences变量未重置求助
问题排查与解决方案
核心问题分析
你的代码存在3个关键问题导致变量无法重置:
daysPassed函数判断逻辑错误:DateTime.difference().inDays是按连续24小时间隔计算,而非自然日(比如昨天23:00到今天22:00,间隔不足24小时,inDays返回0,但实际已跨天)。- 重置后未同步内存变量:修改SharedPreferences后,没有更新
HOME类中的全局变量,导致UI依然显示旧值。 - 未更新判断用的时间戳:重置操作完成后,没有更新存储的
day_timestamp_values_changed,下次启动会重复触发重置或一直用旧时间戳判断。 - 异步写入未等待:SharedPreferences的
set方法是异步操作,直接调用可能导致数据未持久化就执行后续逻辑。
修正代码
1. 修正daysPassed函数(自然日判断)
添加DateTime扩展,提取日期部分忽略时分秒,确保跨天即触发判断:
bool daysPassed(int timeStamp, int days) { final givenDate = DateTime.fromMillisecondsSinceEpoch(timeStamp).date; final currentDate = DateTime.now().date; return currentDate.difference(givenDate).inDays >= days; } // 扩展DateTime,获取仅包含年月日的日期对象 extension DateTimeExtension on DateTime { DateTime get date => DateTime(year, month, day); }
2. 修正逻辑代码(完整版本)
HOME.pref = await SharedPreferences.getInstance(); int? timeStamp = HOME.pref!.getInt('day_timestamp_values_changed'); int? timeStamp1Week = HOME.pref!.getInt('week_timestamp'); // 处理首次启动无时间戳的情况 if (timeStamp == null) { await HOME.pref!.setInt('day_timestamp_values_changed', DateTime.now().millisecondsSinceEpoch); // 初始化全局变量 HOME.currentCircleProgressValue = 0; HOME.currentCircleProgressValue2 = 0; HOME.currentCircleProgressValue3 = 0; HOME.iii = 0; HOME.Currentday = 0; HOME.Lastday = 0; setState(() {}); return; } if (daysPassed(timeStamp, 1)) { // 批量执行异步写入,等待全部完成 await Future.wait([ HOME.pref!.setDouble('currentCircleProgressValue', 0), HOME.pref!.setDouble('currentCircleProgressValue2', 0), HOME.pref!.setDouble('currentCircleProgressValue3', 0), HOME.pref!.setInt('iii', 0), HOME.pref!.setInt('Currentday', 0), // 更新时间戳,避免下次重复触发 HOME.pref!.setInt('day_timestamp_values_changed', DateTime.now().millisecondsSinceEpoch), ]); // 同步更新全局变量 HOME.currentCircleProgressValue = 0; HOME.currentCircleProgressValue2 = 0; HOME.currentCircleProgressValue3 = 0; HOME.iii = 0; if (HOME.Currentday != 0) { HOME.Lastday = HOME.Currentday; } HOME.Currentday = 0; } else { // 读取存储值,添加空安全默认值 HOME.currentCircleProgressValue = HOME.pref!.getDouble('currentCircleProgressValue') ?? 0; HOME.currentCircleProgressValue2 = HOME.pref!.getDouble('currentCircleProgressValue2') ?? 0; HOME.currentCircleProgressValue3 = HOME.pref!.getDouble('currentCircleProgressValue3') ?? 0; HOME.iii = HOME.pref!.getInt('iii') ?? 0; HOME.Currentday = HOME.pref!.getInt('Currentday') ?? 0; HOME.Lastday = HOME.pref!.getInt('Lastday') ?? 0; } // 最后统一调用setState更新UI setState(() {});
关键修正点说明
- 自然日判断:通过扩展提取日期部分,确保只要跨天就触发重置,不受具体时分秒影响。
- 异步写入等待:用
Future.wait批量处理SharedPreferences的异步操作,保证数据持久化完成后再更新UI。 - 同步内存变量:重置后直接修改
HOME类的全局变量,确保UI显示最新值。 - 时间戳更新:重置完成后更新存储的时间戳,避免下次启动重复执行重置逻辑。
- 空安全处理:读取SharedPreferences时添加
??默认值,避免空指针异常。
内容的提问来源于stack exchange,提问作者GUN10010
相关产品推荐
相关产品推荐

