在 Swift (iOS/macOS) 中处理日期:库概览
在 iOS 和 macOS 开发中,处理日期和时间是一项关键任务。标准 Foundation 框架提供了强大但有时略显繁琐的工具。为了简化代码并提高可读性,开发者经常使用第三方库。本文将介绍 Swift 的原生功能 (Foundation) 以及两个流行的库:SwiftDate 和 DateTools。
1. Foundation:内置功能
Foundation 的基本工具集包括 Date、DateFormatter、Calendar 和 TimeZone。这对于大多数任务来说已经足够,但需要编写冗长的代码。
示例:创建和格式化日期
import Foundation
let now = Date()let formatter = DateFormatter()formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"formatter.timeZone = TimeZone(abbreviation: "UTC")let dateString = formatter.string(from: now)print(dateString) // 2025-04-01 14:30:00示例:计算日期之间的差值
let startDate = Date()let endDate = Calendar.current.date(byAdding: .day, value: 7, to: startDate)!let components = Calendar.current.dateComponents([.day, .hour], from: startDate, to: endDate)print("\\(components.day!) 天, \\(components.hour!) 小时")Foundation 优点:无依赖、完全可控、支持所有时区和历法。
缺点:简单操作需要大量代码,本地化和相对日期处理复杂。
2. SwiftDate — 强大且灵活的库
SwiftDate 是 Swift 中最流行的日期处理库之一。它扩展了 Foundation 的功能,添加了用于解析、格式化、操作和时区处理的便捷方法。
安装 (Swift Package Manager)
// Package.swiftdependencies: [ .package(url: "https://github.com/malcommac/SwiftDate.git", from: "6.3.0")]示例:从字符串创建日期
import SwiftDate
let date = "2025-04-01T14:30:00+0000".toDate()print(date?.toFormat("dd.MM.yyyy HH:mm")) // 01.04.2025 14:30示例:相对日期和时间间隔
let now = Date()let oneWeekAgo = now - 1.weeksprint(oneWeekAgo.toRelative()) // "1 week ago"
let nextMonth = now + 1.monthsprint(nextMonth.toFormat("MMMM yyyy")) // May 2025示例:时区处理
let parisDate = DateInRegion(Date(), region: .init(calendar: Calendars.gregorian, zone: Zones.europeParis, locale: Locales.french))print(parisDate.toFormat("HH:mm")) // 巴黎时间SwiftDate 优点:语法简洁、内置支持相对日期、区域和语言环境、强大的解析功能。
缺点:库体积较大 (~2 MB),对于简单项目可能过于臃肿。
3. DateTools — 简单易读
DateTools 是一个轻量级库,专注于代码的可读性。它为 Date 添加了用于快速计算时间间隔、比较和格式化的方法。
安装 (CocoaPods)
pod 'DateToolsSwift'示例:检查时间间隔
import DateToolsSwift
let date1 = Date()let date2 = date1 + 2.hoursprint(date2.isToday) // trueprint(date1.earlierDate(date2) == date1) // true示例:人类可读的字符串
let pastDate = Date() - 3.daysprint(pastDate.timeAgoSinceNow) // "3 days ago"
let futureDate = Date() + 1.weeksprint(futureDate.timeAgoSinceNow) // "in 1 w