使用ephem计算“太阳正午”,并转换为当地时间
我查看了这里关于使用ephem库来计算日出和日落的例子,发现这些都运行得很好。
但是,当我尝试计算这两个时间的中间点时,就遇到了问题。以下是我现在的代码:
import datetime
import ephem
o = ephem.Observer()
o.lat, o.long, o.date = '37.0625', '-95.677068', datetime.datetime.utcnow()
sun = ephem.Sun(o)
print "sunrise:", o.previous_rising(sun), "UTC"
print "sunset:",o.next_setting(sun), "UTC"
print "noon:",datetime.timedelta((o.next_setting(sun)-o.previous_rising(sun))/2)
我得到的结果是:
日出时间:2010年11月2日 12:47:40 UTC
日落时间:2010年11月2日 23:24:25 UTC
中午时间:5:18:22.679044
我在这里卡住了。我是个Python初学者,老实说,编程水平也不高。
任何建议都非常欢迎!
4 个回答
0
两个数字的平均值是把这两个数字相加,然后再除以二,而不是把白天的长度除以二。如果你把这个结果加到 o.previous_rising(sun) 上,也可以得到结果,但这其实和直接计算平均值是一样的(我们在计算日期时间对象的平均值时,这一点并没有区别)。
2
如果使用ephem并不是必须的,我最近写了一个叫做 daylight 的库,它有一个直接计算太阳正午的功能。
>>> import daylight, pytz
>>> from datetime import datetime
>>> sun = daylight.Sunclock(37.0625, -95.677068)
>>> t = sun.solar_noon(datetime.utcnow().timestamp())
>>> datetime.utcfromtimestamp(t)
datetime.datetime(2020, 6, 4, 18, 20, 54)
注意,上面的时间是以协调世界时(UTC)表示的。如果你想要更合适的时区,比如东部标准时间(EST),你可以这样做:
>>> tz = pytz.timezone('EST')
>>> tz_offset = tz.utcoffset(datetime.utcnow()).total_seconds()/3600
>>> sun = daylight.Sunclock(37.0625, -95.677068, tz_offset)
>>> t = sun.solar_noon(datetime.utcnow().timestamp())
>>> datetime.utcfromtimestamp(t).astimezone(tz)
datetime.datetime(2020, 6, 3, 7, 50, 54, tzinfo=<StaticTzInfo 'EST'>)
或者你可以为特定的日期,比如2020年5月21日,做这个:
>>> t = sun.solar_noon(datetime(2020, 5, 21).timestamp())
>>> datetime.utcfromtimestamp(t)
datetime.datetime(2020, 5, 20, 18, 19, 14)
9
太阳正午其实并不是日出和日落时间的平均值(想了解更多可以看看时间方程的解释)。ephem
这个包里有一些获取过境时间的方法,你应该使用这些方法。
>>> import ephem
>>> o = ephem.Observer()
>>> o.lat, o.long = '37.0625', '-95.677068'
>>> sun = ephem.Sun()
>>> sunrise = o.previous_rising(sun, start=ephem.now())
>>> noon = o.next_transit(sun, start=sunrise)
>>> sunset = o.next_setting(sun, start=noon)
>>> noon
2010/11/6 18:06:21
>>> ephem.date((sunrise + sunset) / 2)
2010/11/6 18:06:08
请注意,今天你所在位置的正午时间比日出和日落的平均时间晚了13秒。
(代码行ephem.date((sunrise + sunset) / 2)
展示了如果这样做是对的,你可以如何轻松地在ephem
包中处理日期。)