From e2f6c71b2733e4b3976eaffc2f0b8e4c81439be2 Mon Sep 17 00:00:00 2001 From: Dylan Shine Date: Mon, 8 Aug 2022 13:43:49 -0600 Subject: [PATCH] Add ability to use custom `Calendar` in `ScheduleBuilder` (#113) Add Calendar to ScheduleBuilder --- Sources/Queues/ScheduleBuilder.swift | 10 +++- Tests/QueuesTests/ScheduleBuilderTests.swift | 60 ++++++++++---------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/Sources/Queues/ScheduleBuilder.swift b/Sources/Queues/ScheduleBuilder.swift index 0111863..310dd6e 100644 --- a/Sources/Queues/ScheduleBuilder.swift +++ b/Sources/Queues/ScheduleBuilder.swift @@ -3,6 +3,7 @@ import struct Foundation.Calendar /// An object that can be used to build a scheduled job public final class ScheduleBuilder { + /// Months of the year public enum Month: Int { case january = 1 @@ -374,13 +375,16 @@ public final class ScheduleBuilder { if let month = self.month { components.month = month.rawValue } - return Calendar.current.nextDate( + return calendar.nextDate( after: current, matching: components, matchingPolicy: .strict ) } + /// The caledar used to compute the next date + let calendar: Calendar + /// Date to perform task (one-off job) var date: Date? var month: Month? @@ -391,7 +395,9 @@ public final class ScheduleBuilder { var second: Second? var millisecond: Int? - public init() { } + public init(calendar: Calendar = .current) { + self.calendar = calendar + } // MARK: Helpers diff --git a/Tests/QueuesTests/ScheduleBuilderTests.swift b/Tests/QueuesTests/ScheduleBuilderTests.swift index 0696db1..bf89f1a 100644 --- a/Tests/QueuesTests/ScheduleBuilderTests.swift +++ b/Tests/QueuesTests/ScheduleBuilderTests.swift @@ -133,6 +133,27 @@ final class ScheduleBuilderTests: XCTestCase { Date(year: 2020, month: 5, day: 23, hour: 14, minute: 58) ) } + + func testCustomCalendarBuilder() throws { + + let est = Calendar.calendar(timezone: "EST") + let mst = Calendar.calendar(timezone: "MST") + + // Create a date at 8:00pm EST + let estDate = Date(calendar: est, hour: 20, minute: 00) + + // Schedule it for 7:00pm MST + let builder = ScheduleBuilder(calendar: mst) + builder.daily().at("7:00pm") + + XCTAssertEqual( + builder.nextDate(current: estDate), + // one hour later + Date(calendar: est, hour: 21, minute: 00) + ) + + } + } @@ -144,35 +165,8 @@ final class Cleanup: ScheduledJob { } extension Date { - var year: Int { - Calendar.current.component(.year, from: self) - } - - var month: Int { - Calendar.current.component(.month, from: self) - } - - var weekday: Int { - Calendar.current.component(.weekday, from: self) - } - - var day: Int { - Calendar.current.component(.day, from: self) - } - - var hour: Int { - Calendar.current.component(.hour, from: self) - } - - var minute: Int { - Calendar.current.component(.minute, from: self) - } - - var second: Int { - Calendar.current.component(.second, from: self) - } - init( + calendar: Calendar = .current, year: Int = 2020, month: Int = 1, day: Int = 1, @@ -181,8 +175,16 @@ extension Date { second: Int = 0 ) { self = DateComponents( - calendar: .current, + calendar: calendar, year: year, month: month, day: day, hour: hour, minute: minute, second: second ).date! } } + +extension Calendar { + fileprivate static func calendar(timezone identifier: String) -> Calendar { + var calendar = Calendar.current + calendar.timeZone = TimeZone(identifier: identifier)! + return calendar + } +}