diff --git a/Sources/Jobs/Scheduler/Schedule.swift b/Sources/Jobs/Scheduler/Schedule.swift index 5ffcfd8..8f713de 100644 --- a/Sources/Jobs/Scheduler/Schedule.swift +++ b/Sources/Jobs/Scheduler/Schedule.swift @@ -117,6 +117,39 @@ public struct Schedule: Sendable { .init(second: .specific(second)) } + /// Return schedule that generates a Date for minutes, hours or seconds + /// - Parameter minute: minute value e.g 5 + /// - Parameter hour: hour value e.g 3 + /// - Parameter timeZone defaults to current timezone + public static func every(minute: Int = 5, hour: Int = 0, timeZone: TimeZone = .current) -> Self { + let maxNumber = if minute > 0, hour == 0 { + 60 / minute + } else { + 24 / hour + } + + var multiples: [Int] = [] + var index = 0 + let number = hour > 0 ? hour : minute + repeat { + let multiple = number * index + + if hour > 0, multiple > 24 { + let remainder = multiple % 24 + multiples.append(remainder - hour) + } else { + multiples.append(multiple) + } + + index = index + 1 + } while index < maxNumber + + if hour == 0 { + return .onMinutes(multiples) + } + return .onHours(multiples, timeZone: timeZone) + } + /// Return Schedule that generates a Date for a selection of minutes /// - Parameters /// - minutes: Array of minutes if should return Dates for diff --git a/Tests/JobsTests/JobSchedulerTests.swift b/Tests/JobsTests/JobSchedulerTests.swift index 330ff6e..e697b7d 100644 --- a/Tests/JobsTests/JobSchedulerTests.swift +++ b/Tests/JobsTests/JobSchedulerTests.swift @@ -62,6 +62,15 @@ final class JobSchedulerTests: XCTestCase { try self.testSchedule(start: "1999-12-31T23:59:25Z", expectedEnd: "2000-01-01T00:00:15Z", schedule: .everyMinute(second: 15)) } + func testEverySchedule() throws { + try self.testSchedule(start: "2021-06-21T21:00:00Z", expectedEnd: "2021-06-21T22:00:00Z", schedule: .every(minute: 5)) + try self.testSchedule(start: "2021-06-21T21:10:15Z", expectedEnd: "2021-06-21T22:00:00Z", schedule: .every(minute: 5)) + try self.testSchedule(start: "2024-02-22T20:00:00Z", expectedEnd: "2024-02-23T00:00:00Z", schedule: .every(hour: 3)) + try self.testSchedule(start: "2024-02-22T20:00:00Z", expectedEnd: "2024-02-23T00:00:00Z", schedule: .every(hour: 12)) + try self.testSchedule(start: "2024-02-22T00:00:00Z", expectedEnd: "2024-02-23T00:00:00Z", schedule: .every(hour: 12)) + try self.testSchedule(start: "2024-02-22T01:00:00Z", expectedEnd: "2024-02-23T00:00:00Z", schedule: .every(hour: 24)) + } + func testHourlySchedule() throws { try self.testSchedule(start: "2021-06-21T21:10:15Z", expectedEnd: "2021-06-21T21:58:00Z", schedule: .hourly(minute: 58)) try self.testSchedule(start: "1999-12-31T23:59:25Z", expectedEnd: "2000-01-01T00:01:00Z", schedule: .hourly(minute: 1))