我喜欢追踪日出和日落时间。过去几年,我一直使用我喜爱的编程语言中流行的库编写的小程序来实现这一点。最近两个月里,我比平时更经常地跟踪这些时间,并注意到在春分的那天,日出时间比前一天提前了八分钟!我知道这是不可能的,于是与NOAA进行比较,发现我的升起和降落时间已经错误了好几天,并且事实上,大部分时间似乎都偏了约一分钟。
此时此刻,我想自己实现这些计算。有哪些可用的算法或公式可以进行这种计算呢?
我喜欢追踪日出和日落时间。过去几年,我一直使用我喜爱的编程语言中流行的库编写的小程序来实现这一点。最近两个月里,我比平时更经常地跟踪这些时间,并注意到在春分的那天,日出时间比前一天提前了八分钟!我知道这是不可能的,于是与NOAA进行比较,发现我的升起和降落时间已经错误了好几天,并且事实上,大部分时间似乎都偏了约一分钟。
此时此刻,我想自己实现这些计算。有哪些可用的算法或公式可以进行这种计算呢?
日出和日落的定义因国家不同而异。例如,在ephem
中,“日出和日落被定义为当物体的上肢接触地平线时刻(也就是当物体的高度加半径等于零时)”【PyEphem 快速参考】。
#!/usr/bin/env python
import datetime
import ephem # to install, run `pip install pyephem`
o = ephem.Observer()
o.lat, o.long, o.date = '34:3', '-118:15', datetime.datetime.utcnow()
sun = ephem.Sun(o)
print "Los Angeles"
print "sunrise:", o.next_rising(sun), "UTC"
print "sunset:",o.next_setting(sun), "UTC"
Los Angeles, CA
sunrise: 2010/3/30 13:42:43 UTC
sunset: 2010/3/30 02:11:50 UTC
如果是开源库,你可以修复它而不是创建一个新的带有新错误的库。
要在5分钟范围内获得准确时间,您需要考虑“哪个”日落时间。点击此处了解更多信息。
您是想知道太阳底部接触地平线的时间还是太阳顶部下降到地平线以下的时间?
太阳穿过地平线需要2分钟的时间。
在1分钟以下的范围内,您还需要考虑大气折射的影响。
我用Ruby编写了这个程序来计算时间方程。
include Math
# degrees to radians = PI/180
to_r = PI/180.0
#radians to degrees = 180/PI
to_d = 180.0/PI
puts "Day, Declination, EofT"
# test a celestial year worth of values.
for jday in 1..366
et = -7.633 * sin(jday * (2 * PI)/365.24) + 9.65 * sin((jday - 78) * 180/92 * to_r)
a_sin = sin(23.433 * to_r) * sin((2 * PI/366) * (jday - 81))
declination = asin(a_sin) * to_d
puts "#{jday}, #{declination}, #{et}"
end
对于上述方程:
# center disk and refraction factor have been considered.
cos_omega = sin(-0.83 * to_r) - tan(latitude * to_r) * tan(declination * to_r)
semi_diurnal_arc = acos(cos_omega)
这个网站专门介绍了这方面的知识:http://www.analemma.com/
我在这个NOAA页面的技术定义和计算细节部分看到了一些有趣的东西,但我相信你已经读过了。
对于SO问题“给定时间和纬度/经度的太阳位置”,上面提到的可能是你所需要的全部内容。
顺便说一句(它并没有直接回答你的问题),你不能拉取NOAA数据并将其用作查找表而不是计算吗?存储成本现在相对较低。