TypedDate 是 Swift Date 的一个包装器,它在类型层面增强了日期处理能力。 它能够构建自定义的日期结构,范围从诸如年份之类的单个组件到年份、月份、日期、时间等组合,以满足特定的开发需求。
TypedDate 的主要特性包括
要初始化 TypedDate,您可以使用以下语法
import TypedDate
TypedDate(Year(2023), Month(11), Day(12))
TypedDate(Year(2023), Month(11), Day(12), calendar: Calendar(identifier: .gregorian))
TypedDate(Year(2023), Month(11), Day(12), Hour(11), Minute(12), Second(1), Nanosecond(10000000))
TypedDate(Year(2023), Month(11), Day(12), Hour(11), Minute(12), FractionalSecond(5.12))
这将创建一个表示日期 2023/11/12 的 TypedDate 实例。
Date 具有以下可用组件:年、月、日、小时、分钟、秒和纳秒。
要从 Date 创建 TypedDate,请使用 Date.scope(to:calendar:)
。
let typedDate1: TypedDate<(Year, Month)> = Date().scope(to: \.month)
let typedDate2: TypedDate<(Year, Month, Day, Hour)> = Date().scope(to: \.hour)
let typedDate3: TypedDate<(Year, Month, Day, Hour, Minute)> = Date().scope(to: \.minute, calendar: Calendar(identifier: .gregorian))
let typedDate4: TypedDateOfYear = Date().scope(to: \.year)
let typedDate5: TypedDateOfDay = Date().scope(to: \.day)
要从 TypedDate 转换为 Date,请使用 date 属性。
typedDate.date // Date
fill 方法允许您填充日期的特定部分。 例如
let typedDate = TypedDate(Year(2023), Month(11), Day(12))
// typedDate: TypedDate<(Year, Month, Day)>
typedDate.fill(
to: \.second,
arguments: (Hour(11), Minute(12), Second(10))
)
// TypedDate<(Year, Month, Day, Hour, Minute, Second)>
typedDate.fill(
to: \.hour,
arguments: (Hour(11)),
calendar: Calendar(identifier: .gregorian)
)
// TypedDate<(Year, Month, Day, Hour)>
在此示例中,filledDate 将表示日期 2023/11/12 11:12
erase 方法允许您擦除日期的特定部分。 例如
let date = TypedDate(Year(2023), Month(11), Day(12), Hour(11), Minute(12))
let erasedDate1: TypedDate<(Year, Month, Day)> = date.erase(to: \.day)
let erasedDate2: TypedDate<(Year, Month)> = date.erase(to: \.month)
let erasedDate2: TypedDate<(Year)> = date.erase(to: \.year, calendar: Calendar(identifier: .gregorian)
在此示例中,erasedDate 将被擦除到 keyPath 中指定的日期。
modify 方法允许您修改日期的特定部分。 例如
let typedDate = TypedDate(Year(2023), Month(11), Day(12), Hour(11), Minute(12))
// typedDate: 2023/11/12 11:12
let modifiedDate = typedDate.modifying(\.year) { $0 += 1 }
.modifying(\.month) { $0 -= 2 }
.modifying(\.day) { $0 += 3 }
.modifying(\.hour) { $0 += 4 }
.modifying(\.minute) { $0 += 5 }
.add(\.year, 1)
.add(\.month, -2)
.add(\.day, 3)
.add(\.hour, -2)
.add(\.minute, -3)
// modifiedDate: 2025/07/18 13:14
或者使用 TypedDate.modify(_:calendar:modify:)
方法
var typedDate = TypedDate(Year(2023), Month(11))
typedDate.modify(\.year) { $0 += 1 }
// typedDate: 2024/11
let typedDate = TypedDate(Year(2023), Month(11), Day(12), Hour(11), Minute(12), Second(1), Nanosecond(10000000))
typedDate.year() // 2023
typedDate.month(calendar: Calendar(identifier: .gregorian)) // 11
typedDate.day() // 12
typedDate.hour(calendar: Calendar(identifier: .gregorian)) // 11
typedDate.minute() // 12
typedDate.second(calendar: Calendar(identifier: .gregorian) // 1
typedDate.nanosecond() // 10000000
该库包含以下类型别名
public typealias TypedDateOfYear = TypedDate<Year>
public typealias TypedDateOfMonth = TypedDate<(Year, Month)>
public typealias TypedDateOfDay = TypedDate<(Year, Month, Day)>
public typealias TypedDateOfHour = TypedDate<(Year, Month, Day, Hour)>
public typealias TypedDateOfMinute = TypedDate<(Year, Month, Day, Hour, Minute)>
public typealias TypedDateOfSecond = TypedDate<(Year, Month, Day, Hour, Minute, Second)>
public typealias TypedDateOfNanosecond = TypedDate<(Year, Month, Day, Hour, Minute, Second, Nanosecond)>
TypedDate 符合 Comparable、Equatable、Hashable 和 Codable 协议,这使其比传统的日期处理更加强大和方便
这些协议允许轻松比较 TypedDate 实例。 您可以使用标准比较运算符(==、<、> 等)检查一个日期是否等于、小于或大于另一个日期。 这比比较单个日期组件更直观,更不容易出错。
let date1: Date // 2023/11/12
let date2: Date // 2023/11/11
// To check the date have the same year
date1.scope(to: \.year) == date2.scope(to: \.year) // -> true
// To check the date have the same year, month, and day
date1.scope(to: \.day) == date2.scope(to: \.day) // -> false
// Compare days
date1.scope(to: \.day) > date2.scope(to: \.day) // -> true
Codable 一致性意味着 TypedDate 实例可以轻松编码为和解码为各种格式,例如 JSON。 这在处理 API 或将日期保存到持久性存储时特别有用。
.package(url: "https://github.com/Ryu0118/swift-typed-date", exact: "0.6.0")