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

为何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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:33:24