summaryrefslogtreecommitdiffstats
path: root/Shared/Models
diff options
context:
space:
mode:
authorivar <i@oiee.no>2026-05-07 01:24:28 +0200
committerivar <i@oiee.no>2026-05-07 01:24:28 +0200
commit6eb17a18e901e2d7faa219d7e5a79083a5891dc9 (patch)
tree3d0796e1e567864dfdf7c675f7e8a5a40fb51a95 /Shared/Models
parent4fb690150b77afced6453e6bdb14cc4cf00d5305 (diff)
downloadsolverv-6eb17a18e901e2d7faa219d7e5a79083a5891dc9.tar.xz
solverv-6eb17a18e901e2d7faa219d7e5a79083a5891dc9.zip
RefactorsHEADmaster
Diffstat (limited to 'Shared/Models')
-rw-r--r--Shared/Models/Season.swift9
-rw-r--r--Shared/Models/SolsticeData.swift111
-rw-r--r--Shared/Models/SolsticeEvent.swift15
3 files changed, 75 insertions, 60 deletions
diff --git a/Shared/Models/Season.swift b/Shared/Models/Season.swift
index c956fed..ed9b7df 100644
--- a/Shared/Models/Season.swift
+++ b/Shared/Models/Season.swift
@@ -6,6 +6,15 @@ enum Season: String, Codable {
case autumn
case winter
+ var eventName: String {
+ switch self {
+ case .spring: return "Vårjevndøgn"
+ case .summer: return "Sommersolverv"
+ case .autumn: return "Høstjevndøgn"
+ case .winter: return "Vintersolverv"
+ }
+ }
+
var displayName: String {
switch self {
case .spring: return "Spring"
diff --git a/Shared/Models/SolsticeData.swift b/Shared/Models/SolsticeData.swift
index 9285aad..d891a0a 100644
--- a/Shared/Models/SolsticeData.swift
+++ b/Shared/Models/SolsticeData.swift
@@ -6,45 +6,48 @@ class SolsticeData {
private let events: [SolsticeEvent]
private init() {
- var allEvents: [SolsticeEvent] = []
+ let table: [(year: Int, month: Int, day: Int, hour: Int, minute: Int, season: Season)] = [
+ // 2025
+ (2025, 3, 20, 9, 1, .spring),
+ (2025, 6, 20, 14, 42, .summer),
+ (2025, 9, 22, 18, 20, .autumn),
+ (2025, 12, 21, 15, 3, .winter),
+ // 2026
+ (2026, 3, 20, 14, 46, .spring),
+ (2026, 6, 21, 8, 25, .summer),
+ (2026, 9, 23, 0, 6, .autumn),
+ (2026, 12, 21, 20, 50, .winter),
+ // 2027
+ (2027, 3, 20, 20, 25, .spring),
+ (2027, 6, 21, 14, 11, .summer),
+ (2027, 9, 23, 6, 2, .autumn),
+ (2027, 12, 22, 2, 43, .winter),
+ // 2028
+ (2028, 3, 20, 2, 17, .spring),
+ (2028, 6, 20, 20, 2, .summer),
+ (2028, 9, 22, 11, 45, .autumn),
+ (2028, 12, 21, 8, 20, .winter),
+ // 2029
+ (2029, 3, 20, 8, 1, .spring),
+ (2029, 6, 21, 1, 48, .summer),
+ (2029, 9, 22, 17, 37, .autumn),
+ (2029, 12, 21, 14, 14, .winter),
+ // 2030
+ (2030, 3, 20, 13, 51, .spring),
+ (2030, 6, 21, 7, 31, .summer),
+ (2030, 9, 22, 23, 27, .autumn),
+ (2030, 12, 21, 20, 9, .winter),
+ ]
- // 2025
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 3, day: 20, hour: 9, minute: 1), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 6, day: 20, hour: 14, minute: 42), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 9, day: 22, hour: 18, minute: 20), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 12, day: 21, hour: 15, minute: 3), season: .winter))
-
- // 2026
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 3, day: 20, hour: 14, minute: 46), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 6, day: 21, hour: 8, minute: 25), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 9, day: 23, hour: 0, minute: 6), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 12, day: 21, hour: 20, minute: 50), season: .winter))
-
- // 2027
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 3, day: 20, hour: 20, minute: 25), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 6, day: 21, hour: 14, minute: 11), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 9, day: 23, hour: 6, minute: 2), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 12, day: 22, hour: 2, minute: 43), season: .winter))
-
- // 2028
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 3, day: 20, hour: 2, minute: 17), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 6, day: 20, hour: 20, minute: 2), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 9, day: 22, hour: 11, minute: 45), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 12, day: 21, hour: 8, minute: 20), season: .winter))
-
- // 2029
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 3, day: 20, hour: 8, minute: 1), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 6, day: 21, hour: 1, minute: 48), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 9, day: 22, hour: 17, minute: 37), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 12, day: 21, hour: 14, minute: 14), season: .winter))
-
- // 2030
- allEvents.append(SolsticeEvent(name: "Vårjevndøgn 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 3, day: 20, hour: 13, minute: 51), season: .spring))
- allEvents.append(SolsticeEvent(name: "Sommersolverv 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 6, day: 21, hour: 7, minute: 31), season: .summer))
- allEvents.append(SolsticeEvent(name: "Høstjevndøgn 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 9, day: 22, hour: 23, minute: 27), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Vintersolverv 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 12, day: 21, hour: 20, minute: 9), season: .winter))
-
- self.events = allEvents.sorted { $0.date < $1.date }
+ events = table
+ .map { row in
+ SolsticeEvent(
+ date: SolsticeData.dateFromUTC(year: row.year, month: row.month, day: row.day,
+ hour: row.hour, minute: row.minute),
+ season: row.season
+ )
+ }
+ .sorted { $0.date < $1.date }
}
private static func dateFromUTC(year: Int, month: Int, day: Int, hour: Int, minute: Int) -> Date {
@@ -60,7 +63,13 @@ class SolsticeData {
}
func nextEvent(from now: Date = Date()) -> SolsticeEvent? {
- return events.first { $0.date > now }
+ return events.first(where: { $0.date > now })
+ }
+
+ func currentEvent(from now: Date = Date()) -> SolsticeEvent? {
+ guard let nextIndex = events.firstIndex(where: { $0.date > now }),
+ nextIndex > 0 else { return nil }
+ return events[nextIndex - 1]
}
func upcomingEvents(count: Int, from now: Date = Date()) -> [SolsticeEvent] {
@@ -69,27 +78,15 @@ class SolsticeData {
}
func progressToNextEvent(from now: Date = Date()) -> (elapsed: Int, total: Int)? {
- guard let _ = nextEvent(from: now) else { return nil }
+ guard let nextIndex = events.firstIndex(where: { $0.date > now }),
+ nextIndex > 0 else { return nil }
let today = Calendar.current.startOfDay(for: now)
+ let previousEventDay = Calendar.current.startOfDay(for: events[nextIndex - 1].date)
+ let eventDay = Calendar.current.startOfDay(for: events[nextIndex].date)
- guard let previousEventIndex = events.firstIndex(where: { $0.date > now }) else {
- return nil
- }
-
- guard previousEventIndex > 0 else { return nil }
-
- let nextEvent = events[previousEventIndex]
- let previousEvent = events[previousEventIndex - 1]
-
- let previousEventDay = Calendar.current.startOfDay(for: previousEvent.date)
- let eventDay = Calendar.current.startOfDay(for: nextEvent.date)
-
- let elapsedComponents = Calendar.current.dateComponents([.day], from: previousEventDay, to: today)
- let totalComponents = Calendar.current.dateComponents([.day], from: previousEventDay, to: eventDay)
-
- let elapsed = max(0, elapsedComponents.day ?? 0)
- let total = max(1, totalComponents.day ?? 1)
+ let elapsed = max(0, Calendar.current.dateComponents([.day], from: previousEventDay, to: today).day ?? 0)
+ let total = max(1, Calendar.current.dateComponents([.day], from: previousEventDay, to: eventDay).day ?? 1)
return (elapsed: elapsed, total: total)
}
diff --git a/Shared/Models/SolsticeEvent.swift b/Shared/Models/SolsticeEvent.swift
index b28cba8..6126d2b 100644
--- a/Shared/Models/SolsticeEvent.swift
+++ b/Shared/Models/SolsticeEvent.swift
@@ -2,17 +2,26 @@ import Foundation
struct SolsticeEvent: Identifiable, Codable {
let id: UUID
- let name: String
let date: Date
let season: Season
- init(name: String, date: Date, season: Season) {
+ init(date: Date, season: Season) {
self.id = UUID()
- self.name = name
self.date = date
self.season = season
}
+ /// Full display name including year, e.g. "Vårjevndøgn 2026".
+ var name: String {
+ let year = Calendar.current.component(.year, from: date)
+ return "\(season.eventName) \(year)"
+ }
+
+ /// Event type name without year, e.g. "Vårjevndøgn".
+ var shortName: String {
+ season.eventName
+ }
+
func localDateTime() -> Date {
let utcCalendar = Calendar(identifier: .gregorian)
let utcComponents = utcCalendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)