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

Dart/Flutter每月服务使用校验逻辑代码故障排查求助

问题描述

我有两项数据:

  • usage count(使用次数)
  • last used date(最后使用日期)

需求是判断用户是否每月使用过一次服务:若用户当月已使用该服务一次,返回false;否则返回true。

以下是我编写的Dart代码,但无法正常运行:

bool checkValidity( int usageCount,DateTime lastUsed){
      int differenceInMonths =
          (lastUsed.difference(DateTime.now()).inDays / 30).floor();
  print('no of usage : $usageCount, past months : $differenceInMonths');
      return differenceInMonths >= usageCount ? false: true;
}

void main() {
   print(checkValidity(1,DateTime.now().add(Duration(days:28))));
   print(checkValidity(1,DateTime.now().add(Duration(days:29))));
   print(checkValidity(1,DateTime.now().add(Duration(days:30))));
   print(checkValidity(1,DateTime.now().add(Duration(days:31))));
   print(checkValidity(1,DateTime.now().add(Duration(days:60))));
   print(checkValidity(2,DateTime.now().add(Duration(days:59))));
   print(checkValidity(2,DateTime.now().add(Duration(days:60))));
   print(checkValidity(2,DateTime.now().add(Duration(days:61))));
}
代码问题分析
  1. 日期差计算方向错误:
    lastUsed.difference(DateTime.now())会在lastUsed是未来时间时返回正数,但实际我们需要计算当前时间与最后使用时间的间隔,应该用DateTime.now().difference(lastUsed),这样过去的时间返回正数,未来时间返回负数。

  2. 月份差计算不准确:
    用天数/30取整计算月份差非常粗糙,不同月份天数不同(比如2月28天、3月31天),会导致月份判断错误。正确的方式是通过年份和月份的差值计算准确的月份数。

  3. 逻辑判断与需求不匹配:
    原代码的返回逻辑differenceInMonths >= usageCount ? false : true完全不符合需求,没有正确关联“当月是否使用”的判断逻辑。

修正后的代码

如果你的核心需求是判断当月是否未使用服务(用过返回false,没用到返回true),可以使用简化版代码:

bool checkValidity(int usageCount, DateTime lastUsed) {
  final now = DateTime.now();
  // 判断最后使用日期是否在当前月份
  final isSameMonth = now.year == lastUsed.year && now.month == lastUsed.month;
  // 当月已使用返回false,否则返回true
  return !isSameMonth;
}

void main() {
  print(checkValidity(1, DateTime.now().add(Duration(days:28)))); // 当月内使用,返回false
  print(checkValidity(1, DateTime.now().add(Duration(days:29)))); // 当月内使用,返回false
  print(checkValidity(1, DateTime.now().add(Duration(days:30)))); // 跨月,返回true
  print(checkValidity(1, DateTime.now().add(Duration(days:31)))); // 跨月,返回true
  print(checkValidity(1, DateTime.now().add(Duration(days:60)))); // 间隔2个月,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:59)))); // 当月未使用,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:60)))); // 跨月,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:61)))); // 跨月,返回true
}

如果需要同时验证是否满足每月使用一次的历史要求(即使用次数覆盖所有应使用的月份),可以使用完整版代码:

bool checkValidity(int usageCount, DateTime lastUsed) {
  final now = DateTime.now();
  // 计算从最后使用日期到当前日期的准确月份差
  final monthsPassed = (now.year - lastUsed.year) * 12 + (now.month - lastUsed.month);
  
  // 判断当月是否已使用:最后使用日期在当前月或未来
  final usedThisMonth = monthsPassed <= 0;
  
  // 验证是否有遗漏的使用月份:使用次数小于已过的月份数
  final hasMissingMonths = monthsPassed >= usageCount;
  
  // 需求:当月已使用则返回false;若有遗漏月份或当月未使用,返回true
  return usedThisMonth ? false : hasMissingMonths;
}

void main() {
  print(checkValidity(1, DateTime.now().add(Duration(days:28)))); // 当月内使用,返回false
  print(checkValidity(1, DateTime.now().add(Duration(days:29)))); // 当月内使用,返回false
  print(checkValidity(1, DateTime.now().add(Duration(days:30)))); // 跨月且遗漏当月,返回true
  print(checkValidity(1, DateTime.now().add(Duration(days:31)))); // 跨月且遗漏当月,返回true
  print(checkValidity(1, DateTime.now().add(Duration(days:60)))); // 间隔2个月,遗漏月份,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:59)))); // 间隔1个月,遗漏当月,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:60)))); // 间隔2个月,遗漏月份,返回true
  print(checkValidity(2, DateTime.now().add(Duration(days:61)))); // 间隔2个月以上,遗漏月份,返回true
}

内容的提问来源于stack exchange,提问作者Abhishek Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:17:04