remindwall / RWPureSwift / Sources / AppTypes / ReminderPart.swift
Back to remindwall — Current RemindWall
import Foundation
import SwiftData
public enum DaysOfWeek: Int, CaseIterable, Sendable {
case Sunday = 1,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
public struct ReminderPart: Equatable, Sendable {
//Range 1 = Sun to 7 = Sat
public var weekDay: DaysOfWeek
public var hour: Int
public var minute: Int
public init(){
self.weekDay = .Sunday
self.hour = 1
self.minute = 0
}
public init(weekDay: DaysOfWeek, hour: Int, minute: Int) {
self.weekDay = weekDay
self.hour = hour
self.minute = minute
}
public init(date: Date, calendar: Calendar){
self.weekDay = DaysOfWeek(rawValue: calendar.component(.weekday, from: date))!
self.hour = calendar.component(.hour, from: date)
self.minute = calendar.component(.minute, from: date)
}
public func earlyScan() -> ReminderPart {
var newWeekDay = weekDay.rawValue
//2 hours before
var newHour = hour - 2
if newHour < 0 {
newHour = 24 + newHour
newWeekDay = newWeekDay - 1
}
if newWeekDay < 1 {
newWeekDay = 7 + newWeekDay
}
return ReminderPart(weekDay: DaysOfWeek(rawValue:newWeekDay)!, hour: newHour, minute: minute)
}
public func lateReminder() -> ReminderPart {
var newWeekDay = weekDay.rawValue
//4 hours after
var newHour = hour + 4
if newHour > 23 {
newHour -= 24
newWeekDay += 1
}
if newWeekDay > 7 {
newWeekDay -= 7
}
return ReminderPart(weekDay: DaysOfWeek(rawValue:newWeekDay)!, hour: newHour, minute: minute)
}
/// By default a reminder is late if we are within 4 hours after its window
public func inLateWindow(asOf: Date, calendar: Calendar) -> Bool {
let now_rt = ReminderPart(date: asOf, calendar: calendar)
let late_rt = self.lateReminder()
//Have to be on the same days for this to even be close
if now_rt.weekDay != self.weekDay && now_rt.weekDay != late_rt.weekDay {
return false
}
//Are we in the right hour range?
if now_rt.weekDay == self.weekDay && now_rt.hour < self.hour {
return false
}
if now_rt.weekDay == late_rt.weekDay && now_rt.hour > late_rt.hour {
return false
}
//Are we in the minute range?
if now_rt.weekDay == self.weekDay && now_rt.hour == self.hour && now_rt.minute < self.minute {
return false
}
if now_rt.weekDay == late_rt.weekDay && now_rt.hour == late_rt.hour && now_rt.minute >= late_rt.minute {
return false
}
return true
}
/// By default a reminder scan window is two hours before OR in the late window
public func inScanWindow(asOf: Date, calendar: Calendar) -> Bool {
if self.inLateWindow(asOf: asOf, calendar: calendar){
return true
}
//Now we just have to check for early
let now_rt = ReminderPart(date: asOf, calendar: calendar)
let early_rt = self.earlyScan()
//Have to be on the same days for this to even be close
if now_rt.weekDay != self.weekDay && now_rt.weekDay != early_rt.weekDay {
return false
}
//Are we in the right hour range?
if now_rt.weekDay == early_rt.weekDay && now_rt.hour < early_rt.hour {
return false
}
if now_rt.weekDay == self.weekDay && now_rt.hour > self.hour {
return false
}
//Are we in the minute range?
if now_rt.weekDay == early_rt.weekDay && now_rt.hour == early_rt.hour && now_rt.minute < early_rt.minute {
return false
}
if now_rt.weekDay == self.weekDay && now_rt.hour == self.hour && now_rt.minute > self.minute {
return false
}
return true
}
}
extension ReminderPart: CustomDebugStringConvertible {
public var debugDescription: String {
return "ReminderPart(weekDay: \(weekDay), hour: \(hour), minute: \(minute)"
}
}