-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathDay.swift
78 lines (69 loc) · 2.18 KB
/
Day.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import Foundation
import ReactiveSwift
import Schemata
/// A particular day (i.e. a `Date` without a time)
public struct Day: Hashable {
public let daysSinceReferenceDate: Int
public init(daysSinceReferenceDate: Int) {
self.daysSinceReferenceDate = daysSinceReferenceDate
}
public init(_ date: Date = Date(), timeZone: TimeZone = .current) {
var calendar = Calendar.current
calendar.timeZone = timeZone
let reference = calendar.date(
from: DateComponents(
year: 2001,
month: 1,
day: 1
)
)!
let components = calendar.dateComponents([.day], from: reference, to: date)
daysSinceReferenceDate = components.day!
}
}
extension Day {
/// The start timestamp of `self` in the given timezone.
internal func start(in timeZone: TimeZone = .current) -> Date {
var calendar = Calendar.current
calendar.timeZone = timeZone
let reference = calendar.date(
from: DateComponents(
year: 2001,
month: 1,
day: 1
)
)!
return calendar.date(byAdding: .day, value: daysSinceReferenceDate, to: reference)!
}
/// The start timestamp of `self` in the current timezone.
public var start: Date {
return start()
}
}
extension Day: Comparable {
public static func < (lhs: Day, rhs: Day) -> Bool {
return lhs.daysSinceReferenceDate < rhs.daysSinceReferenceDate
}
}
extension Day {
/// A property with the current day that changes when the day changes.
public static let current = ReactiveSwift.Property<Day>(
initial: Day(),
then: NotificationCenter
.default
.reactive
.notifications(forName: .NSCalendarDayChanged)
.map { _ in Day() }
)
}
extension Day: ModelValue {
public static let value = Int.value.bimap(
decode: Day.init(daysSinceReferenceDate:),
encode: { $0.daysSinceReferenceDate }
)
}
extension Day {
public static func + (lhs: Day, rhs: Int) -> Day {
return Day(daysSinceReferenceDate: lhs.daysSinceReferenceDate + rhs)
}
}