You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:用Ephem/Astral/PvLib非迭代获取太阳特定仰角时刻

问题解答

一、各库直接获取特定太阳高度角时刻的方法

1. ephem库

ephem支持通过自定义观察者的horizon参数,直接计算太阳到达指定高度角的时刻,无需逐分钟迭代。只需将horizon设为目标高度角(负数表示地平线以下),再调用next_rising/next_setting即可得到对应时间。

2. astral库(推荐astral4版本)

astral专门处理太阳与暮光时间计算,可通过sun()方法的depression参数指定地平线以下的角度,直接获取对应时刻,无需手动迭代。

3. pvlib库

pvlib的sun_rise_set_transit_spa函数基于高精度SPA算法,支持自定义太阳高度角阈值,能快速返回目标时刻,效率远高于逐分钟计算。

二、替代库推荐

  • astral4:API简洁直观,专注太阳与暮光时间计算,内置多种暮光类型,也支持自定义高度角。
  • skyfield:高精度天文计算库,基于SPICE数据,可精准计算任意太阳高度角对应的时刻。

三、可运行示例

示例1:用ephem获取太阳-6°(航海暮光)的时刻

import ephem
from datetime import datetime
import zoneinfo

# 配置墨尔本观测点
melbourne = ephem.Observer()
melbourne.lat = "-37.8136"
melbourne.lon = "144.9631"
melbourne.elev = 0

# 设置目标太阳高度角(地平线以下6°)
target_alt = -6
melbourne.horizon = str(target_alt)

# 指定日期
target_date = datetime(2023, 1, 1)
melbourne.date = ephem.Date(target_date)

# 获取UTC时刻并转换为墨尔本本地时间
sun_rise_utc = melbourne.next_rising(ephem.Sun())
sun_set_utc = melbourne.next_setting(ephem.Sun())

tz_mel = zoneinfo.ZoneInfo("Australia/Melbourne")
rise_local = ephem.localtime(sun_rise_utc).astimezone(tz_mel)
set_local = ephem.localtime(sun_set_utc).astimezone(tz_mel)

print(f"太阳高度{target_alt}°升起时刻(墨尔本时间):{rise_local.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"太阳高度{target_alt}°落下时刻(墨尔本时间):{set_local.strftime('%Y-%m-%d %H:%M:%S')}")

示例2:用astral4获取自定义高度角时刻

from astral import LocationInfo
from astral.sun import sun
from datetime import date
import zoneinfo

# 定义墨尔本位置
city = LocationInfo(
    name="Melbourne",
    region="Australia",
    timezone="Australia/Melbourne",
    latitude=-37.8136,
    longitude=144.9631
)
target_date = date(2023, 1, 1)
tz_mel = zoneinfo.ZoneInfo(city.timezone)

# 获取太阳-6°(航海暮光)的时刻
sun_data_nautical = sun(city.observer, date=target_date, depression=6)
print(f"航海暮光开始:{sun_data_nautical['dawn'].astimezone(tz_mel)}")
print(f"航海暮光结束:{sun_data_nautical['dusk'].astimezone(tz_mel)}")

# 获取太阳-12°(天文暮光)的时刻
sun_data_astro = sun(city.observer, date=target_date, depression=12)
print(f"天文暮光开始:{sun_data_astro['dawn'].astimezone(tz_mel)}")
print(f"天文暮光结束:{sun_data_astro['dusk'].astimezone(tz_mel)}")

示例3:用pvlib获取自定义高度角时刻

import pvlib
from datetime import date
import zoneinfo

# 墨尔本参数
lat, lon = -37.8136, 144.9631
tz = "Australia/Melbourne"
target_date = date(2023, 1, 1)

# 计算太阳高度角为-6°的时刻
sun_times = pvlib.solarposition.sun_rise_set_transit_spa(
    latitude=lat,
    longitude=lon,
    date=target_date,
    altitude=-6,  # 负数表示地平线以下
    tz=tz
)

print(f"太阳-6°升起时刻:{sun_times['sun_rise']}")
print(f"太阳-6°落下时刻:{sun_times['sun_set']}")

四、优化原始代码的思路

你的逐分钟迭代效率极低,可改为:

  1. 对每一天,用上述库直接获取所有关键高度角(-1°、-6°、-12°、-18°)对应的时刻
  2. 根据这些时刻计算对应时间段的Y轴像素范围(对应24小时的比例)
  3. 直接绘制对应颜色的线段/矩形,无需逐像素计算高度角

这样每天仅需几次计算,效率会大幅提升。

内容的提问来源于stack exchange,提问作者Mutley Eugenius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:12:04