- Initialize iOS project with 6-tab navigation structure - Configure custom Light/Dark themes and AppColors - Define SwiftData models for Tasks, Tags, Goals, and TrackingRecords - Setup relationships (Super/Sub tags) and cascade delete rules - Implement Observable TrackingEngine for real-time timer updates
47 lines
1.6 KiB
Swift
47 lines
1.6 KiB
Swift
import Foundation
|
|
|
|
final class CalendarBoundaryService {
|
|
private let preferences: AppPreferences
|
|
|
|
init(preferences: AppPreferences) {
|
|
self.preferences = preferences
|
|
}
|
|
|
|
private var calendar: Calendar {
|
|
var cal = Calendar.current
|
|
cal.firstWeekday = preferences.weekStartDay
|
|
return cal
|
|
}
|
|
|
|
func customDayStart(for date: Date) -> Date {
|
|
// TODO: apply dayStartHour / dayStartMinute boundary shift in milestone 2
|
|
var comps = calendar.dateComponents([.year, .month, .day], from: date)
|
|
comps.hour = preferences.dayStartHour
|
|
comps.minute = preferences.dayStartMinute
|
|
comps.second = 0
|
|
return calendar.date(from: comps) ?? date
|
|
}
|
|
|
|
func dayRange(for date: Date) -> DateInterval {
|
|
let start = customDayStart(for: date)
|
|
let end = calendar.date(byAdding: .day, value: 1, to: start) ?? start
|
|
return DateInterval(start: start, end: end)
|
|
}
|
|
|
|
func weekRange(for date: Date) -> DateInterval {
|
|
// TODO: align to custom day-start boundary in milestone 2
|
|
guard let interval = calendar.dateInterval(of: .weekOfYear, for: date) else {
|
|
return DateInterval(start: date, duration: 7 * 86_400)
|
|
}
|
|
return interval
|
|
}
|
|
|
|
func monthRange(for date: Date) -> DateInterval {
|
|
// TODO: align to custom day-start boundary in milestone 2
|
|
guard let interval = calendar.dateInterval(of: .month, for: date) else {
|
|
return DateInterval(start: date, duration: 30 * 86_400)
|
|
}
|
|
return interval
|
|
}
|
|
}
|