diff --git a/.swift-version b/.swift-version
new file mode 100644
index 0000000..819e07a
--- /dev/null
+++ b/.swift-version
@@ -0,0 +1 @@
+5.0
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Daylight.xcodeproj/project.pbxproj b/Daylight.xcodeproj/project.pbxproj
index 1fccc81..d726a5c 100644
--- a/Daylight.xcodeproj/project.pbxproj
+++ b/Daylight.xcodeproj/project.pbxproj
@@ -53,6 +53,16 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 25455E7D2BEA51F500CABDF3 /* Daylight */ = {
+ isa = PBXGroup;
+ children = (
+ OBJ_9 /* Daylight.swift */,
+ 5B402B651E9B29A20079BE20 /* DaylightUtilities.swift */,
+ 5B402B671E9B29FF0079BE20 /* DaylightAstronomy.swift */,
+ );
+ path = Daylight;
+ sourceTree = "";
+ };
OBJ_10 /* Tests */ = {
isa = PBXGroup;
children = (
@@ -92,22 +102,11 @@
OBJ_7 /* Sources */ = {
isa = PBXGroup;
children = (
- OBJ_8 /* Daylight */,
+ 25455E7D2BEA51F500CABDF3 /* Daylight */,
);
path = Sources;
sourceTree = "";
};
- OBJ_8 /* Daylight */ = {
- isa = PBXGroup;
- children = (
- OBJ_9 /* Daylight.swift */,
- 5B402B651E9B29A20079BE20 /* DaylightUtilities.swift */,
- 5B402B671E9B29FF0079BE20 /* DaylightAstronomy.swift */,
- );
- name = Daylight;
- path = Sources;
- sourceTree = SOURCE_ROOT;
- };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -158,6 +157,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = OBJ_5;
@@ -228,13 +228,20 @@
);
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = Daylight.xcodeproj/Daylight_Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = Daylight;
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator";
+ SUPPORTS_MACCATALYST = NO;
+ TARGETED_DEVICE_FAMILY = "1,2";
TARGET_NAME = Daylight;
+ TVOS_DEPLOYMENT_TARGET = 16.0;
+ WATCHOS_DEPLOYMENT_TARGET = 9.0;
};
name = Debug;
};
@@ -248,13 +255,20 @@
);
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = Daylight.xcodeproj/Daylight_Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
+ MACOSX_DEPLOYMENT_TARGET = 11.0;
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = Daylight;
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator";
+ SUPPORTS_MACCATALYST = NO;
+ TARGETED_DEVICE_FAMILY = "1,2";
TARGET_NAME = Daylight;
+ TVOS_DEPLOYMENT_TARGET = 16.0;
+ WATCHOS_DEPLOYMENT_TARGET = 9.0;
};
name = Release;
};
@@ -297,10 +311,12 @@
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 0.1.0;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-DXcode";
@@ -309,7 +325,7 @@
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
USE_HEADERMAP = NO;
};
name = Debug;
@@ -319,9 +335,11 @@
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
+ CURRENT_PROJECT_VERSION = 0.1.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_OPTIMIZATION_LEVEL = s;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_SWIFT_FLAGS = "-DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -329,7 +347,7 @@
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_OPTIMIZATION_LEVEL = "-O";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
USE_HEADERMAP = NO;
};
name = Release;
diff --git a/Daylight.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Daylight.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Daylight.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Example/DaylightExample/DaylightExample.xcodeproj/project.pbxproj b/Example/DaylightExample/DaylightExample.xcodeproj/project.pbxproj
index f9f1d99..f8a93c0 100644
--- a/Example/DaylightExample/DaylightExample.xcodeproj/project.pbxproj
+++ b/Example/DaylightExample/DaylightExample.xcodeproj/project.pbxproj
@@ -123,6 +123,7 @@
TargetAttributes = {
5B7EA00A1EA84DC900B58F3A = {
CreatedOnToolsVersion = 8.2.1;
+ LastSwiftMigration = 0920;
ProvisioningStyle = Automatic;
};
};
@@ -339,7 +340,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.emergencestudios.DaylightExample;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -353,7 +354,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.emergencestudios.DaylightExample;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
};
name = Release;
};
@@ -376,6 +377,7 @@
5B7EA01F1EA84DC900B58F3A /* Release */,
);
defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
diff --git a/Example/DaylightExample/DaylightExample/ViewController.swift b/Example/DaylightExample/DaylightExample/ViewController.swift
index eeddefa..08a8648 100644
--- a/Example/DaylightExample/DaylightExample/ViewController.swift
+++ b/Example/DaylightExample/DaylightExample/ViewController.swift
@@ -43,11 +43,11 @@ class ViewController: UIViewController {
let date = Date()
let loc = Location(tz: timeZone, coords: location.coordinate)
- let sunrise = date.timeOf(.sunrise, at: loc)
- let noon = date.timeOf(.noon, at: loc)
- let sunset = date.timeOf(.sunset, at: loc)
- let nextSunrise = date.timeOfNext(.sunrise, at: loc)
- let nextSunset = date.timeOfNext(.sunset, at: loc)
+ let sunrise = try? date.timeOf(.sunrise, at: loc)
+ let noon = try? date.timeOf(.noon, at: loc)
+ let sunset = try? date.timeOf(.sunset, at: loc)
+ let nextSunrise = try? date.timeOfNext(.sunrise, at: loc)
+ let nextSunset = try? date.timeOfNext(.sunset, at: loc)
let numberFormatter = NumberFormatter()
numberFormatter.maximumFractionDigits = 3
@@ -58,11 +58,11 @@ class ViewController: UIViewController {
let labelStrings = [
"Lon: \(latString)º Lat: \(lonString)º",
"Timezone: \(timeZone.identifier)",
- "Sunrise: \(dateFormatter.string(from: sunrise))",
- "Solar Noon: \(dateFormatter.string(from: noon))",
- "Sunset: \(dateFormatter.string(from: sunset))",
- "Next Sunrise: \(dateFormatter.string(from: nextSunrise))",
- "Next Sunset: \(dateFormatter.string(from: nextSunset))"
+ "Sunrise: \(dateFormatter.string(from: sunrise!))",
+ "Solar Noon: \(dateFormatter.string(from: noon!))",
+ "Sunset: \(dateFormatter.string(from: sunset!))",
+ "Next Sunrise: \(dateFormatter.string(from: nextSunrise!))",
+ "Next Sunset: \(dateFormatter.string(from: nextSunset!))"
]
for view in stackView.subviews {
diff --git a/Example/DaylightExample/Pods/Pods.xcodeproj/project.pbxproj b/Example/DaylightExample/Pods/Pods.xcodeproj/project.pbxproj
index cc47ac2..7b514c1 100644
--- a/Example/DaylightExample/Pods/Pods.xcodeproj/project.pbxproj
+++ b/Example/DaylightExample/Pods/Pods.xcodeproj/project.pbxproj
@@ -243,6 +243,11 @@
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0700;
+ TargetAttributes = {
+ 38D4BD3525C035213ABCD2FAA6DE0F70 = {
+ LastSwiftMigration = 0920;
+ };
+ };
};
buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
compatibilityVersion = "Xcode 3.2";
@@ -334,6 +339,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 09D23E3ADA40F0B48BA9CDCD3B2EC0FE /* Daylight.xcconfig */;
buildSettings = {
+ APPLICATION_EXTENSION_API_ONLY = YES;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
@@ -356,7 +362,7 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -442,6 +448,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 09D23E3ADA40F0B48BA9CDCD3B2EC0FE /* Daylight.xcconfig */;
buildSettings = {
+ APPLICATION_EXTENSION_API_ONLY = YES;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
@@ -463,7 +470,7 @@
PRODUCT_NAME = Daylight;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
diff --git a/Package.swift b/Package.swift
index e6418c3..277e4a4 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,5 +1,27 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
import PackageDescription
let package = Package(
- name: "Daylight"
+ name: "Daylight",
+ platforms: [.iOS(.v13), .macOS(.v10_15)],
+ products: [
+ // Products define the executables and libraries produced by a package, and make them visible to other packages.
+ .library(
+ name: "Daylight",
+ targets: ["Daylight"]),
+ ],
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages which this package depends on.
+ .target(
+ name: "Daylight",
+ dependencies: []),
+ ],
+ swiftLanguageVersions: [.v5]
)
diff --git a/Sources/Daylight.swift b/Sources/Daylight/Daylight.swift
similarity index 69%
rename from Sources/Daylight.swift
rename to Sources/Daylight/Daylight.swift
index 6d55fe2..74e5fb8 100644
--- a/Sources/Daylight.swift
+++ b/Sources/Daylight/Daylight.swift
@@ -8,6 +8,11 @@
import Foundation
import CoreLocation
+public enum SolarEventError: Error {
+ case neverRise
+ case neverSet
+}
+
public enum SolarEvent {
case sunrise
case noon
@@ -59,69 +64,68 @@ public struct Day {
self.day = day
}
- public func timeOf(_ solarEvent: SolarEvent, at location: Location) -> Date {
+ public func timeOf(_ solarEvent: SolarEvent, at location: Location) throws -> Date {
let components = DateComponents(year: year, month: month, day: day)
let calendar = Calendar.with(tz: location.tz)
let inputDate = calendar.date(from: components)!
- return inputDate.timeOf(solarEvent, at: location)
+ return try inputDate.timeOf(solarEvent, at: location)
}
}
public extension Date {
- public func timeOf(_ solarEvent: SolarEvent, at location: Location) -> Date {
+ func timeOf(_ solarEvent: SolarEvent, at location: Location) throws -> Date {
switch solarEvent {
case .sunrise, .civilDawn, .nauticalDawn, .astronomicalDawn:
- return calculateDawn(location: location.coords,
- solarElevation: solarEvent.elevation.rawValue,
- timezone: location.tz)
+ return try calculateDawn(location: location.coords,
+ solarElevation: solarEvent.elevation.rawValue,
+ timezone: location.tz)
case .sunset, .civilDusk, .nauticalDusk, .astronomicalDusk:
- return calculateDusk(location: location.coords,
- solarElevation: solarEvent.elevation.rawValue,
- timezone: location.tz)
+ return try calculateDusk(location: location.coords,
+ solarElevation: solarEvent.elevation.rawValue,
+ timezone: location.tz)
case .noon:
- return calculateNoon(location: location.coords,
+ return try calculateNoon(location: location.coords,
timezone: location.tz)
}
}
- public func timeOfNext(_ solarEvent: SolarEvent, at location: Location) -> Date {
- var time = self.timeOf(solarEvent, at: location)
+ func timeOfNext(_ solarEvent: SolarEvent, at location: Location) throws -> Date {
+ var time = try timeOf(solarEvent, at: location)
if self >= time {
- time = self.dayAfter.timeOf(solarEvent, at: location)
+ time = try dayAfter.timeOf(solarEvent, at: location)
}
return time
}
private func calculateDawn(location: CLLocationCoordinate2D,
solarElevation: Float64,
- timezone: TimeZone) -> Date {
+ timezone: TimeZone) throws -> Date {
let midnight = self.atMidnight(timeZone: timezone)
let julianDate = midnight.julianTz(timezone)
- let sunriseUTCMins = julianDate.sunriseUTC(location: location, solarElevation: solarElevation)
+ let sunriseUTCMins = try julianDate.sunriseUTC(location: location, solarElevation: solarElevation)
return self.dateFromTimeUTC(timeUTCMins: sunriseUTCMins, timezone: timezone)
}
private func calculateDusk(location: CLLocationCoordinate2D,
solarElevation: Float64,
- timezone: TimeZone) -> Date {
+ timezone: TimeZone) throws -> Date {
let midnight = self.atMidnight(timeZone: timezone)
let julianDate = midnight.julianTz(timezone)
- let duskUTCMins = julianDate.sunsetUTC(location: location, solarElevation: solarElevation)
+ let duskUTCMins = try julianDate.sunsetUTC(location: location, solarElevation: solarElevation)
return self.dateFromTimeUTC(timeUTCMins: duskUTCMins, timezone: timezone)
}
private func calculateNoon(location: CLLocationCoordinate2D,
- timezone: TimeZone) -> Date {
-
- let sunrise = calculateDawn(location: location,
+ timezone: TimeZone) throws -> Date {
+ let sunrise = try calculateDawn(location: location,
solarElevation: SolarEvent.sunrise.elevation.rawValue,
timezone: timezone)
- let sunset = calculateDusk(location: location,
+ let sunset = try calculateDusk(location: location,
solarElevation: SolarEvent.sunset.elevation.rawValue,
timezone: timezone)
let dayLength = sunset.timeIntervalSince(sunrise)
diff --git a/Sources/DaylightAstronomy.swift b/Sources/Daylight/DaylightAstronomy.swift
similarity index 82%
rename from Sources/DaylightAstronomy.swift
rename to Sources/Daylight/DaylightAstronomy.swift
index 80e1b80..49aa528 100644
--- a/Sources/DaylightAstronomy.swift
+++ b/Sources/Daylight/DaylightAstronomy.swift
@@ -134,7 +134,7 @@ internal extension JulianDate {
private typealias HourAngleFunction = (
_ latitude: Float64,
_ solarDeclination: Float64,
- _ solarElevation: Float64) -> Float64
+ _ solarElevation: Float64) throws -> Float64
// Purpose: calculate the Universal Coordinated Time (UTC) of the given solar position
// for the given day at the given location on earth
@@ -143,14 +143,14 @@ internal extension JulianDate {
private func calculateTimeUTCatHourAngle(location: CLLocationCoordinate2D,
solarElevation: Float64,
- hourAngleFunction: @escaping HourAngleFunction ) -> Float64 {
+ hourAngleFunction: @escaping HourAngleFunction ) throws -> Float64 {
let longitude = location.longitude * -1
- func calculateTime(from centuries: JulianCenturies) -> Float64 {
+ func calculateTime(from centuries: JulianCenturies) throws -> Float64 {
let eqTime = centuries.equationOfTime
let declination = centuries.declinationOfSun
- let hourAngle = hourAngleFunction(location.latitude, declination, solarElevation)
+ let hourAngle = try hourAngleFunction(location.latitude, declination, solarElevation)
let delta = longitude - hourAngle.radToDeg
let timeDiff = delta * 4.0
return 720.0 + timeDiff - eqTime
@@ -162,23 +162,23 @@ internal extension JulianDate {
// First Pass
- let timeUTC = calculateTime(from: noonTime)
+ let timeUTC = try calculateTime(from: noonTime)
// Second Pass
let newTime = (JulianDate.from(centuries: centuries) + (timeUTC/1440.0)).centuries
- let finalTimeUTC = calculateTime(from: newTime)
+ let finalTimeUTC = try calculateTime(from: newTime)
return finalTimeUTC
}
- func sunriseUTC(location: CLLocationCoordinate2D, solarElevation: Float64) -> Float64 {
- return calculateTimeUTCatHourAngle(location: location,
- solarElevation: solarElevation,
- hourAngleFunction: hourAngleOfSunrise)
+ func sunriseUTC(location: CLLocationCoordinate2D, solarElevation: Float64) throws -> Float64 {
+ return try calculateTimeUTCatHourAngle(location: location,
+ solarElevation: solarElevation,
+ hourAngleFunction: hourAngleOfSunrise)
}
- func sunsetUTC(location: CLLocationCoordinate2D, solarElevation: Float64) -> Float64 {
- return calculateTimeUTCatHourAngle(location: location,
+ func sunsetUTC(location: CLLocationCoordinate2D, solarElevation: Float64) throws -> Float64 {
+ return try calculateTimeUTCatHourAngle(location: location,
solarElevation: solarElevation,
hourAngleFunction: hourAngleOfSunset)
}
@@ -189,7 +189,7 @@ internal extension JulianDate {
internal extension Date {
- internal func dateFromTimeUTC(timeUTCMins: Float64, timezone: TimeZone) -> Date {
+ func dateFromTimeUTC(timeUTCMins: Float64, timezone: TimeZone) -> Date {
var localCalendar = Calendar(identifier: .gregorian)
localCalendar.timeZone = timezone
@@ -218,26 +218,41 @@ private func refractiveCorrection(solarElevation: Float64) -> Float64 {
}
}
-private func hourAngleOfSunrise(latitude: Float64, solarDeclination: Float64, solarElevation: Float64) -> Float64 {
+private func hourAngleOfSunrise(latitude: Float64, solarDeclination: Float64, solarElevation: Float64) throws -> Float64 {
let latRad = latitude.degToRad
let sdRad = solarDeclination.degToRad
let correction = refractiveCorrection(solarElevation: solarElevation)
+ let cosH = cos((90+correction).degToRad)/(cos(latRad)*cos(sdRad)) - tan(latRad)*tan(sdRad)
+
+ if cosH > 1 {
+ throw SolarEventError.neverRise
+ }
+ if cosH < -1 {
+ throw SolarEventError.neverSet
+ }
- return (acos(cos((90+correction).degToRad)/(cos(latRad)*cos(sdRad)) - tan(latRad)*tan(sdRad)))
+ return (acos(cosH))
}
-private func hourAngleOfSunset(latitude: Float64, solarDeclination: Float64, solarElevation: Float64) -> Float64 {
+private func hourAngleOfSunset(latitude: Float64, solarDeclination: Float64, solarElevation: Float64) throws -> Float64 {
let latRad = latitude.degToRad
let sdRad = solarDeclination.degToRad
let correction = refractiveCorrection(solarElevation: solarElevation)
- let hourAngle = acos(
- cos((90.0 + correction).degToRad) /
- (cos(latRad) * cos(sdRad)) -
- (tan(latRad) * tan(sdRad))
- )
+ let cosH = cos((90.0 + correction).degToRad) /
+ (cos(latRad) * cos(sdRad)) -
+ (tan(latRad) * tan(sdRad))
+
+ if cosH > 1 {
+ throw SolarEventError.neverRise
+ }
+ if cosH < -1 {
+ throw SolarEventError.neverSet
+ }
+
+ let hourAngle = acos(cosH)
return -hourAngle
}
diff --git a/Sources/DaylightUtilities.swift b/Sources/Daylight/DaylightUtilities.swift
similarity index 100%
rename from Sources/DaylightUtilities.swift
rename to Sources/Daylight/DaylightUtilities.swift