Swift日期组件DateComponents
Swift日期组件DateComponents

Swift日期组件DateComponents

DateComponents 是 Foundation 框架中的一个结构体,用于表示一个或多个日期和时间的组成部分(比如年、月、日、小时、分钟等)。它常与 Calendar 和 Date 配合使用,以便对日期和时间进行创建、提取、比较和计算。

基本用法

1、空组件初始化

var components = DateComponents()
dc.year = 2025
dc.month = 12
dc.day = 8

2、指定字段初始化

let components = DateComponents(year: 2024, month: 12, day: 14, hour: 10, minute: 30)

常用属性

1、isValidDate

判断是否能组成日期

var dc = DateComponents(year: 2024, month: 2, day: 30)
dc.calendar = Calendar.current

print(dc.isValidDate)   // false

注:判断依据实际上是根据calendar来判断的,如果有calendar,可以组成日期(默认值为0001-01-01 00:00:00 +0000)。

2、isLeapMonth

判断是否为闰月,只在某些历法中返回true。

print(dc.isLeapMonth)   // false

常用方法

1、date()

使用calendar组合成Date。

var dc = DateComponents()
dc.year = 2024
dc.month = 1
dc.day = 1
dc.calendar = Calendar.current

let d = dc.date()       // 转换成 Date?

2、isValidDate(in:)

传入自定义Calendar。

dc.isValidDate(in: Calendar(identifier: .gregorian))

配合Calendar使用

1、创建日期

通过 DateComponents 创建一个指定的日期,例如生日、事件日期等。

let calendar = Calendar.current
let components = DateComponents(year: 2024, month: 12, day: 14, hour: 10, minute: 30)

if let date = calendar.date(from: components) {
    print(date) // 转换成功后的具体日期
}

2、提取时间部分

从 Date 中只提取时间部分(时分秒),并忽略日期。

let now = Date()
let timeComponents = Calendar.current.dateComponents([.hour, .minute, .second], from: now)

if let hour = timeComponents.hour, let minute = timeComponents.minute {
    print("Current time: \(hour):\(minute)")
}

3、计算日期间的差异

通过 Calendar 的 dateComponents(_:from:to:) 方法,可以计算两个日期之间的差异,返回一个 DateComponents。

let calendar = Calendar.current
let startDate = Date()
let endDate = calendar.date(byAdding: .day, value: 5, to: startDate)!

let difference = calendar.dateComponents([.day, .hour], from: startDate, to: endDate)
print("Difference: \(difference.day ?? 0) days, \(difference.hour ?? 0) hours")

4、加减日期

通过 Calendar 的 date(byAdding:to:) 方法,可以使用 DateComponents 调整日期。

例如,月份+1:

let next = Calendar.current.date(byAdding: DateComponents(month: 1), to: Date())

注意事项

1、不完整的 DateComponents

DateComponents 可能包含部分组件(比如只有 year 和 month),在使用时需确保其包含的字段是完整且有效的,否则使用默认值(0001-01-01 00:00:00 +0000)。

如果缺失calendar,则无法正常使用date()方法创建日期。

2、与时区相关

如果使用 DateComponents 创建 Date,它会使用当前 Calendar 的时区。如果需要自定义时区,需提前设置 Calendar 的 timeZone。

var calendar: Calendar {
    var c = Calendar.current
    c.timeZone = TimeZone(identifier: "UTC")!
    return c
}

总结

DateComponents 可以表示不完整的时间信息,比如 “2024 年”、“6 月” 或 “某一天的 14 点”。

因为Date 表示具体的时间点,但它本身无法直接操作年、月、日等组件。使用DateComponents,可以构建一个特定的时间,用于创建、提取、比较和计算日期与时间。

它与 Calendar 和 Date 紧密结合,通常用于构造日期、解析日期、加减日期。

DateComponents需要借助Calendar生成日期,例如date()方法的内部使用的是:

returnedDate = calendar.date(from: self)

默认使用的是:

Calendar.current

也就是说,调用DateComponents的date()方法,等同于:

Calendar.current.date(from: components)

DateComponents只负责存储字段,解析日期、拆解日期、组合日期等工作都需要Calendar实现。

相关文章

1、Swift Date时间:https://fangjunyu.com/2024/12/14/swift-date%e7%b1%bb%e5%9e%8b%e7%9a%84%e5%b8%b8%e7%94%a8%e6%96%b9%e6%b3%95%e5%92%8c%e5%b1%9e%e6%80%a7%e5%88%86%e6%9e%90/

2、Swift日期时间类Calendar:https://fangjunyu.com/2024/12/14/swift%e6%97%a5%e6%9c%9f%e6%97%b6%e9%97%b4%e7%b1%bbcalendar/

扩展知识

1、DateComponents结构体

Swift定义了唯一的指定初始化器:

struct DateComponents {

    // MARK: Core fields (Optional Int)
    var era: Int?
    var year: Int?
    var month: Int?
    var day: Int?
    var hour: Int?
    var minute: Int?
    var second: Int?
    var nanosecond: Int?

    // MARK: Week-based fields
    var weekday: Int?
    var weekdayOrdinal: Int?
    var weekOfMonth: Int?
    var weekOfYear: Int?
    var yearForWeekOfYear: Int?

    // MARK: Extra
    var quarter: Int?

    // MARK: Locale and calendar context
    var calendar: Calendar?
    var timeZone: TimeZone?

    // MARK: Computed info
    var isLeapMonth: Bool?
    var isValidDate: Bool { get }  
    var isValidDate(in: Calendar) -> Bool

    // MARK: Duration conversion
    func date() -> Date?        // 需要 calendar 字段非空
}

字段解析

1、era:纪元编号,0表示公元前(BC),1表示公元(AD),特殊历法(日本历法、印度历法的era则不同)。

2、year、month、day、hour、minute、second、nanosecond:年、月、日、时、分、秒和钠秒,1秒=10亿纳秒。

3、weekday:星期几(1=星期日,2=星期一,以此类推,取决于Calendar.firstWeekday),范围1-7。

4、weekdayOrdinal:当月的第几个某星期,第二个星期三。

5、weekOfMonth:月内的第几周,范围:1-5。

6、weekOfYear:年内的第几周,范围1-53。

7、yearForWeekOfYear:ISO 周历使用,常用于国际周号。

8、quarter:季度,对应四个季度,范围1-4。

9、calendar:日历,对应gregorian、iso8601等日历,没有calendar无法使用date()、isValidDate。

10、timeZone:时区,例如UTC。

11、isLeapMonth:是否为闰月(农历十月),只在某些历法中返回true。

12、isValidDate:根据Calendar判断是否为有效日期。

13、isValidDate(in:):传入自定义Calendar。

14、date():使用calendar组合成Date。

注意事项:weekdayOrdinal和weekOfMonth的区别在于weekdayOrdinal是按第一个周来计算的(包括前面的空格),weekOfMonth则按照完整的周进行计算。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注