mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 22:12:50 -05:00
123 lines
3.6 KiB
Go
123 lines
3.6 KiB
Go
package wayland
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
degToRad = math.Pi / 180.0
|
|
radToDeg = 180.0 / math.Pi
|
|
)
|
|
|
|
type SunCondition int
|
|
|
|
const (
|
|
SunNormal SunCondition = iota
|
|
SunMidnightSun
|
|
SunPolarNight
|
|
)
|
|
|
|
type SunTimes struct {
|
|
Dawn time.Time
|
|
Sunrise time.Time
|
|
Sunset time.Time
|
|
Night time.Time
|
|
}
|
|
|
|
func daysInYear(year int) int {
|
|
if (year%4 == 0 && year%100 != 0) || year%400 == 0 {
|
|
return 366
|
|
}
|
|
return 365
|
|
}
|
|
|
|
func dateOrbitAngle(t time.Time) float64 {
|
|
return 2 * math.Pi / float64(daysInYear(t.Year())) * float64(t.YearDay()-1)
|
|
}
|
|
|
|
func equationOfTime(orbitAngle float64) float64 {
|
|
return 4 * (0.000075 +
|
|
0.001868*math.Cos(orbitAngle) -
|
|
0.032077*math.Sin(orbitAngle) -
|
|
0.014615*math.Cos(2*orbitAngle) -
|
|
0.040849*math.Sin(2*orbitAngle))
|
|
}
|
|
|
|
func sunDeclination(orbitAngle float64) float64 {
|
|
return 0.006918 -
|
|
0.399912*math.Cos(orbitAngle) +
|
|
0.070257*math.Sin(orbitAngle) -
|
|
0.006758*math.Cos(2*orbitAngle) +
|
|
0.000907*math.Sin(2*orbitAngle) -
|
|
0.002697*math.Cos(3*orbitAngle) +
|
|
0.00148*math.Sin(3*orbitAngle)
|
|
}
|
|
|
|
func sunHourAngle(latRad, declination, targetSunRad float64) float64 {
|
|
return math.Acos(math.Cos(targetSunRad)/
|
|
math.Cos(latRad)*math.Cos(declination) -
|
|
math.Tan(latRad)*math.Tan(declination))
|
|
}
|
|
|
|
func hourAngleToSeconds(hourAngle, eqtime float64) float64 {
|
|
return radToDeg * (4.0*math.Pi - 4*hourAngle - eqtime) * 60
|
|
}
|
|
|
|
func sunCondition(latRad, declination float64) SunCondition {
|
|
signLat := latRad >= 0
|
|
signDecl := declination >= 0
|
|
if signLat == signDecl {
|
|
return SunMidnightSun
|
|
}
|
|
return SunPolarNight
|
|
}
|
|
|
|
func CalculateSunTimesWithTwilight(lat, lon float64, date time.Time, elevTwilight, elevDaylight float64) (SunTimes, SunCondition) {
|
|
latRad := lat * degToRad
|
|
elevTwilightRad := (90.833 - elevTwilight) * degToRad
|
|
elevDaylightRad := (90.833 - elevDaylight) * degToRad
|
|
|
|
utc := date.UTC()
|
|
orbitAngle := dateOrbitAngle(utc)
|
|
decl := sunDeclination(orbitAngle)
|
|
eqtime := equationOfTime(orbitAngle)
|
|
|
|
haTwilight := sunHourAngle(latRad, decl, elevTwilightRad)
|
|
haDaylight := sunHourAngle(latRad, decl, elevDaylightRad)
|
|
|
|
if math.IsNaN(haTwilight) || math.IsNaN(haDaylight) {
|
|
cond := sunCondition(latRad, decl)
|
|
return SunTimes{}, cond
|
|
}
|
|
|
|
dayStart := time.Date(utc.Year(), utc.Month(), utc.Day(), 0, 0, 0, 0, time.UTC)
|
|
lonOffset := time.Duration(-lon*4) * time.Minute
|
|
|
|
dawnSecs := hourAngleToSeconds(math.Abs(haTwilight), eqtime)
|
|
sunriseSecs := hourAngleToSeconds(math.Abs(haDaylight), eqtime)
|
|
sunsetSecs := hourAngleToSeconds(-math.Abs(haDaylight), eqtime)
|
|
nightSecs := hourAngleToSeconds(-math.Abs(haTwilight), eqtime)
|
|
|
|
return SunTimes{
|
|
Dawn: dayStart.Add(time.Duration(dawnSecs)*time.Second + lonOffset).In(date.Location()),
|
|
Sunrise: dayStart.Add(time.Duration(sunriseSecs)*time.Second + lonOffset).In(date.Location()),
|
|
Sunset: dayStart.Add(time.Duration(sunsetSecs)*time.Second + lonOffset).In(date.Location()),
|
|
Night: dayStart.Add(time.Duration(nightSecs)*time.Second + lonOffset).In(date.Location()),
|
|
}, SunNormal
|
|
}
|
|
|
|
func CalculateSunTimes(lat, lon float64, date time.Time) SunTimes {
|
|
times, cond := CalculateSunTimesWithTwilight(lat, lon, date, -6.0, 3.0)
|
|
switch cond {
|
|
case SunMidnightSun:
|
|
dayStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
|
|
dayEnd := dayStart.Add(24*time.Hour - time.Second)
|
|
return SunTimes{Dawn: dayStart, Sunrise: dayStart, Sunset: dayEnd, Night: dayEnd}
|
|
case SunPolarNight:
|
|
dayStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
|
|
return SunTimes{Dawn: dayStart, Sunrise: dayStart, Sunset: dayStart, Night: dayStart}
|
|
}
|
|
return times
|
|
}
|