使用ephem计算“太阳中午”并将其转换为当地时间

9

我已经查看了使用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个回答

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包中轻松操作日期,如果这是正确的做法的话。)

如果你在足够北方(或南方)以至于太阳今天没有升起,那么你的日出计算就会“失效”...(例如,今天是7月8日,但上次日出是5月17日 :-)) - thebjorn
是的,我看到问题了:ephem.AlwaysUpError: 'Sun' 在 2011/7/8 00:04:58 仍然在地平线以上 - Gareth Rees

2
如果不是必需使用ephem,我最近写了一个名为daylight的库,其中有一个直接用于太阳正午的本地函数。请参考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)

干得好!这个软件包对我来说很有效。 - Richard

0
两个数字的平均值是它们的和除以二,而不是将白天长度除以二。如果将其添加到 o.previous_rising(sun) 中,也可以起作用,但这应该与直接求平均值相同(我们对日期时间对象进行平均化并不重要)。

0

我知道这个问题早就有答案了。但是对于那些可能使用任何代码或不太理解Python的人来说,下面是关于时间方程式目的的简单解释。您的平均太阳过境(中午)发生在您的经度位置。这意味着,只要知道您的经度,您就可以通过将您的经度除以15.0并从12中减去该值来找到您的平均太阳过境,这将得到一个小时小数时间的GMT或UTC结果。您的真实太阳过境是通过从平均太阳过境中减去时间方程式得出的。通常情况下,您需要计算这个值才能获得日出和日落时间,就像维基百科公式中所示的那样。但感谢Python包信息,因为我在使用sunpy包时遇到了一些麻烦。这里有一个很棒的程序,请点击bitbucket链接查看:https://bitbucket.org/cmcqueen1975/sundials/wiki/Home


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接