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

Flutter中Dart日期差函数失效,SharedPreferences变量未重置求助

问题排查与解决方案

核心问题分析

你的代码存在3个关键问题导致变量无法重置:

  1. daysPassed函数判断逻辑错误:DateTime.difference().inDays是按连续24小时间隔计算,而非自然日(比如昨天23:00到今天22:00,间隔不足24小时,inDays返回0,但实际已跨天)。
  2. 重置后未同步内存变量:修改SharedPreferences后,没有更新HOME类中的全局变量,导致UI依然显示旧值。
  3. 未更新判断用的时间戳:重置操作完成后,没有更新存储的day_timestamp_values_changed,下次启动会重复触发重置或一直用旧时间戳判断。
  4. 异步写入未等待: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:10:35