init
This commit is contained in:
parent
d4b3fe6668
commit
1b0d3cd576
17
README.md
17
README.md
@ -1,3 +1,16 @@
|
||||
# sunset
|
||||
# Calculating sunrise/sunset times for a given location
|
||||
|
||||
Based on algorithm by United Stated Naval Observatory, Washington
|
||||
|
||||
https://edwilliams.org/sunrise_sunset_algorithm.htm
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
local sun = require('sun')
|
||||
|
||||
sunrise, sunset,length = sun.get('2025-05-25 21:00:14+03',54.314192, 48.403132)
|
||||
|
||||
```
|
||||
|
||||
|
||||
Калькулятор времен восхода и заката Солнца по классическому алгоритму
|
||||
106
sun.lua
Normal file
106
sun.lua
Normal file
@ -0,0 +1,106 @@
|
||||
-- Module for calculating sunrise/sunset times for a given location
|
||||
-- Based on algorithm by United Stated Naval Observatory, Washington
|
||||
-- Link: https://edwilliams.org/sunrise_sunset_algorithm.htm
|
||||
-- @author Alexander Yakushev
|
||||
-- @author Alexander Pavlov (Zoviet)
|
||||
-- @license CC0 http://creativecommons.org/about/cc0
|
||||
|
||||
local date = require("date")
|
||||
|
||||
local _M = {}
|
||||
|
||||
local cosH_rise,RA_rise,cosH_set,RA_set,sunrise,sunset,length
|
||||
|
||||
local current_time = nil
|
||||
local srs_args
|
||||
local rad = math.rad
|
||||
local deg = math.deg
|
||||
local floor = math.floor
|
||||
local frac = function(n) return n - floor(n) end
|
||||
local cos = function(d) return math.cos(rad(d)) end
|
||||
local acos = function(d) return deg(math.acos(d)) end
|
||||
local sin = function(d) return math.sin(rad(d)) end
|
||||
local asin = function(d) return deg(math.asin(d)) end
|
||||
local tan = function(d) return math.tan(rad(d)) end
|
||||
local atan = function(d) return deg(math.atan(d)) end
|
||||
|
||||
local function days(utc)
|
||||
local UT = 0
|
||||
if utc then
|
||||
UT = tonumber(string.match(utc, '%+(%d+)')) or 0
|
||||
utc = date(utc)
|
||||
else
|
||||
utc = date():toutc()
|
||||
end
|
||||
return utc:getyearday(), UT
|
||||
end
|
||||
|
||||
local function fit_into_range(val, min, max)
|
||||
local range = max - min
|
||||
local count
|
||||
if val < min then
|
||||
count = floor((min - val) / range) + 1
|
||||
return val + count * range
|
||||
elseif val >= max then
|
||||
count = floor((val - max) / range) + 1
|
||||
return val - count * range
|
||||
else
|
||||
return val
|
||||
end
|
||||
end
|
||||
|
||||
local function calc(t,lat,lon,zenith)
|
||||
local M = (0.9856 * t) - 3.289
|
||||
local L = fit_into_range(M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634, 0, 360)
|
||||
local RA = fit_into_range(atan(0.91764 * tan(L)), 0, 360) -- Прямое восхождение Солнца
|
||||
local Lquadrant = floor(L / 90) * 90
|
||||
local RAquadrant = floor(RA / 90) * 90
|
||||
RA = RA + Lquadrant - RAquadrant
|
||||
RA = RA / 15
|
||||
local sinDec = 0.39782 * sin(L)
|
||||
local cosDec = cos(asin(sinDec))
|
||||
local cosH = (cos(zenith) - (sinDec * sin(lat))) / (cosDec * cos(lon))
|
||||
return cosH,RA
|
||||
end
|
||||
|
||||
local function sun(utc,lat,lon,zenith)
|
||||
zenith = zenith or 90.5--90.83
|
||||
local days,UT = days(utc)
|
||||
local lng_hour = lon/15
|
||||
local t_rise, t_set
|
||||
local t_rise = days + ((6 - lng_hour) / 24)
|
||||
local t_set = days + ((18 - lng_hour) / 24)
|
||||
cosH_rise,RA_rise = calc(t_rise,lat,lon,zenith) -- часовой угол
|
||||
cosH_set,RA_set = calc(t_set,lat,lon,zenith)
|
||||
local H_rise,H_set,sunrise_i,sunset_i
|
||||
if cosH_rise > 1 then sunrise = nil
|
||||
else
|
||||
H_rise = (360 - acos(cosH_rise))/15
|
||||
sunrise = H_rise + RA_rise - (0.06571 * t_rise) - 6.622
|
||||
sunrise_i = fit_into_range(sunrise - lng_hour, 0, 24) + UT
|
||||
sunrise = date():sethours(0, 0, 0):addhours(sunrise_i):fmt('%Y-%m-%d %T')
|
||||
end
|
||||
if cosH_set < -1 then sunset = nil
|
||||
else
|
||||
H_set = acos(cosH_set)/15
|
||||
sunset = H_set + RA_set - (0.06571 * t_set) - 6.622
|
||||
sunset_i = fit_into_range(sunset - lng_hour, 0, 24) + UT
|
||||
sunset = date():sethours(0, 0, 0):addhours(sunset_i):fmt('%Y-%m-%d %T')
|
||||
end
|
||||
if sunset and sunrise then length = sunset_i - sunrise_i end
|
||||
end
|
||||
|
||||
--Sun's zenith for sunrise/sunset:
|
||||
|
||||
-- zenith:
|
||||
-- offical = 90 degrees 50'
|
||||
-- civil = 96 degrees
|
||||
-- nautical = 102 degrees
|
||||
-- astronomical = 108 degrees
|
||||
|
||||
function _M.get(utc,lat,lon,zenith)
|
||||
sun(utc,lat,lon,zenith)
|
||||
return sunrise, sunset,length
|
||||
end
|
||||
|
||||
return _M
|
||||
Loading…
x
Reference in New Issue
Block a user