Python 3 用户注意事项:我刚刚使用 Python 3.8.6 尝试了以下代码,它也适用于该版本。我不得不将print 语句转换为print() 函数调用,但仅此而已。
我注意到 tzinfo 类的示例实现与 Python 2 文档中的不同,但使用 tzinfo_example.py 文件中的示例 tzinfo 类在 latest documentation 中引用的工作很好(但是这样旧的 2.x 版本)。
您可以从here 下载下面显示的sunriseset.py 文件的 Python 3 版本。
您可以像我一样使用这个公共域Sun.py 模块来计算太阳相对于地球位置的位置。 (警告:它包含制表符并假定制表符是每 8 个字符。)它已经很老了,但多年来一直对我很好。我对其进行了一些表面上的修改以使其与 Python 2.7 保持同步,例如使其中的少数类成为新样式,但大部分都没有改变。
这是我创建的一个模块,名为sunriseset.py,它展示了如何使用它来计算特定位置的日出和日落时间,因为它的地理坐标和时区。引用的timezone 模块是datetime 模块文档tzinfoobjects 中描述的tzinfo 抽象基类的实现。
# -*- coding: iso-8859-1 -*-
import datetime
import timezone # concrete tzinfo subclass based on the Python docs
import math
from Sun import Sun
__all__ = ['getsuninfo', 'Place']
class Place(object):
def __init__(self, name, coords, tz=timezone.Pacific):
self.name = name # string
self.coords = coords # tuple (E/W long, N/S lat)
self.tz = tz # tzinfo constant
def _hoursmins(hours):
"""Convert floating point decimal time in hours to integer hrs,mins"""
frac,h = math.modf(hours)
m = round(frac*60, 0)
if m == 60: # rounded up to next hour
h += 1; m = 0
return int(h),int(m)
def _ymd(date):
"""Return y,m,d from datetime object as tuple"""
return date.timetuple()[:3]
def getsuninfo(location, date=None):
"""Return local datetime of sunrise, sunset, and length of day in hrs,mins)"""
if date == None:
querydate = datetime.date.today()
else: # date given should be datetime instance
querydate = date
args = _ymd(querydate) + location.coords
utcrise, utcset = Sun().sunRiseSet(*args)
daylength = Sun().dayLength(*args)
hrs,mins = _hoursmins(daylength)
risehour, risemin = _hoursmins(utcrise)
sethour, setmin = _hoursmins(utcset)
# convert times to timedelta values (ie from midnight utc of the date)
midnight = datetime.datetime(tzinfo=timezone.utc, *_ymd(querydate))
deltarise = datetime.timedelta(hours=risehour, minutes=risemin)
utcdatetimerise = midnight+deltarise
deltaset = datetime.timedelta(hours=sethour, minutes=setmin)
utcdatetimeset = midnight+deltaset
# convert results from UTC time to local time of location
localrise = utcdatetimerise.astimezone(location.tz)
localset = utcdatetimeset.astimezone(location.tz)
return localrise, localset, hrs, mins
if __name__ == "__main__":
import datetime, timezone
def unittest(location, testdate):
risetime, settime, hrs, mins = getsuninfo(location, testdate)
print "Location:", location.name
print "Date:", testdate.strftime("%a %x")
print risetime.strftime("Sunrise %I:%M %p"), settime.strftime("- Sunset %I:%M %p (%Z)")
print "daylight: %d:%02d" % (hrs,mins)
print
place = Place("My House", (-121.990278, 47.204444), timezone.Pacific)
# test dates just before and after DST transitions
print "pre 2007"
print "========="
unittest(place, datetime.date(2006, 4, 1))
unittest(place, datetime.date(2006, 4, 2))
unittest(place, datetime.date(2006, 10, 28))
unittest(place, datetime.date(2006, 10, 29))
print "2007"
print "========="
unittest(place, datetime.date(2007, 3, 10))
unittest(place, datetime.date(2007, 3, 11))
unittest(place, datetime.date(2007, 11, 3))
unittest(place, datetime.date(2007, 11, 4))