一个用 Swift 编写的节日计算器。
将以下依赖项添加到你的 Package.swift
文件中
.package(url: "https://github.com/sersoft-gmbh/swifty-holidays", from: "2.0.0"),
或者通过 Xcode 添加(从 Xcode 11 开始)。
SwiftyHolidays 基于计算器构建。计算器负责计算特定日历中给定年份的节日。目前,SwiftyHolidays 拥有一个用于公历的计算器。
SwiftyHolidays 中的所有计算都是线程安全的,并且只执行一次。这意味着即使你从两个并行线程向给定的计算器请求某个日期,它也只会计算一次,第二个线程将等待第一个线程完成其计算。某些日期(例如,除夕夜)甚至不需要计算,而是固定的日期-月份组合。必须计算的日期会被缓存,因此下次请求某个日期时,不需要进行计算,而是立即返回。尽管计算器通常是结构体,但它们具有引用语义,并且在涉及其上下文(例如,包含其缓存)时是线程安全的。这意味着你可以在多个地方使用计算器对象,并且通过仅计算一次日期,仍然可以获得相同的性能。
计算器的上下文也可以被序列化和合并。这意味着你可以创建一个计算器,使用它计算一些日期,然后将其上下文序列化到磁盘。稍后,你反序列化上下文并将其传递给一个新的计算器,该计算器将从先前计算并已缓存的日期中受益。这甚至可以跨年使用。这意味着你可以构建一个跨越多年的缓存。如果你的缓存变得太大,你可以随时清除上下文(或者简单地创建一个使用新上下文的新计算器)。
以下是一些示例
let calculator = GregorianCalculator()
// A few calculations:
let easterSunday20 = calculator.easterSunday(forYear: 2020)
// -> 2020-04-12
let firstAdvent19 = calculator.firstSundayOfAdvent(forYear: 2019)
// -> 2019-12-01
let firstAdvent20 = calculator.firstSundayOfAdvent(forYear: 2020)
// -> 2020-11-29
// Serialize context
let data = try JSONEncoder().encode(calculator.context)
let ctxPath = URL(fileURLWithPath: "/path/to/gregorian.ctx")
try data.write(to: ctxPath, options: .atomic)
// [...]
// Deserialize context
let data = try Data(contentsOf: ctxPath)
let deserializedCtx = try JSONDecoder().decode(GregorianCalculator.Context.self, from: data)
let newCalculator = GregorianCalculator()
newCalculator.initialize(with: deserializedCtx)
// -> `newCalculator` will now have cached values for the dates calculated above. So the following calls will use the cached values instead of recalculating them.
let cachedEasterSunday20 = calculator.easterSunday(forYear: 2020)
// -> 2020-04-12
let cachedFirstAdvent19 = calculator.firstSundayOfAdvent(forYear: 2019)
// -> 2019-12-01
let cachedFirstAdvent20 = calculator.firstSundayOfAdvent(forYear: 2020)
// -> 2020-11-29
请注意,所有计算都返回 HolidayDate
- 一个没有时间成分的日期。这不是一个通用的无时间日期。它只是从计算中消除了时区问题。这也是计算器的 calendar: Foundation.Calendar
始终将其时区设置为 UTC 的原因。一旦你使用计算结果,你应该再次使用 Foundation.Date
和 Foundation.DateComponents
。这非常容易,因为你总是可以向 HolidayDate
请求它的 components
(这将返回匹配的 DateComponents
),或者请求计算器为给定的 HolidayDate
返回一个 Date
(这将使用计算器的日历从 HolidayDate
创建一个 Date
)。
该 API 使用 header doc 进行文档记录。如果你希望将文档作为网页查看,则有一个在线版本可供你使用。
如果你发现一个错误/希望看到一个新功能,有几种方法可以提供帮助
请参阅 LICENSE 文件。