为何DateComponents生成日期时错误组件不返回nil?如何校验?
解决DateComponents无效日期自动调整的问题
默认情况下,Calendar.current.date(from:)会自动调整无效的日期组件(比如2023年2月31日会被转为2023年3月3日),如果要让这种无效日期返回nil,没有直接的配置参数,需要手动验证,以下是两种可行方案:
方案一:对比生成前后的日期组件
生成日期后,将其转回DateComponents,对比关键字段是否与原组件一致,若不一致说明日期被自动调整过,返回nil:
private var date: Date? { let components = DateComponents( year: 2023, month: 2, day: 31, hour: 11, minute: 14 ) guard let generatedDate = Calendar.current.date(from: components) else { return nil } let reversedComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: generatedDate) guard reversedComponents.year == components.year, reversedComponents.month == components.month, reversedComponents.day == components.day, reversedComponents.hour == components.hour, reversedComponents.minute == components.minute else { return nil } return generatedDate }
方案二:提前验证天数是否在当月范围内
先获取指定年月的有效天数范围,判断输入的天数是否在范围内,再决定是否生成日期:
private var date: Date? { let components = DateComponents( year: 2023, month: 2, day: 31, hour: 11, minute: 14 ) guard let year = components.year, let month = components.month, let day = components.day, let monthDate = Calendar.current.date(from: DateComponents(year: year, month: month)), let dayRange = Calendar.current.range(of: .day, in: .month, for: monthDate) else { return nil } return dayRange.contains(day) ? Calendar.current.date(from: components) : nil }
两种方案都能实现需求,方案一逻辑更通用(能覆盖所有组件的无效调整,比如月份13的情况),方案二则更直接针对天数的验证。
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

