Foundation — Calendar
This article is extracted from the chat log with AI. Please identify it with caution.

Calendar 介绍 #


一、Calendar 核心 API 分类表 #

分类API / 方法说明
静态属性Calendar.current用户当前设置的日历(跟随系统设置,但不自动更新)
Calendar.autoupdatingCurrent自动更新时区/本地化设置的当前日历(动态变化)
Calendar.iso8601ISO 8601 标准日历(固定为公历,周一为每周第一天)
初始化init(identifier: Calendar.Identifier)通过标识符创建(如 .gregorian, .chinese, .islamic
日历标识符var identifier: Calendar.Identifier获取日历类型(只读)
时区与区域var timeZone: TimeZone设置或获取日历的时区
var locale: Locale?设置或获取本地化规则(影响符号和星期起始日)
日期分解与合成func component(_ component: Component, from date: Date) -> Int提取单个日期单位(如年、月)
func dateComponents(_ components: Set<Component>, from date: Date) -> DateComponents提取多个日期单位
func date(from components: DateComponents) -> Date?DateComponents 生成日期
日期生成与调整func date(byAdding component: Component, value: Int, to date: Date) -> Date?日期加减(如加 3 天)
func date(bySetting component: Component, value: Int, of date: Date) -> Date?设置日期的某个单位(如将小时设为 0)
func startOfDay(for date: Date) -> Date返回日期的午夜时间(当日开始时刻)
日期比较与查询func isDate(_ date1: Date, inSameDayAs date2: Date) -> Bool判断是否为同一天
func isDateInToday(_ date: Date) -> Bool是否为今天
func isDateInWeekend(_ date: Date) -> Bool是否为周末
func compare(_ date1: Date, to date2: Date, toGranularity: Component) -> ComparisonResult按粒度比较日期顺序(如是否同年)
日期范围与周期func dateInterval(of component: Component, for date: Date) -> DateInterval?获取日期所在周期(如当天的起止时间)
func range(of smaller: Component, in larger: Component, for date: Date) -> Range<Int>?获取某单位在更大单位内的范围(如某月的天数)
func enumerateDates(startingAfter start: Date, matching components: DateComponents, matchingPolicy: MatchingPolicy, using block: (Date?, Bool, inout Bool) -> Void)遍历符合条件的所有日期(如每月第一天)
本地化符号var weekdaySymbols: [String]星期名称(如 [“Sunday”, “Monday”, …])
var monthSymbols: [String]月份名称(如 [“January”, “February”, …])
var amSymbol: String上午符号(如 “AM”)
日历元数据var minimumDaysInFirstWeek: Int第一周至少包含的天数(通常为 1)
var firstWeekday: Int每周的第一天(1=周日,2=周一,依此类推)

二、关键静态属性与常用 API 示例 #

1. 静态属性的使用 #

// 使用当前日历(用户设置,不自动更新)
let current = Calendar.current
let year = current.component(.year, from: Date())

// 使用自动更新的当前日历(时区变化时会自动更新)
let autoCalendar = Calendar.autoupdatingCurrent

2. 日期范围与周期 #

// 获取某个月的天数范围
if let range = current.range(of: .day, in: .month, for: Date()) {
    print("本月天数: \(range.count)") // 如 30
}

// 获取今天的日期区间(开始和结束时间)
if let todayInterval = current.dateInterval(of: .day, for: Date()) {
    print("今天从 \(todayInterval.start)\(todayInterval.end)")
}

3. 日期调整与合成 #

// 将日期调整到当天的午夜
let midnight = current.startOfDay(for: Date())

// 设置日期的小时为 12
let noon = current.date(bySetting: .hour, value: 12, of: Date())

4. 本地化符号 #

// 获取中文日历的月份符号
var cnCalendar = Calendar(identifier: .chinese)
cnCalendar.locale = Locale(identifier: "zh_CN")
print(cnCalendar.monthSymbols) // ["一月", "二月", ...]

三、补充说明 #

Calendar.current vs Calendar.autoupdatingCurrent #

  • current: 获取用户当前的日历设置,但不会自动更新(应用生命周期内固定)。
  • autoupdatingCurrent: 动态跟踪系统设置的变更(如用户切换时区)。

日期组件 (Calendar.Component) #

完整枚举值包括:
.era, .year, .month, .day, .hour, .minute, .second, .weekday, .weekOfMonth, .weekOfYear, .timeZone, .calendar, 等。

日历标识符 (Calendar.Identifier) #

常见类型:

  • .gregorian(公历)
  • .japanese(和历)
  • .buddhist(佛历)
  • .islamic(伊斯兰历)
  • .chinese(农历)
  • .indian(印度历)

四、总结 #

Calendar 的核心功能覆盖了:

  • 日期解析与生成dateComponents/date(from:)
  • 动态调整与计算date(byAdding:)/startOfDay
  • 复杂周期处理enumerateDates/range(of:in:)
  • 本地化与符号控制weekdaySymbols/locale

通过 Calendar.current 或特定标识符创建的实例,可灵活适配不同地区和历法需求。

代码示例 #


一、Calendar 核心功能分类 #

分类API / 方法说明
初始化Calendar.init(identifier:)根据日历标识符(如 .gregorian, .japanese)创建实例
Calendar.autoupdatingCurrent获取系统当前日历(自动更新时区/本地化设置)
日历单位component(_:from:)获取日期中指定单位的值(如年、月、日)
dateComponents(_:from:)获取多个日期单位的值(返回 DateComponents 对象)
日期计算date(byAdding:value:to:options:)在日期上添加指定数量的时间单位(如加 1 天)
nextDate(after:matching:matchingPolicy:)找到符合指定条件的下一个日期(如每周五)
日期比较isDate(_:equalTo:toGranularity:)判断两个日期在指定粒度下是否相等(如是否是同一天)
compare(_:to:toGranularity:)比较两个日期的顺序(早于、等于、晚于)
时区与本地化timeZone (属性)设置或获取日历的时区
localizedWeekdaySymbols获取本地化的星期名称(如 [“Sunday”, “Monday”, …])
枚举日期范围enumerateDates(startingAfter:matching:matchingPolicy:using:)遍历符合指定条件的所有日期(如某个月的所有日期)
日期区间计算dateInterval(of:for:)获取日期所在时间区间的开始和结束(如某一天的范围)
日历元信息minimumRange(of:)
maximumRange(of:)
获取某个日历单位的最小/最大值范围(如月份的最小天数为 28)

二、核心 API 代码示例 #

1. 初始化日历 #

// 创建 Gregorian 日历
let gregorian = Calendar(identifier: .gregorian)

// 获取自动更新的当前日历
let currentCalendar = Calendar.autoupdatingCurrent

2. 获取日期单位 #

let date = Date()
let year = gregorian.component(.year, from: date)
let components = gregorian.dateComponents([.year, .month, .day], from: date)
print("Year: \(components.year!), Month: \(components.month!), Day: \(components.day!)")

3. 日期计算 #

// 计算明天的日期
let tomorrow = gregorian.date(byAdding: .day, value: 1, to: Date())!

// 找到下一个星期五
let nextFriday = gregorian.nextDate(
    after: Date(),
    matching: DateComponents(weekday: 6), // 1=Sunday, 6=Friday
    matchingPolicy: .nextTime
)

4. 日期比较 #

let date1 = Date()
let date2 = date1.addingTimeInterval(3600)
if gregorian.isDate(date1, equalTo: date2, toGranularity: .hour) {
    print("Same hour")
} else {
    print("Different hours")
}

5. 时区与本地化 #

var japanCalendar = Calendar(identifier: .gregorian)
japanCalendar.timeZone = TimeZone(identifier: "Asia/Tokyo")!

let weekdaySymbols = japanCalendar.localizedWeekdaySymbols
print(weekdaySymbols) // ["日曜日", "月曜日", ...]

6. 枚举日期范围 #

// 获取某个月的所有日期
var startDate: Date?
gregorian.enumerateDates(
    startingAfter: Date(),
    matching: DateComponents(day: 1, hour: 0),
    matchingPolicy: .nextTime
) { (date, _, stop) in
    guard let date = date else { return }
    if gregorian.component(.month, from: date) != 5 {
        stop = true
        return
    }
    print(date)
    startDate = date
}

三、关键参数说明 #

日历标识符(Identifier) #

  • .gregorian:公历
  • .japanese:日本历
  • .buddhist:佛历
  • .islamic:伊斯兰历

日期组件(Calendar.Component) #

  • .era, .year, .month, .day, .hour, .minute, .second, .weekday, .weekOfYear, 等。

匹配策略(MatchingPolicy) #

  • .nextTime:允许向前或向后查找
  • .previousTime:严格向后查找
  • .strict:必须精确匹配

四、总结 #

Calendar 提供了强大的日期计算和本地化能力,核心功能包括:

  1. 精确的日期分解与合成(通过 DateComponents
  2. 灵活的日期计算(支持时区和本地化)
  3. 复杂的日期匹配与遍历(如周期性事件)

使用时需注意时区设置和本地化符号的差异,避免逻辑错误。更多细节可参考 Apple 官方文档

本文共 2232 字,创建于 Mar 21, 2025
相关标签: Xcode, Foundation, ByAI