From 92f0c3894a701ba5ff83034c9429760125eeb4dc Mon Sep 17 00:00:00 2001 From: QuentinJin Date: Sun, 26 Aug 2018 22:37:51 +0800 Subject: [PATCH] Fix issues about weekday & monthday calculating --- .codecov.yml | 3 +- Sources/Schedule/Schedule.swift | 36 +++++++++++------------- Tests/ScheduleTests/SchedulesTests.swift | 14 +++++---- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 9d395ee..3eb29c2 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,4 +2,5 @@ ignore: - "Tests/" - "Schedule.playground" -comment: off \ No newline at end of file +comment: + layout: header, changes, diff diff --git a/Sources/Schedule/Schedule.swift b/Sources/Schedule/Schedule.swift index b7b315b..5d495b0 100644 --- a/Sources/Schedule/Schedule.swift +++ b/Sources/Schedule/Schedule.swift @@ -268,6 +268,9 @@ extension Schedule { } } } +} + +extension Schedule { /// Creates a schedule that executes the task immediately. public static var now: Schedule { @@ -286,17 +289,17 @@ extension Schedule { } } - /// Creates a schedule that executes the task at the specific date. - public static func at(_ date: Date) -> Schedule { - return Schedule.of(date) - } - /// Creates a schedule that executes the task after delay then repeat /// every interval. public static func after(_ delay: Interval, repeating interval: Interval) -> Schedule { return Schedule.after(delay).concat(Schedule.every(interval)) } + /// Creates a schedule that executes the task at the specific date. + public static func at(_ date: Date) -> Schedule { + return Schedule.of(date) + } + /// Creates a schedule that executes the task every period. public static func every(_ period: Period) -> Schedule { return Schedule.make { () -> AnyIterator in @@ -337,20 +340,15 @@ extension Schedule { /// Returns a schedule at the specific time. public func at(_ time: Time) -> Schedule { - return Schedule.make { () -> AnyIterator in - let iterator = self.schedule.dates.makeIterator() - let calendar = Calendar.gregorian - var last: Date! + var interval = time.intervalSinceZeroClock + return Schedule.make { () -> AnyIterator in + let it = self.schedule.makeIterator() return AnyIterator { - last = last ?? Date() - guard let date = iterator.next(), - let next = calendar.nextDate(after: date.zeroClock(), - matching: time.toDateComponents(), - matchingPolicy: .strict) else { - return nil + if let next = it.next() { + defer { interval = 0.nanoseconds } + return next + interval } - defer { last = next } - return next + return nil } } } @@ -392,7 +390,7 @@ extension Schedule { var date: Date! return AnyIterator { if weekday.isToday { - date = Date() + date = Date().zeroClock() } else if date == nil { date = calendar.nextDate(after: Date(), matching: components, matchingPolicy: .strict) } else { @@ -423,7 +421,7 @@ extension Schedule { var date: Date! return AnyIterator { if monthDay.isToday { - date = Date() + date = Date().zeroClock() } else if date == nil { date = calendar.nextDate(after: Date(), matching: components, matchingPolicy: .strict) } else { diff --git a/Tests/ScheduleTests/SchedulesTests.swift b/Tests/ScheduleTests/SchedulesTests.swift index 616d320..c836c40 100644 --- a/Tests/ScheduleTests/SchedulesTests.swift +++ b/Tests/ScheduleTests/SchedulesTests.swift @@ -21,6 +21,10 @@ final class SchedulesTests: XCTestCase { let s3 = Schedule.from([d0, d1, d2, d3]) XCTAssertTrue(s2.makeIterator().isAlmostEqual(to: intervals, leeway: leeway)) XCTAssertTrue(s3.makeIterator().isAlmostEqual(to: intervals, leeway: leeway)) + + let longTime = (100 * 365).days + XCTAssertTrue(Schedule.distantPast.makeIterator().next()!.isLonger(than: longTime)) + XCTAssertTrue(Schedule.distantFuture.makeIterator().next()!.isLonger(than: longTime)) } func testDates() { @@ -93,7 +97,7 @@ final class SchedulesTests: XCTestCase { } func testEveryPeriod() { - let s = Schedule.every(1.year).first(10) + let s = Schedule.every("1 year").first(10) var date = Date() for i in s.dates { XCTAssertEqual(i.dateComponents.year!, date.dateComponents.year! + 1) @@ -104,17 +108,17 @@ final class SchedulesTests: XCTestCase { } func testEveryWeekday() { - let s = Schedule.every(.friday).at("11:11:00").first(5) + let s = Schedule.every(.friday, .monday).at("11:11:00").first(5) for i in s.dates { - XCTAssertEqual(i.dateComponents.weekday, 6) + XCTAssertTrue(i.dateComponents.weekday == 6 || i.dateComponents.weekday == 2) XCTAssertEqual(i.dateComponents.hour, 11) } } func testEveryMonthday() { - let s = Schedule.every(.april(1)).at(11, 11).first(5) + let s = Schedule.every(.april(1), .october(1)).at(11, 11).first(5) for i in s.dates { - XCTAssertEqual(i.dateComponents.month, 4) + XCTAssertTrue(i.dateComponents.month == 4 || i.dateComponents.month == 10) XCTAssertEqual(i.dateComponents.day, 1) XCTAssertEqual(i.dateComponents.hour, 11) }