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)))); }
代码问题分析
日期差计算方向错误:
lastUsed.difference(DateTime.now())会在lastUsed是未来时间时返回正数,但实际我们需要计算当前时间与最后使用时间的间隔,应该用DateTime.now().difference(lastUsed),这样过去的时间返回正数,未来时间返回负数。月份差计算不准确:
用天数/30取整计算月份差非常粗糙,不同月份天数不同(比如2月28天、3月31天),会导致月份判断错误。正确的方式是通过年份和月份的差值计算准确的月份数。逻辑判断与需求不匹配:
原代码的返回逻辑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
相关产品推荐
相关产品推荐

