Swift:生成指定时段(9am-11pm/当前至11pm)日期数组的问题
我来帮你搞定这两个时间数组的需求,直接上代码和清晰的解释,让你一目了然~
需求一:获取当日9am至11pm的所有小时日期数组
要精准拿到当天从早上9点到晚上11点的每一个整点日期,我们可以基于当天的起始时刻,逐个设置小时数来生成对应的Date,这种方式比直接累加小时更稳妥,能避免跨天或时区带来的问题:
let today9amTo11pm: [Date] = { let calendar = Calendar.current // 先拿到当天的起始时刻(比如今天00:00:00) guard let todayStart = calendar.startOfDay(for: Date()) else { return [] } // 9am对应小时9,11pm对应小时23,遍历这个区间的所有小时 return (9...23).compactMap { hour in // 给当天起始时刻设置对应的小时、分、秒,生成整点日期 calendar.date(bySettingHour: hour, minute: 0, second: 0, of: todayStart) } }()
需求二:获取从当前小时到当日11pm的剩余小时日期数组
这个需求需要先拿到当前的小时数,再从当前小时开始遍历到23点,生成对应的整点日期。这里还可以加个小判断,确保不会出现早于9am的时间(如果业务需要的话):
let remainingHoursUntil11pm: [Date] = { let calendar = Calendar.current let now = Date() // 拿到当天起始时刻和当前小时数 guard let todayStart = calendar.startOfDay(for: now), let currentHour = calendar.component(.hour, from: now) else { return [] } // 起始小时:如果需要确保不早于9am,就用max(currentHour, 9),否则直接用currentHour let startHour = max(currentHour, 9) let endHour = 23 // 11pm对应的小时数 // 如果当前小时已经超过23点(理论上不会发生,但做个判断更安全),返回空数组 guard startHour <= endHour else { return [] } // 遍历从起始小时到23点的所有小时,生成对应日期 return (startHour...endHour).compactMap { hour in calendar.date(bySettingHour: hour, minute: 0, second: 0, of: todayStart) } }()
为什么你原来的代码不符合需求?
你之前用(0..<14).forEach是从当前时间往后累加0到13小时,这会有三个明显问题:
- 如果当前时间早于9am,生成的数组会包含9am之前的时间(比如当前是8点,加0小时就是8点);
- 如果当前时间晚于9am但加14小时后跨天了(比如当前是下午2点,加14小时是第二天凌晨4点),就会混入第二天的时间;
- 而且没法保证一定会覆盖到23点(比如当前是中午12点,加14小时是凌晨2点,漏掉了23点)。
而上面的方法是基于当天的起始日期来设置小时数,所有生成的日期都是当天的,且严格落在9am-11pm的范围内。
内容的提问来源于stack exchange,提问作者user1889692
相关产品推荐
相关产品推荐

