DateComponents
在 swift 中,DateComponents 结构体表示的是日期时间的组成部分,比如年、月、日、小时、分钟等。你可以根据需要选择性的设置字段(例如,只设置年月日、忽略时间等)。
它符合以下协议:
- Hashable:支持哈希操作,用于存储在 Set 或作为字典的键。
- Equatable:支持比较两个 DateComponents 是否相等。
- Sendable:支持多线程安全传递(在并发编程中很有用
这是它的初始化方法:
swift
public init(calendar: Calendar? = nil, timeZone: TimeZone? = nil, era: Int? = nil, year: Int? = nil, month: Int? = nil, day: Int? = nil, hour: Int? = nil, minute: Int? = nil, second: Int? = nil, nanosecond: Int? = nil, weekday: Int? = nil, weekdayOrdinal: Int? = nil, quarter: Int? = nil, weekOfMonth: Int? = nil, weekOfYear: Int? = nil, yearForWeekOfYear: Int? = nil)
各个字段说明如下:
字段 | 描述 |
---|---|
calendar |
使用的日历(如公历、农历等) |
timeZone |
时区 |
era |
纪元(如公历纪元、佛历纪元等) |
year |
年份 |
month |
月份 |
day |
天数 |
hour |
小时 |
minute |
分钟 |
second |
秒 |
nanosecond |
纳秒 |
weekday |
星期几(1=周日,2=周一等) |
weekdayOrdinal |
周几的顺序(如第二个周五) |
quarter |
季度(1、2、3、4) |
weekOfMonth |
月中的第几周 |
weekOfYear |
年中的第几周 |
dayOfYear |
一年中的第几天(如 1 到 365 或 366) |
yearForWeekOfYear |
ISO 8601 周编号年份 |
isLeapMonth |
是否为闰月 |
你可以传入一些参数来构建时间,如果不传入就是nil,默认使用系统的时间参数,下面是示例:
ini
let components = DateComponents(year: 2025, month: 7, day: 28, hour: 15)
let calendar = Calendar.current
let date = calendar.date(from: components)
calendar 参数是一个 Calendar 类型,表示使用哪种日历系统。 使用方法如下:
scss
let calendar = Calendar(identifier: .republicOfChina) // 创建 Republic of China 日历
let currentDate = DateComponents(calendar: calendar)
它还包括验证某个日期组成是不是有效的方法:
ini
let components = DateComponents(year: 2025, month: 2, day: 30)
let isValid = components.isValidDate(in: Calendar.current)
一个验证两个日期组成是不是相等的方法,
ini
import Foundation
var a = DateComponents()
a.year = 2025
a.month = 7
a.day = 28
var b = DateComponents()
b.year = 2025
b.month = 7
b.day = 28
print(a == b) // 输出 true
一个往DateComponents中加入日期组成和一个提取出日期组成的方法 示例如下:
scss
var components = DateComponents()
components.setValue(2025, for: .year)
components.setValue(7, for: .month)
components.setValue(28, for: .day)
csharp
let year = components.value(for: .year) // 返回 Optional(2025)
Calendar 结构体
这个结构体是swift处理时间和日期的核心工具,基于底层的 NSCalendar,支持多种历法(如公历、佛历、伊斯兰历等)。
下面是它的初始化函数,,需要传入一个历法参数。
swift
/// Returns a new Calendar.
///
/// - parameter identifier: The kind of calendar to use.
public init(identifier: Calendar.Identifier)
示例:
ini
let gregorian = Calendar(identifier: .gregorian)
let chinese = Calendar(identifier: .chinese)
它有提取日期时间组成的方法:
例如:
swift
func dateComponents(_:from:) -> DateComponents
func component(_:from:) -> Int
示例:
ini
let now = Date()
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.year, .month, .day], from: now)
// 或
let year = calendar.component(.year, from: now)
下面是它所有的方法汇总:
方法签名 | 作用 | 返回类型 | 是否支持自定义 TimeZone |
---|---|---|---|
func date(from: DateComponents) -> Date? |
用日期组件构建 Date |
Date? |
✅(通过 DateComponents.timeZone ) |
func dateComponents(_ comps: Set<Calendar.Component>, from: Date) -> DateComponents |
提取单个日期的组成部分 | DateComponents |
✅(使用 Calendar.timeZone ) |
func dateComponents(_ comps: Set<Calendar.Component>, from: Date, to: Date) -> DateComponents |
计算两个日期之间的差值 | DateComponents |
✅(使用 Calendar.timeZone ) |
func dateComponents(in: TimeZone, from: Date) -> DateComponents |
用指定时区提取日期组件 | DateComponents |
✅(显式参数) |
func component(_ component: Calendar.Component, from: Date) -> Int |
提取单个时间单位 | Int |
✅ |
func isDate(_ date1: Date, equalTo: Date, toGranularity: Calendar.Component) -> Bool |
判断两个日期在某个单位是否相等 | Bool |
✅ |
func isDateInToday(_ date: Date) -> Bool |
是否是今天 | Bool |
✅ |
func isDateInTomorrow(_ date: Date) -> Bool |
是否是明天 | Bool |
✅ |
func isDateInYesterday(_ date: Date) -> Bool |
是否是昨天 | Bool |
✅ |
func isDateInWeekend(_ date: Date) -> Bool |
是否在周末 | Bool |
✅ |
func nextDate(after: Date, matching: DateComponents, matchingPolicy: MatchingPolicy) -> Date? |
查找下一个匹配的日期(如下一个 10 点) | Date? |
✅ |
func date(byAdding component: Calendar.Component, value: Int, to: Date) -> Date? |
增加时间(如 +3 天) | Date? |
✅ |
func date(byAdding: DateComponents, to: Date) -> Date? |
增加多个组件(如 +3天 +2小时) | Date? |
✅ |
func startOfDay(for: Date) -> Date |
获取一天的开始 | Date |
✅ |
func range(of: Calendar.Component, in: Calendar.Component, for: Date) -> Range<Int>? |
某单位在上一级单位中的范围(如某月有几天) | Range<Int>? |
✅ |
func ordinality(of: Calendar.Component, in: Calendar.Component, for: Date) -> Int? |
获取某单位在上一级单位中的序号(如今天是本月第几天) | Int? |
✅ |
func compare(_ date1: Date, to date2: Date, toGranularity: Calendar.Component) -> ComparisonResult |
比较两个日期在某单位的大小关系 | ComparisonResult |
✅ |
方法类型分类
类别 | 方法举例 |
---|---|
创建/生成 | date(from:) , date(byAdding:) , nextDate(after:) |
提取组件 | dateComponents(...) , component(...) |
判断属性 | isDateInToday(...) , isDateInWeekend(...) |
比较关系 | isDate(_:equalTo:toGranularity:) , compare(...) |
范围信息 | range(of:in:for:) , ordinality(of:in:for:) |
日期转字符串
如果您有一个 Date 对象,您可能需要以一种用户友好的格式显示它。值得庆幸的是,Swift 提供了多种将日期格式化为字符串的方法,允许您根据特定需求定制输出,例如 2023 年 11 月 1 日或 2023 年 11 月 1 日。
您可以使用 DateFormatter 类将日期转换为字符串表示形式:
ini
// Change the date format
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let formattedDate = dateFormatter.string(from: currentDate)
print(formattedDate)
Date 结构体
Date 表示从参考点(2001-01-01 00:00:00 UTC)起经过的秒数
它与calendar的区别是:
它表示一个精确的时间点(绝对时间),而 Calendar 是用来解释和操作这个时间点的工具,它将 Date 映射为"人类可读"的时间单位(年、月、日、时、分等),考虑时区和历法差异。
本文使用 「Markdown 在线编辑器 | 公众号内容排版工具」 排版