swift 日期与时间的三个结构体

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 在线编辑器 | 公众号内容排版工具」 排版

相关推荐
Jerry19 分钟前
Compose 基础知识测试
前端
changuncle28 分钟前
Angular初学者入门第三课——工厂函数(精品)
前端·javascript·angular.js
ScottePerk1 小时前
前端安全之XSS和CSRF
前端·安全·xss
PineappleCoder1 小时前
Canvas 复杂交互步骤:从事件监听 to 重新绘制全流程
前端
s3xysteak1 小时前
我要成为vue高手01:上下文
前端·javascript·vue.js
复苏季风1 小时前
前端居中布局:从 "卡壳" 到 "精通" 的全方位指南
前端·css
qb1 小时前
vue3.5.18源码:computed 在发布订阅者模式中的双重角色
前端·vue.js·架构
专注VB编程开发20年1 小时前
c# .net支持 NativeAOT 或 Trimming 的库是什么原理
前端·javascript·c#·.net
挽淚1 小时前
前端HTTP请求:Fetch api和Axios
前端
乘风丿1 小时前
🚀 从零构建 AI 代码审查机器人:让 GitLab 自动审查代码质量
前端