如何计算两个日期的完成进度百分比?
解决日期区间进度百分比计算(适配Swift贝塞尔路径绘制)
我来帮你搞定这个日期进度的计算问题,刚好能完美适配你用贝塞尔路径画进度圈的需求~
核心逻辑梳理
首先咱们明确计算规则:
- 总进度周期是 date2 - date1 的自然天数
- 当前日期早于date1时,进度为0%;追平date2时,进度100%
- 日期处于两者之间时,进度 = (当前日期与date1的天数差) / 总周期天数 * 100%
修正后的Swift代码实现
你之前的代码用了固定20天的硬编码,不够灵活,这里给你改成动态计算日期差的版本,还做了边界容错:
let calendar = Calendar.current let startDate = date1 // 你的起始日期变量 let endDate = date2 // 你的结束日期变量 // 1. 计算总周期天数(确保endDate不早于startDate,避免负数) guard let totalDays = calendar.dateComponents([.day], from: startDate, to: endDate).day, totalDays > 0 else { // 日期无效时的容错:如果endDate >= startDate直接返回100%,否则返回0% let percentFull = endDate >= startDate ? 1.0 : 0.0 // 这里可以继续你的贝塞尔路径绘制逻辑 return } // 2. 计算当前日期到起始日期的已过天数 let currentDate = Date() guard let elapsedDays = calendar.dateComponents([.day], from: startDate, to: currentDate).day else { // 无法获取天数差时默认进度0% let percentFull = 0.0 // 继续绘制逻辑 return } // 3. 计算进度百分比,自动限制在0~1之间(适配当前日期超出区间的情况) let percentFull = max(0.0, min(Double(elapsedDays) / Double(totalDays), 1.0))
关键细节说明
- 用
Calendar计算日期差:比直接用时间戳更准确,能自动处理时区、闰年、不同月份天数差异等问题 - 可选值安全处理:用
guard解包dateComponents返回的可选值,避免强制解包导致崩溃 - 边界值限制:通过
max和min把进度牢牢锁在0到1之间,哪怕当前日期还没到startDate,或者已经超过endDate,都不会出现异常进度
贝塞尔路径适配提示
拿到percentFull后,你可以直接用它来控制圆弧的绘制范围:
比如绘制一个从顶部开始的顺时针进度圈,结束角度可以这么计算:
let startAngle = -CGFloat.pi / 2 // 顶部为起始点 let endAngle = startAngle + CGFloat(percentFull) * 2 * .pi // 用这两个角度创建贝塞尔圆弧路径即可
内容的提问来源于stack exchange,提问作者tloz1506996
相关产品推荐
相关产品推荐

