DateBuilder 允许您以可视化和声明式的方式轻松创建 Date
和 DateComponents
实例。使用 DateBuilder,您可以轻松定义日期,从简单的“明天晚上 9 点”到复杂的“未来 24 个月内每个月的第一个星期五,时间在下午 3 点到 7 点之间的随机时间”。
维护者: @dreymonde
目前,DateBuilder 仍处于 beta 阶段。某些 API 可能会在发布版本之间发生更改。
DateBuilder 是 NiceNotifications 的一个独立部分,这是一个从内容到权限都大大简化了本地通知的框架。
import DateBuilder
Today()
.at(hour: 20, minute: 15)
.dateComponents() // year: 2021, month: 1, day: 31, hour: 20, minute: 15
NextWeek()
.weekday(.saturday)
.at(hour: 18, minute: 50)
.dateComponents() // DateComponents
EveryWeek(forWeeks: 10, starting: .thisWeek)
.weekendStartDay
.at(hour: 9, minute: 00)
.dates() // [Date]
ExactlyAt(account.createdAt)
.addingDays(15)
.date() // Date
WeekOf(account.createdAt)
.addingWeeks(1)
.lastDay
.at(hour: 10, minute: 00)
.dateComponents() // DateComponents
EveryMonth(forMonths: 12, starting: .thisMonth)
.lastDay
.at(hour: 23, minute: 50)
.dateComponents() // [DateComponents]
NextYear().addingYears(2)
.firstMonth.addingMonths(3) // April (in Gregorian)
.first(.thursday)
.dateComponents() // year: 2024, month: 4, day: 4
ExactDay(year: 2020, month: 10, day: 5)
.at(hour: 10, minute: 15)
.date() // Date
ExactYear(year: 2020)
.lastMonth
.lastDay
.dateComponents()
每个 DateBuilder 表达式都以特定的日期结束(如果您使用像 EveryDay
/EveryMonth
/etc. 这样的函数,则为一组日期)。首先,您将表达式指定到日期,然后通过调用 at(hour:minute:)
函数定义一天中的时间。 例如:
NextWeek()
.firstDay
.at(hour: 10, minute: 15)
一旦有了 at
表达式,您的日期就完全确定了。 您可以通过调用 .date()
或 .dateComponents()
来获取现成的 Date
或 DateComponents
实例。
稍微复杂一点的例子是:
let dateComponents = NextYear()
.firstMonth.addingMonths(3)
.first(.thursday)
.at(hour: 21, minute: 00)
.dateComponents()
因此,我们从年份的尺度开始,然后将其缩小到月份的尺度,最后我们得到特定的日期,在本例中是明年 4 月的第一个星期四。 之后,我们使用 at
函数来完成查询。
// top-level
Today()
Tomorrow()
DayOf(account.createdAt)
ExactDay(year: 2021, month: 1, day: 26)
AddingDays(15, to: .today)
AddingDays(15, to: .dayOf(account.createdAt))
EveryDay(forDays: 100, starting: .tomorrow)
EveryDay(forDays: 100, starting: .dayOf(account.createdAt))
// instance
Today()
--->.addingDays(10)
注意:一周的开始和结束由当前设置的 Calendar
及其 Locale
决定。 要了解如何自定义用于 DateBuilder 查询的日历对象,请参阅下面的“自定义日历/区域设置/时区”部分
// top-level
ThisWeek()
NextWeek()
WeekOf(account.createdAt)
WeekOf(Today()) // use any `DateBuilder.Day` instance here
AddingWeeks(5, to: .thisWeek)
EveryWeek(forWeeks: 10, starting: .nextWeek)
// instance
ThisWeek()
--->.addingWeeks(10) // Week
--->.firstDay // Day
--->.lastDay // Day
--->.allDays // [Day]
--->.weekday(.thursday) // Day
--->.weekendStartDay // Day
--->.weekendEndDay // Day
// top-level
ThisMonth()
NextMonth()
MonthOf(account.createdAt)
MonthOf(Today()) // use any `DateBuilder.Day` instance here
ExactMonth(year: 2021, month: 03)
AddingMonths(3, to: .thisMonth)
EveryMonth(forMonths: 5, starting: .monthOf(account.createdAt))
// instance
ThisMonth()
--->.addingMonths(5) // Month
--->.firstDay // Day
--->.lastDay // Day
--->.allDays // [Day]
--->.first(.saturday) // Day
--->.weekday(.third, .friday) // Day
// top-level
ThisYear()
NextYear()
YearOf(account.createdAt)
YearOf(Tomorrow()) // use any `DateBuilder.Day` instance here
YearOf(NextMonth()) // use any `DateBuilder.Month` instance here
ExactYear(year: 2022)
AddingYears(1, to: ThisYear())
EveryYear(forYears: 100, starting: .thisYear)
// instance
ThisYear()
--->.addingYears(1) // Year
--->.firstMonth // Month
--->.lastMonth // Month
--->.allMonths // [Month]
Today()
--->.at(hour: 10, minute: 15)
--->.at(hour: 19, minute: 30, second: 30)
--->.at(TimeOfDay(hour: 10, minute: 30, second: 0)) // equivalent to:
--->.at(.time(hour: 10, minute: 30))
--->.at(.randomTime(from: .time(hour: 10, minute: 15), to: .time(hour: 15, minute: 30)))
Today()
.at(hour: 9, minute: 15)
.date() // Date
// or
Today()
.at(hour: 9, minute: 15)
.dateComponents() // DateComponents
您还可以通过在 DateBuilder.Day
的实例上调用 dateComponents()
来获取 DateComponents
实例(但不是 Date
),而无需使用 at
NextMonth()
.firstDay
.dateComponents() // year: 2021, month: 2, day: 1
ExactlyAt
从现有的 Date
实例创建一个已解析的日期。 然后,您可以使用它来执行简单的日期计算(函数 addingMinutes
/addingHours
等),并轻松获取 Date
或 DateComponents
实例。
ExactlyAt(account.createdAt)
--->.addingSeconds(30)
--->.addingMinutes(1)
--->.addingHours(5)
--->.addingDays(20)
--->.addingMonths(3)
--->.addingWeeks(14)
--->.addingYears(1)
// usge:
ExactlyAt(account.createdAt)
.addingMinutes(15)
.dateComponents() // DateComponents
您可以像使用 Today()
或 NextYear()
一样使用 EveryDay
、EveryWeek
、EveryMonth
和 EveryYear
函数。 唯一的区别是,最后您将获得一个日期数组,而不是单个实例
let dates = EveryMonth(forMonths: 12, starting: .thisMonth)
.firstDay.addingDays(9)
.at(hour: 20, minute: 00)
.dates() // [Date]
// or
let dates = EveryMonth(forMonths: 12, starting: .thisMonth)
.lastDay.addingDays(-5)
.at(hour: 20, minute: 00)
.dateComponents() // [DateComponents]
如果您将 .at(.randomTime( ... ))
函数与 Every
函数一起使用,则每天的确切解析时间将不同。
默认情况下,DateBuilder 使用 Calendar.current
进行所有计算。 如果需要自定义它,您可以全局更改它
var customCalendar = DateBuilder.calendar
customCalendar.firstWeekday = 6
DateBuilder.calendar = customCalendar
或者暂时使用 DateBuilder.withCalendar
函数
DateBuilder.withCalendar(customCalendar) {
ThisWeek().firstDay.dateComponents()
}
在评估表达式后,DateBuilder 将返回到其全局 Calendar
实例。
以类似的方式,您也可以使用 DateBuilder.withTimeZone
和 DateBuilder.withLocale
函数
DateBuilder.withTimeZone(TimeZone(identifier: "America/Cancun")) {
Tomorrow().at(hour: 9, minute: 15).date()
}
let nextFriday = DateBuilder.withLocale(Locale(identifier: "he_IL")) {
NextWeek()
.weekendStartDay
.at(hour: 7, minute: 00)
.date() // next friday!
}
所有这些函数都支持返回闭包的结果(见上文)。
http://github.com/nicephoton/DateBuilder.git
。特别感谢
相关资料