onekiloparsec / SwiftAA

The most comprehensive collection of accurate astronomical algorithms in (C++, Objective-C and) Swift.
http://www.onekiloparsec.dev/
MIT License
171 stars 31 forks source link

Calculate daytime hours based on location #96

Closed vincentneo closed 3 years ago

vincentneo commented 3 years ago

Hi,

I am currently trying to implement a feature in my app that calculates the daytime hours at a specific coordinate and date. Is it possible to do so using this library? I'm not really good with astronomy stuff and algorithms, hence, I am not sure if this is the right tool for the job, or that its hidden somewhere, and I couldn't find it.

Thank you in advance!

onekiloparsec commented 3 years ago

Hi. Yes, you can use SwiftAA for that. Grab the Earth object, and compute the twilights times. You will get precise times of sunrise, sunset etc. You must choose the precise altitude of the sun (you may start with 0):

For instance:

let paris = GeographicCoordinates(positivelyWestwardLongitude: Degree(.minus, 2, 21, 07), latitude: Degree(.plus, 48, 51, 24))
let jd = JulianDay(year: 2017, month: 6, day: 21)
let times = Earth(julianDay: jd).twilights(forSunAltitude: 0, coordinates: paris)
vincentneo commented 3 years ago

Alright! Thank you

vincentneo commented 3 years ago

Hi @onekiloparsec

So I tried with this code:

let singapore = GeographicCoordinates(CLLocation(latitude: 1.290, longitude: 103.852))
let today = JulianDay(year: 2020, month: 9, day: 6)
let todayTimes = Earth(julianDay: today).twilights(forSunAltitude: 0, coordinates: singapore)

let timeFormatter = DateComponentsFormatter()
timeFormatter.unitsStyle = .short
timeFormatter.allowedUnits = [.hour, .minute, .second]
timeFormatter.allowsFractionalUnits = false

print(timeFormatter.string(from: todayTimes.set!.date, to: todayTimes.rise!.date)!) 
// 11 hr, 58 min, 43 sec

and noticed that the daytime hours to be a little off, compared to https://www.timeanddate.com/sun/@1.290,103.852, which gave 12:07:37 instead of 11:58:43.

Did I do something wrong, or are the values online inaccurate?

Thank you.

onekiloparsec commented 3 years ago

Hello Vincent. You did perfectly correct, but it all depends on the details. For instance, for the standard sunAltitude (ArcMinute(-50).inDegrees in the Sun class), you get a result that is 6 minutes different (11 hr, 52 min, 1 sec).

It is hard to say which one is correct. I have no idea how timeanddate.com compute their values. It would be nice to discuss with them and compare (there is no reason at all theirs should be "wrong").

Please note that due to the recent issue #95 , I have made 2 changes that will impact you.

vincentneo commented 3 years ago

Alright then, thanks for the guidance!

vincentneo commented 3 years ago

Looks like if I were to use TwilightSunAltitude.upperLimbOnHorizonWithRefraction or -0.833, I would get similar results from online sources, just about 1 minute away.

onekiloparsec commented 3 years ago

Wonderful, thanks for sharing. I'll try to add another unit test then to validate that in the code.