进一步改进@Wojciech Jakubas answer,这是基准(省略时区):
# boilerplate
from datetime import date, datetime, timezone, timedelta
import pytz
import time
from suntime import Sun, SunTimeException
from suntimes import SunTimes
import sunriset
import astral, astral.sun
latitude = 6.2088
longitude = 106.8456
altitude = 0
tz_name = 'Asia/Jakarta'
for_date = date(2021, 4, 6)
%%timeit
# print('====== suntime ======')
sun = Sun(latitude, longitude)
today_sr = sun.get_sunrise_time(for_date)
today_ss = sun.get_sunset_time(for_date)
# 20.3 µs ± 90.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
# print('====== suntimes ======')
sun2 = SunTimes(longitude=longitude, latitude=latitude, altitude=altitude)
today_sr = sun2.riseutc(for_date)
today_ss = sun2.setutc(for_date)
# 83 µs ± 261 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
# print('====== sunriset ======')
df = sunriset.to_pandas(for_date, latitude, longitude, 0, 1)
for index, row in df.iterrows():
today_sr = row['Sunrise']
today_ss = row['Sunset']
break
# 28.7 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
# print('====== astral ======')
l = astral.LocationInfo('Custom Name', 'My Region', tz_name, latitude, longitude)
today_sr = astral.sun.sunrise(l.observer, date=for_date)
today_sr = astral.sun.sunset(l.observer, date=for_date)
# 64.3 µs ± 292 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
要转换为本地 time zone (UTC+X),请使用:
# with known region name
tz_name = 'Asia/Jakarta'
tz = pytz.timezone(tz_name)
today_sr.astimezone(tz)
# with known time different
time_different = 7
tz = datetime.timezone(datetime.timedelta(hours=time_different))
today_sr.astimezone(tz)
结论:
- 使用
suntime。
- 如果您确实需要一年的数据并且不关心速度,请尝试
sunriset,因为它会输出一年。
-
sunriset 需要从源代码中手动编辑才能解决单次
-
sunriset 输出在timedelta 中,因此无法直接使用.astimezone 进行转换。