Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
ee8fc7b
Fixed formatting and style in Utils
Aug 28, 2025
9fbc093
Fixed formatting and style in SunElevationEvents and Utils.
Aug 28, 2025
36302de
Fixed formatting and style in Sun.
Aug 28, 2025
cfe102a
Fixed formatting and style in HorizonCoordinates.
Aug 28, 2025
61174e8
Fixed formatting and style in HMS.
Aug 28, 2025
aa20431
Fixed formatting and style in Extensions.
Aug 28, 2025
60744b1
Fixed formatting and style in EquatorialCoordinates.
Aug 28, 2025
d170ebd
Fixed formatting and style in EclipticCoordinates.
Aug 28, 2025
216bf34
Fixed formatting and style in DMS.
Aug 28, 2025
e76b871
Fixed formatting and style in Angle.
Aug 28, 2025
1c127e6
Fixed formatting and style in UT_DMS.
Aug 28, 2025
7a3b826
Fixed formatting and style in UT_EclipticCoordinates.
Aug 28, 2025
9caf1a1
Fixed formatting and style in UT_EquatorialCoordinates.
Aug 28, 2025
8618626
Fixed formatting and style in UT_HMS.
Aug 28, 2025
e61c09c
Fixed formatting and style in UT_HorizonCoordinates.
Aug 28, 2025
39d16bf
Fixed formatting and style in UT_Sun.
Aug 28, 2025
3c0b9ed
Fixed formatting and style in UT_Utils. Completed first pass refactor…
Aug 28, 2025
63853dc
Added sun folder.
Sep 19, 2025
04c28b4
Created debugging utils file. Moved functions.
Sep 19, 2025
8474d85
Code cleanup.
Sep 19, 2025
4557f3d
Removed or shortened redundant comments.
Sep 19, 2025
2747da4
Applied consistent horizontal spacing style.
Sep 19, 2025
a748514
Applied consistent vertical spacing style.
Sep 19, 2025
769093c
Reorganized the order of sun event variables to be chronological.
Sep 19, 2025
58a4457
Cleaned up comments for computed sun event variables.
Sep 19, 2025
b30c9f3
Reorganized order of variables in refresh function.
Sep 19, 2025
9373a71
Reorganized order of get functions used in refresh to match order of …
Sep 19, 2025
553562b
Moved debugging utils into extension folder.
Sep 19, 2025
ab5a5d0
Moved equatable comformance into extension folder.
Sep 19, 2025
96e3c5c
Moved hashable comformance into extension folder.
Sep 19, 2025
0c81cb7
Extracted sun horizon coordinate calculation as nested function.
Sep 19, 2025
a15c219
Extracted sun equatorial coordinates calculation as nested function.
Sep 19, 2025
5550400
Extracted sun ecliptic coordinates calculation as nested function.
Sep 19, 2025
c4ac1cb
Added todo comment.
Sep 19, 2025
2365b0b
Parameterized calculateSunEclipticCoordinates function. Extracted nes…
Sep 19, 2025
3990efa
Parameterized calculateSunEquatorialCoordinates function. Extracted n…
Sep 19, 2025
ee5eed2
Parameterized calculateSunHorizonCoordinates function. Added comment …
Sep 19, 2025
a115b3e
Made horizontal spacing consistent.
Sep 19, 2025
d66cfaf
Removed redundant comments.
Sep 19, 2025
9df2962
Extracted calculateHorizonCoordinates function.
Sep 19, 2025
8d8b695
Added tracking to missing file.
Sep 19, 2025
6f0a17d
Added initial folder.
Sep 19, 2025
532080a
Tracked missing files.
Sep 19, 2025
c09a2e6
Created SunCoordinates.
Sep 19, 2025
d330fc3
Created private backing variable for sun coordinate related properties.
Sep 19, 2025
167399e
Extracted function calculateSunEclipticLongitude.
Sep 19, 2025
2a5222a
Extracted calculateLSTDecimal function.
Sep 19, 2025
3eac14c
Moved function closer to use.
Sep 19, 2025
6598754
Deleted unused function.
Sep 19, 2025
018e588
Added section marks.
Sep 19, 2025
7d797d9
Extracted variables from month events.
Sep 19, 2025
1a5495c
Extracted calculateCosineofSolarHourAngle function.
Sep 19, 2025
0c0574c
Extracted clampCosineOfSolarHourAngle function.
Sep 19, 2025
36f28e7
Extracted calculateSunriseSolarHourAngle function.
Sep 19, 2025
bbcb741
Extracted calculateSunsetSolarHourAngle function.
Sep 19, 2025
b10edaf
Slide variable closer to site of use.
Sep 19, 2025
7f60f95
Extracted calculateSeconds function.
Sep 19, 2025
ff95652
Extracted calculateUTCMinutes function.
Sep 19, 2025
8699e80
Extracted calculateSunriseSeconds function.
Sep 19, 2025
e4cc2bc
Extracted calculateSunsetSeconds function.
Sep 19, 2025
cf82f51
Extracted calculateDate function.
Sep 19, 2025
6185b63
Moved additional code into calculate seconds functions.
Sep 19, 2025
1ac8cb7
Added TODO.
Sep 19, 2025
c28e2ef
Created extension folder. Move date strideable extension into folder.
Sep 19, 2025
d57b601
Moved Calendar extension into folder.
Sep 19, 2025
dfafa3e
Renamed and moved file.
Sep 19, 2025
d5caadb
Added methods to SunCoordinates in preparation for sun methods refactor.
Sep 21, 2025
41939d3
Made code style in EclipticCoordinates consistent.
Sep 21, 2025
54f6329
Reorganized EquatorialCoordinates methods to follow a high to low lev…
Sep 21, 2025
3fd1f22
Moved sun constant sunEclipticLongitudePerigee into SunCoordinates.
Sep 22, 2025
fdf4409
Moved sun constant sunEclipticLongitudeAtTheEpoch into SunCoordinates.
Sep 22, 2025
84808cd
Moved function getSunMeanAnomaly into SunCoordinates.
Sep 22, 2025
bc2c1fe
Moved function calculateSunEclipticLongitude into SunCoordinates.
Sep 22, 2025
c3861f7
Adjust privacy level in SunCoordinates.
Sep 22, 2025
1ef3f5c
Parameterized function calculateLSTDecimal and moved it into SunCoord…
Sep 22, 2025
ec193f1
Moved getSunHorizonCoordinatesFrom function closer to where it's used.
Sep 22, 2025
03ad789
Extracted updateCoordinates method.
Sep 22, 2025
acbe306
Parameterized updateSunCoordinates method.
Sep 22, 2025
83e68dc
Moved calculateSunEclipticCoordinates into SunCoordinates.
Sep 22, 2025
c02b122
Moved calculateSunEquatorialCoordinates into SunCoordinates.
Sep 22, 2025
17a5018
Extracted nested function calculateSunHorizonCoordinates.
Sep 22, 2025
1b5478c
Updated getSunHorizonCoordinatesFrom to use extracted calculateSunHor…
Sep 22, 2025
ea7df77
Extracted calculateSunHorizonCoordinates into SunCoordinates.
Sep 22, 2025
7f9cfe5
Renamed function in SunCoordinates. Uncommented implementation of set…
Sep 22, 2025
0b58d6d
Replaced duplicated code in getSunHorizonCoordinatesFrom with getSunH…
Sep 22, 2025
9195224
Extracted function getSunHorizonCoordinates into SunCoordinates.
Sep 22, 2025
6b416f4
Adjusted privacy levels in SunCoordinates.
Sep 22, 2025
bcc1716
Changed the coordinate variables to be backed by the SunCoordinates o…
Sep 22, 2025
e545e73
Extracted setSunCoordinates function into SunCoordinates.
Sep 22, 2025
cacd932
Removed TODO comment.
Sep 22, 2025
b15550e
Removed TODO comment.
Sep 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions Sources/SunKit/Angle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.


import Foundation


public struct Angle: Equatable, Hashable, Codable, Sendable {

public static var zero: Angle = .init()

public init() {
Expand All @@ -30,11 +29,11 @@ public struct Angle: Equatable, Hashable, Codable, Sendable {
public init(radians: Double) {
_radians = radians
}

public init(degrees: Double) {
_radians = degrees * Double.pi / 180.0
}

public var degrees: Double {
get { _radians * 180.0 / Double.pi }
set { _radians = newValue * Double.pi / 180 }
Expand All @@ -54,5 +53,4 @@ public struct Angle: Equatable, Hashable, Codable, Sendable {
public static func radians(_ value: Double) -> Angle {
.init(radians: value)
}

}
21 changes: 10 additions & 11 deletions Sources/SunKit/DMS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@

import Foundation


/// DMS format to express angles
public struct DMS: Equatable, Hashable, Codable, Sendable {

public var degrees: Double
public var minutes: Double
public var seconds: Double
public var isANegativeZero: Bool


init(degrees: Double, minutes: Double, seconds: Double, isANegativeZero: Bool = false) {
init(
degrees: Double,
minutes: Double,
seconds: Double,
isANegativeZero: Bool = false
) {
self.degrees = degrees
self.minutes = minutes
self.seconds = seconds
Expand All @@ -36,8 +40,7 @@ public struct DMS: Equatable, Hashable, Codable, Sendable {

///From decimal it will create the corresponding angle in DMS format
/// - Parameter decimal: Decimal angle that will be converted in DMS format
public init(decimal: Double){

public init(decimal: Double) {
//Step1:
let sign = decimal < 0 ? -1 : 1
//Step2:
Expand All @@ -50,26 +53,23 @@ public struct DMS: Equatable, Hashable, Codable, Sendable {
let seconds = 60 * (60 * dec.truncatingRemainder(dividingBy: 1)).truncatingRemainder(dividingBy: 1)
//Step6:
degrees *= sign

if degrees == 0 && sign == -1 {
self.degrees = Double(degrees)
self.minutes = Double(minutes)
self.seconds = seconds
self.isANegativeZero = true
}
else{
} else {
self.degrees = Double(degrees)
self.minutes = Double(minutes)
self.seconds = seconds
self.isANegativeZero = false
}


}

/// It converts from DMS format to decimal
/// - Returns: DMS of the instance expressed in decimal format
public func dMS2Decimal() -> Double {

//Step1:
let sign: Double = degrees < 0 ? -1 : 1
//Step2:
Expand All @@ -86,7 +86,6 @@ public struct DMS: Equatable, Hashable, Codable, Sendable {
decimal *= sign

if isANegativeZero{

decimal *= -1
}

Expand Down
34 changes: 34 additions & 0 deletions Sources/SunKit/Extensions/Calendar+startOfYear.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Calendar+startOfYear.swift
//
//
// Copyright 2024 Leonardo Bertinelli, Davide Biancardi, Raffaele Fulgente, Clelia Iovine, Nicolas Mariniello, Fabio Pizzano
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation


extension Calendar {
func numberOfDaysSinceStartOfTheYear(for date: Date) -> Int {
let startOfTheYear: Date = startOfYear(date)
let startOfTheDay = startOfDay(for: date)
let numberOfDays = dateComponents([.day], from: startOfTheYear, to: startOfTheDay)

return numberOfDays.day! + 1
}

func startOfYear(_ date: Date) -> Date {
return self.date(from: self.dateComponents([.year], from: date))!
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// Extensions.swift
//
// Date+Strideable.swift
//
//
// Copyright 2024 Leonardo Bertinelli, Davide Biancardi, Raffaele Fulgente, Clelia Iovine, Nicolas Mariniello, Fabio Pizzano
//
Expand All @@ -18,7 +18,8 @@

import Foundation

//It consents us too loop between two dates for n as interval time

// Allows us to loop between two dates using interval time n.
extension Date: @retroactive Strideable {
public func distance(to other: Date) -> TimeInterval {
return other.timeIntervalSinceReferenceDate - self.timeIntervalSinceReferenceDate
Expand All @@ -27,42 +28,17 @@ extension Date: @retroactive Strideable {
func toString(_ timeZone: TimeZone) -> String {
let df = DateFormatter()
df.timeZone = timeZone
let custom = DateFormatter.dateFormat(fromTemplate: "MMdd HH:mm",
options: 0,
locale: Locale(identifier: "en"))
let custom = DateFormatter.dateFormat(
fromTemplate: "MMdd HH:mm",
options: 0,
locale: Locale(identifier: "en")
)
df.dateFormat = custom

return df.string(from: self)
}

public func advanced(by n: TimeInterval) -> Date {
return self + n
}
}

extension Calendar {
func numberOfDaysSinceStartOfTheYear(for date: Date) -> Int {
let startOfTheYear: Date = startOfYear(date)
let startOfTheDay = startOfDay(for: date)
let numberOfDays = dateComponents([.day], from: startOfTheYear, to: startOfTheDay)

return numberOfDays.day! + 1
}

func startOfYear(_ date: Date) -> Date {
return self.date(from: self.dateComponents([.year], from: date))!
}

}

extension TimeZone {

func offset(_ date: Date) -> Double {
let res =
Int(self.secondsFromGMT(for: date))
+ Int(self.daylightSavingTimeOffset(for: date))
- Int(Calendar.current.timeZone.secondsFromGMT(for: date))
- Int(Calendar.current.timeZone.daylightSavingTimeOffset(for: date))
return Double(res)/SECONDS_IN_ONE_HOUR

}
}
31 changes: 31 additions & 0 deletions Sources/SunKit/Extensions/TimeZone+offset.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// TimeZone+offset.swift
//
//
// Copyright 2024 Leonardo Bertinelli, Davide Biancardi, Raffaele Fulgente, Clelia Iovine, Nicolas Mariniello, Fabio Pizzano
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation


extension TimeZone {
func offset(_ date: Date) -> Double {
let res = Int(self.secondsFromGMT(for: date))
+ Int(self.daylightSavingTimeOffset(for: date))
- Int(Calendar.current.timeZone.secondsFromGMT(for: date))
- Int(Calendar.current.timeZone.daylightSavingTimeOffset(for: date))

return Double(res) / SECONDS_IN_ONE_HOUR
}
}
12 changes: 3 additions & 9 deletions Sources/SunKit/HMS.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// HMS.swift
//
//
//
// Copyright 2024 Leonardo Bertinelli, Davide Biancardi, Raffaele Fulgente, Clelia Iovine, Nicolas Mariniello, Fabio Pizzano
//
Expand All @@ -21,13 +21,11 @@ import Foundation

/// Time expressed in HMS format
public struct HMS: Equatable, Hashable, Codable, Sendable {

public var hours: Double
public var minutes: Double
public var seconds: Double

public init(from date: Date){

var calendar: Calendar = .init(identifier: .gregorian)
calendar.timeZone = .init(abbreviation: "GMT")!

Expand All @@ -37,14 +35,12 @@ public struct HMS: Equatable, Hashable, Codable, Sendable {
}

public init(hours: Double,minutes: Double,seconds: Double){

self.hours = hours
self.minutes = minutes
self.seconds = seconds
}

public init(decimal: Double){

//Step1:
let sign = decimal < 0 ? -1 : 1
//Step2:
Expand All @@ -57,17 +53,16 @@ public struct HMS: Equatable, Hashable, Codable, Sendable {
let seconds = 60 * (60 * dec.truncatingRemainder(dividingBy: 1)).truncatingRemainder(dividingBy: 1)
//Step6:
hours *= sign

self.hours = Double(hours)
self.minutes = Double(minutes)
self.seconds = seconds

}

/// It converts from HMS format to decimal
/// - Returns: HMS of the instance expressed in decimal format
public func hMS2Decimal() -> Double {

//Step3:
let dm: Double = Double(seconds / 60)
//Step4:
Expand All @@ -79,5 +74,4 @@ public struct HMS: Equatable, Hashable, Codable, Sendable {

return decimalHour
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,21 @@ import Foundation


public struct EclipticCoordinates: Equatable, Hashable, Codable, Sendable {

public static let obliquityOfTheEcliptic: Angle = .init(degrees: 23.439292)

public var eclipticLatitude: Angle //beta
public var eclipticLongitude: Angle //lambda

/// Converts ecliptic coordinatates to equatorial coordinates
/// - Returns: Equatorial coordinates of the instance
public func ecliptic2Equatorial() -> EquatorialCoordinates{

//Step4:
public func ecliptic2Equatorial() -> EquatorialCoordinates {
let tEclipticToEquatorial: Angle = .init(radians: sin(eclipticLatitude.radians) * cos(EclipticCoordinates.obliquityOfTheEcliptic.radians) + cos(eclipticLatitude.radians) * sin(EclipticCoordinates.obliquityOfTheEcliptic.radians) * sin(eclipticLongitude.radians))

//Step5:
let moonDeclination: Angle = .init(radians: asin(tEclipticToEquatorial.radians))

//Step6:
let yEclipticToEquatorial = sin(eclipticLongitude.radians) * cos(EclipticCoordinates.obliquityOfTheEcliptic.radians) - tan(eclipticLatitude.radians) * sin(EclipticCoordinates.obliquityOfTheEcliptic.radians)

//Step7:
let xEclipticToEquatorial = cos(eclipticLongitude.radians)

//Step8:
var r: Angle = .init(radians: atan(yEclipticToEquatorial / xEclipticToEquatorial))

//Step9:
switch (yEclipticToEquatorial >= 0,xEclipticToEquatorial >= 0){
switch (yEclipticToEquatorial >= 0, xEclipticToEquatorial >= 0) {

case (true, true):
break
Expand All @@ -58,7 +46,7 @@ public struct EclipticCoordinates: Equatable, Hashable, Codable, Sendable {
r.degrees += 180
}

let alfa: Angle = .init(degrees: r.degrees / 15)
let alfa: Angle = .init(degrees: r.degrees / 15)
let delta: Angle = .init(degrees: moonDeclination.degrees)

return .init(declination: delta, rightAscension: alfa)
Expand Down
Loading