Skip to content

Commit e0fae40

Browse files
committed
Add date helpers
1 parent 3d80fde commit e0fae40

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed

Sources/EasyMode/Date.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import Foundation
2+
3+
extension Date {
4+
public var startOfWeek: Date {
5+
return previous(.monday, considerToday: true)
6+
}
7+
8+
public var endOfWeek: Date {
9+
return next(.sunday, considerToday: true)
10+
}
11+
12+
public var isoDate: String {
13+
let formatter = DateFormatter()
14+
formatter.dateFormat = "yyyy-MM-dd"
15+
formatter.timeZone = TimeZone(abbreviation: "CET")!
16+
17+
return formatter.string(from: self)
18+
}
19+
}
20+
21+
extension Date {
22+
23+
public static func today() -> Date {
24+
return Date()
25+
}
26+
27+
public func next(_ weekday: Weekday, considerToday: Bool = false) -> Date {
28+
return get(.next,
29+
weekday,
30+
considerToday: considerToday)
31+
}
32+
33+
public func previous(_ weekday: Weekday, considerToday: Bool = false) -> Date {
34+
return get(.previous,
35+
weekday,
36+
considerToday: considerToday)
37+
}
38+
39+
public func get(_ direction: SearchDirection,
40+
_ weekDay: Weekday,
41+
considerToday consider: Bool = false) -> Date {
42+
43+
let dayName = weekDay.rawValue
44+
45+
let weekdaysName = getWeekDaysInEnglish().map { $0.lowercased() }
46+
47+
assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")
48+
49+
let searchWeekdayIndex = weekdaysName.firstIndex(of: dayName)! + 1
50+
51+
let calendar = Calendar(identifier: .gregorian)
52+
53+
if consider && calendar.component(.weekday, from: self) == searchWeekdayIndex {
54+
return self
55+
}
56+
57+
var nextDateComponent = DateComponents()
58+
nextDateComponent.weekday = searchWeekdayIndex
59+
60+
61+
let date = calendar.nextDate(after: self,
62+
matching: nextDateComponent,
63+
matchingPolicy: .nextTime,
64+
direction: direction.calendarSearchDirection)
65+
66+
return date!
67+
}
68+
69+
}
70+
71+
// MARK: Helper methods
72+
extension Date {
73+
public func getWeekDaysInEnglish() -> [String] {
74+
var calendar = Calendar(identifier: .gregorian)
75+
calendar.locale = Locale(identifier: "en_US_POSIX")
76+
return calendar.weekdaySymbols
77+
}
78+
79+
public enum Weekday: String {
80+
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
81+
}
82+
83+
public enum SearchDirection {
84+
case next
85+
case previous
86+
87+
var calendarSearchDirection: Calendar.SearchDirection {
88+
switch self {
89+
case .next:
90+
return .forward
91+
case .previous:
92+
return .backward
93+
}
94+
}
95+
}
96+
}

Tests/EasyModeTests/DateTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import XCTest
2+
@testable import EasyMode
3+
4+
class DateTests: XCTestCase {
5+
func testStartOfWeek() {
6+
let current = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 28).date!
7+
let expected = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 26).date!
8+
9+
XCTAssertEqual(expected, current.startOfWeek)
10+
}
11+
12+
func testEndOfWeek() {
13+
let current = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 28).date!
14+
let expected = DateComponents(calendar: Calendar.current, year: 2019, month: 9, day: 1).date!
15+
16+
XCTAssertEqual(expected, current.endOfWeek)
17+
}
18+
19+
func testEndOfLastWeek() {
20+
let current = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 28).date!
21+
let expected = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 25).date!
22+
23+
let oneWeekAgo = Calendar.current.date(byAdding: .day, value: -7, to: current)!
24+
25+
XCTAssertEqual(expected, oneWeekAgo.endOfWeek)
26+
}
27+
28+
func testIsoDate() {
29+
let date = DateComponents(calendar: Calendar.current, year: 2019, month: 8, day: 6).date!
30+
31+
XCTAssertEqual("2019-08-06", date.isoDate)
32+
}
33+
34+
func testIsoDateWhenSunday() {
35+
let date = DateComponents(calendar: Calendar.current, year: 2019, month: 9, day: 8).date!
36+
37+
XCTAssertEqual("2019-09-08", date.endOfWeek.isoDate)
38+
}
39+
40+
static var allTests = [
41+
("testStartOfWeek", testStartOfWeek),
42+
("testEndOfWeek", testEndOfWeek),
43+
("testEndOfLastWeek", testEndOfLastWeek),
44+
("testIsoDate", testIsoDate),
45+
("testIsoDateWhenSunday", testIsoDateWhenSunday),
46+
]
47+
}

Tests/EasyModeTests/XCTestManifests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import XCTest
44
public func allTests() -> [XCTestCaseEntry] {
55
return [
66
testCase(EasyModeTests.allTests),
7-
testCase(StringTests.allTests)
7+
testCase(StringTests.allTests),
8+
testCase(DateTests.allTests),
89
]
910
}
1011
#endif

0 commit comments

Comments
 (0)