TypedDate

Language:Swift License:MIT Latest Release Twitter

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 创建 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 的转换

要从 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

使用 TypedDateOf〇〇 别名简化 TypedDate

该库包含以下类型别名

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 协议,这使其比传统的日期处理更加强大和方便

Comparable 和 Equatable

这些协议允许轻松比较 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

Codable 一致性意味着 TypedDate 实例可以轻松编码为和解码为各种格式,例如 JSON。 这在处理 API 或将日期保存到持久性存储时特别有用。

安装

.package(url: "https://github.com/Ryu0118/swift-typed-date", exact: "0.6.0")