From 54dd55db8c19667939536e18535ac9c45817e442 Mon Sep 17 00:00:00 2001 From: ivar Date: Wed, 6 May 2026 21:21:17 +0200 Subject: refactor: remove duplicate source files now served from Shared/ --- Solsnu.Widget/Utilities/SunTimes.swift | 148 --------------------------------- 1 file changed, 148 deletions(-) delete mode 100644 Solsnu.Widget/Utilities/SunTimes.swift (limited to 'Solsnu.Widget/Utilities/SunTimes.swift') diff --git a/Solsnu.Widget/Utilities/SunTimes.swift b/Solsnu.Widget/Utilities/SunTimes.swift deleted file mode 100644 index 8c7132e..0000000 --- a/Solsnu.Widget/Utilities/SunTimes.swift +++ /dev/null @@ -1,148 +0,0 @@ -import Foundation - -class SunTimes { - let latitude: Double - let longitude: Double - let date: Date - - init(latitude: Double, longitude: Double, date: Date) { - self.latitude = latitude - self.longitude = longitude - self.date = date - } - - /// Calculate sunrise time for the location and date - func sunrise() -> Date? { - guard let result = calculateSunTimes() else { return nil } - return result.sunrise - } - - /// Calculate sunset time for the location and date - func sunset() -> Date? { - guard let result = calculateSunTimes() else { return nil } - return result.sunset - } - - // NOAA solar position algorithm - // Reference: https://www.esrl.noaa.gov/gmd/grad/solcalc/ - private func calculateSunTimes() -> (sunrise: Date, sunset: Date)? { - let calendar = Calendar(identifier: .gregorian) - let components = calendar.dateComponents([.year, .month, .day], from: date) - guard let year = components.year else { - return nil - } - - // Step 1: Calculate day of year - let jan1 = calendar.date(from: DateComponents(year: year, month: 1, day: 1))! - let dayOfYear = calendar.dateComponents([.day], from: jan1, to: date).day! + 1 - - // Step 2: Fractional year in radians - let daysInYear = Double(isLeapYear(year) ? 366 : 365) - let gamma = 2.0 * Double.pi * Double(dayOfYear - 1) / daysInYear - - // Step 3: Solar declination (radians) - let decl = 0.006918 - 0.399912 * cos(gamma) + 0.070257 * sin(gamma) - - 0.006758 * cos(2.0 * gamma) + 0.000907 * sin(2.0 * gamma) - - 0.002697 * cos(3.0 * gamma) + 0.00148 * sin(3.0 * gamma) - - // Step 4: Equation of time (minutes) - let eot = 229.18 * (0.000075 + 0.001868 * cos(gamma) - 0.032077 * sin(gamma) - - 0.014615 * cos(2.0 * gamma) - 0.040849 * sin(2.0 * gamma)) - - // Step 5: Hour angle at sunrise/sunset - let latRad = latitude * Double.pi / 180.0 - let cosH = -tan(latRad) * tan(decl) - - guard cosH >= -1.0 && cosH <= 1.0 else { - // Sun is always up or always down at this latitude/date - return nil - } - - let h = acos(cosH) * 180.0 / Double.pi - - // Step 6: Solar noon in UTC (decimal hours) - let solarNoonUTC = 12.0 - (longitude / 15.0) - (eot / 60.0) - - // Step 7: Sunrise and sunset in UTC (decimal hours) - let sunriseUTC = solarNoonUTC - (h / 15.0) - let sunsetUTC = solarNoonUTC + (h / 15.0) - - // Step 8: Convert to local time (add timezone offset) - let tzOffset = Double(TimeZone.current.secondsFromGMT(for: date)) / 3600.0 - let sunriseLocal = sunriseUTC + tzOffset - let sunsetLocal = sunsetUTC + tzOffset - - // Step 9: Create date components, handling day boundary crossing - let currentCalendar = Calendar.current - let baseComponents = currentCalendar.dateComponents([.year, .month, .day], from: date) - - // Sunrise - var sunriseComp = baseComponents - let srHourDouble = sunriseLocal - let srHour = Int(srHourDouble) - let srMinuteDouble = (srHourDouble - Double(srHour)) * 60.0 - let srMinute = Int(srMinuteDouble) - - if srHour < 0 { - if let prevDay = currentCalendar.date(byAdding: .day, value: -1, to: date) { - let prevComponents = currentCalendar.dateComponents([.year, .month, .day], from: prevDay) - sunriseComp = prevComponents - sunriseComp.hour = 24 + srHour - } else { - sunriseComp.hour = 0 - } - } else if srHour >= 24 { - if let nextDay = currentCalendar.date(byAdding: .day, value: 1, to: date) { - let nextComponents = currentCalendar.dateComponents([.year, .month, .day], from: nextDay) - sunriseComp = nextComponents - sunriseComp.hour = srHour - 24 - } else { - sunriseComp.hour = 23 - } - } else { - sunriseComp.hour = srHour - } - sunriseComp.minute = max(0, min(59, srMinute)) - sunriseComp.second = 0 - - // Sunset - var sunsetComp = baseComponents - let ssHourDouble = sunsetLocal - let ssHour = Int(ssHourDouble) - let ssMinuteDouble = (ssHourDouble - Double(ssHour)) * 60.0 - let ssMinute = Int(ssMinuteDouble) - - if ssHour < 0 { - if let prevDay = currentCalendar.date(byAdding: .day, value: -1, to: date) { - let prevComponents = currentCalendar.dateComponents([.year, .month, .day], from: prevDay) - sunsetComp = prevComponents - sunsetComp.hour = 24 + ssHour - } else { - sunsetComp.hour = 0 - } - } else if ssHour >= 24 { - if let nextDay = currentCalendar.date(byAdding: .day, value: 1, to: date) { - let nextComponents = currentCalendar.dateComponents([.year, .month, .day], from: nextDay) - sunsetComp = nextComponents - sunsetComp.hour = ssHour - 24 - } else { - sunsetComp.hour = 23 - } - } else { - sunsetComp.hour = ssHour - } - sunsetComp.minute = max(0, min(59, ssMinute)) - sunsetComp.second = 0 - - guard let sunriseDate = currentCalendar.date(from: sunriseComp), - let sunsetDate = currentCalendar.date(from: sunsetComp) else { - return nil - } - - return (sunriseDate, sunsetDate) - } - - private func isLeapYear(_ year: Int) -> Bool { - return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) - } -} -- cgit v1.3