astro/sun/sun.go

276 lines
7.8 KiB
Go
Raw Normal View History

2019-10-24 10:44:21 +08:00
package sun
import (
"errors"
2020-07-14 15:38:51 +08:00
"math"
"time"
2019-10-24 10:44:21 +08:00
"b612.me/astro/basic"
)
2020-07-14 15:38:51 +08:00
var (
ERR_SUN_NEVER_RISE = errors.New("ERROR:极夜,太阳在今日永远在地平线下!")
ERR_SUN_NEVER_DOWN = errors.New("ERROR:极昼,太阳在今日永远在地平线上!")
ERR_TWILIGHT_NOT_EXISTS = errors.New("ERROR:今日晨昏朦影不存在!")
)
2019-10-24 10:44:21 +08:00
/*
2020-07-14 15:38:51 +08:00
太阳
视星等 26.74
绝对星等 4.839
光谱类型 G2V
金属量 Z = 0.0122
角直径 31.6 32.7
2019-10-24 10:44:21 +08:00
*/
2020-07-14 15:38:51 +08:00
// RiseTime 太阳升起时间
// date取日期时区忽略
// lon经度东正西负
// lat纬度北正南负
2022-01-04 14:24:44 +08:00
// height高度
2020-07-14 15:38:51 +08:00
// aerotrue时进行大气修正
2022-01-04 14:24:44 +08:00
func RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
2020-07-14 15:38:51 +08:00
var err error
var aeroFloat float64
if aero {
aeroFloat = 1
}
2021-03-04 17:27:33 +08:00
if date.Hour() > 12 {
date = date.Add(time.Hour * -12)
}
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2022-01-04 14:24:44 +08:00
riseJde := basic.GetSunRiseTime(jde, lon, lat, timezone, aeroFloat, height)
2020-07-14 15:38:51 +08:00
if riseJde == -2 {
err = ERR_SUN_NEVER_RISE
}
if riseJde == -1 {
err = ERR_SUN_NEVER_DOWN
}
2021-03-04 17:27:33 +08:00
return basic.JDE2DateByZone(riseJde, date.Location(), true), err
2020-07-14 15:38:51 +08:00
}
// SunDownTime 太阳落下时间
2020-12-31 09:07:54 +08:00
// date当地时区日期务必做时区修正
2020-07-14 15:38:51 +08:00
// lon经度东正西负
// lat纬度北正南负
2022-01-04 14:24:44 +08:00
// height高度
2020-07-14 15:38:51 +08:00
// aerotrue时进行大气修正
2022-01-04 14:24:44 +08:00
func DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
2020-07-14 15:38:51 +08:00
var err error
var aeroFloat float64
if aero {
aeroFloat = 1
}
2021-03-04 17:27:33 +08:00
if date.Hour() > 12 {
date = date.Add(time.Hour * -12)
}
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2022-01-04 14:24:44 +08:00
downJde := basic.GetSunDownTime(jde, lon, lat, timezone, aeroFloat, height)
2020-07-14 15:38:51 +08:00
if downJde == -2 {
err = ERR_SUN_NEVER_RISE
}
if downJde == -1 {
err = ERR_SUN_NEVER_DOWN
}
2021-03-04 17:27:33 +08:00
return basic.JDE2DateByZone(downJde, date.Location(), true), err
2020-07-14 15:38:51 +08:00
}
// MorningTwilight 晨朦影
2020-12-31 09:07:54 +08:00
// date当地时区日期
2020-07-14 15:38:51 +08:00
// lon经度东正西负
// lat纬度北正南负
// angle朦影角度可选-6 -12 -18(民用、航海、天文)
2020-12-31 09:07:54 +08:00
func MorningTwilight(date time.Time, lon, lat, angle float64) (time.Time, error) {
2020-07-14 15:38:51 +08:00
var err error
2022-05-10 22:24:10 +08:00
if date.Hour() > 12 {
date = date.Add(time.Hour * -12)
}
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2020-07-14 15:38:51 +08:00
calcJde := basic.GetAsaTime(jde, lon, lat, timezone, angle)
if calcJde == -2 {
err = ERR_TWILIGHT_NOT_EXISTS
}
if calcJde == -1 {
err = ERR_TWILIGHT_NOT_EXISTS
}
return basic.JDE2Date(calcJde), err
}
// EveningTwilight 昏朦影
2020-12-31 09:07:54 +08:00
// date当地时区日期
2020-07-14 15:38:51 +08:00
// lon经度东正西负
// lat纬度北正南负
// angle朦影角度可选-6 -12 -18(民用、航海、天文)
2020-12-31 09:07:54 +08:00
func EveningTwilight(date time.Time, lon, lat, angle float64) (time.Time, error) {
2020-07-14 15:38:51 +08:00
var err error
2022-05-10 22:24:10 +08:00
if date.Hour() > 12 {
date = date.Add(time.Hour * -12)
}
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2020-07-14 15:38:51 +08:00
//不需要进行力学时转换会在GetBanTime中转换
calcJde := basic.GetBanTime(jde, lon, lat, timezone, angle)
if calcJde == -2 {
err = ERR_TWILIGHT_NOT_EXISTS
}
if calcJde == -1 {
err = ERR_TWILIGHT_NOT_EXISTS
}
return basic.JDE2Date(calcJde), err
}
// EclipticObliquity 黄赤交角
// 返回date对应UTC世界时的黄赤交角nutation为true时计算交角章动
func EclipticObliquity(date time.Time, nutation bool) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
//进行力学时转换
2019-10-24 10:44:21 +08:00
jde = basic.TD2UT(jde, true)
2020-07-14 15:38:51 +08:00
//黄赤交角计算
2019-10-24 10:44:21 +08:00
return basic.EclipticObliquity(jde, nutation)
}
2020-07-14 15:38:51 +08:00
// EclipticNutation 黄经章动
// 返回date对应UTC世界时的黄经章动
func EclipticNutation(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
//进行力学时转换与章动计算
2019-10-24 10:44:21 +08:00
return basic.HJZD(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// AxialtiltNutation 交角章动
// 返回date对应UTC世界时的交角章动
func AxialtiltNutation(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
//进行力学时转换与章动计算
2019-10-24 10:44:21 +08:00
return basic.JJZD(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// GeometricLo 太阳几何黄经
// 返回date对应UTC世界时的太阳几何黄经
func GeometricLo(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2019-10-24 10:44:21 +08:00
return basic.SunLo(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// TrueLo 太阳真黄经
// 返回date对应UTC世界时的太阳真黄经
func TrueLo(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2019-10-24 10:44:21 +08:00
return basic.HSunTrueLo(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// TrueBo 太阳真黄纬
// 返回date对应UTC世界时的太阳真黄纬
func TrueBo(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
return basic.HSunTrueLo(basic.TD2UT(jde, true))
}
2022-05-12 15:55:48 +08:00
// ApparentLo 太阳视黄经
2020-07-14 15:38:51 +08:00
// 返回date对应UTC世界时的太阳视黄经
2022-05-12 15:55:48 +08:00
func ApparentLo(date time.Time) float64 {
2020-07-14 15:38:51 +08:00
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2022-05-12 15:55:48 +08:00
return basic.HSunApparentLo(basic.TD2UT(jde, true))
2019-10-24 10:44:21 +08:00
}
2022-05-12 15:55:48 +08:00
// ApparentRa 太阳地心视赤经
2020-07-14 15:38:51 +08:00
// 返回date对应UTC世界时的太阳视赤经使用黄道坐标转换且默认忽略黄纬
2022-05-12 15:55:48 +08:00
func ApparentRa(date time.Time) float64 {
2020-07-14 15:38:51 +08:00
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2022-05-12 15:55:48 +08:00
return basic.HSunApparentRa(basic.TD2UT(jde, true))
2019-10-24 10:44:21 +08:00
}
2022-05-12 15:55:48 +08:00
// ApparentDec 太阳地心视赤纬
2020-07-14 15:38:51 +08:00
// 返回date对应UTC世界时的太阳视赤纬使用黄道坐标转换且默认忽略黄纬
2022-05-12 15:55:48 +08:00
func ApparentDec(date time.Time) float64 {
2020-07-14 15:38:51 +08:00
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2022-05-12 15:55:48 +08:00
return basic.HSunApparentDec(basic.TD2UT(jde, true))
2019-10-24 10:44:21 +08:00
}
2022-05-12 15:55:48 +08:00
// ApparentRaDec 太阳地心视赤经和赤纬
2020-07-14 15:38:51 +08:00
// 返回date对应UTC世界时的太阳视赤纬使用黄道坐标转换且默认忽略黄纬
2022-05-12 15:55:48 +08:00
func ApparentRaDec(date time.Time) (float64, float64) {
2020-07-14 15:38:51 +08:00
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2022-05-12 15:55:48 +08:00
return basic.HSunApparentRaDec(basic.TD2UT(jde, true))
2019-10-24 10:44:21 +08:00
}
2020-07-14 15:38:51 +08:00
// MidFunc 太阳中间方程
func MidFunc(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2019-10-24 10:44:21 +08:00
return basic.SunMidFun(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// EquationTime 均时差
// 返回date对应UTC世界时的均时差
func EquationTime(date time.Time) float64 {
//转换为UTC时间
jde := basic.Date2JDE(date.UTC())
2019-10-24 10:44:21 +08:00
return basic.SunTime(basic.TD2UT(jde, true))
}
2020-07-14 15:38:51 +08:00
// HourAngle 太阳时角
2020-12-31 09:07:54 +08:00
// 返回给定经纬度、对应date时区date时刻的太阳时角
func HourAngle(date time.Time, lon, lat float64) float64 {
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2019-10-24 10:44:21 +08:00
return basic.SunTimeAngle(jde, lon, lat, timezone)
}
2020-07-14 15:38:51 +08:00
// Azimuth 太阳方位角
2020-12-31 09:07:54 +08:00
// 返回给定经纬度、对应date时区date时刻的太阳方位角正北为0向东增加
func Azimuth(date time.Time, lon, lat float64) float64 {
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2019-10-24 10:44:21 +08:00
return basic.SunAngle(jde, lon, lat, timezone)
}
2020-07-14 15:38:51 +08:00
// Zenith 太阳高度角
2020-12-31 09:07:54 +08:00
// 返回给定经纬度、对应date时区date时刻的太阳高度角
func Zenith(date time.Time, lon, lat float64) float64 {
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
2019-10-24 10:44:21 +08:00
return basic.SunHeight(jde, lon, lat, timezone)
}
2020-07-14 15:38:51 +08:00
// CulminationTime 太阳中天时间
2020-12-31 09:07:54 +08:00
// 返回给定经纬度、对应date时区date时刻的太阳中天日期
func CulminationTime(date time.Time, lon float64) time.Time {
2020-07-14 15:38:51 +08:00
jde := basic.Date2JDE(date)
if jde-math.Floor(jde) > 0.5 {
jde++
2019-10-24 10:44:21 +08:00
}
2020-12-31 09:07:54 +08:00
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
calcJde := basic.GetSunTZTime(jde, lon, timezone) - timezone/24.00
2021-03-04 17:27:33 +08:00
return basic.JDE2DateByZone(calcJde, date.Location(), false)
2019-10-24 10:44:21 +08:00
}
2020-07-14 15:38:51 +08:00
// EarthDistance 日地距离
// 返回date对应UTC世界时日地距离
func EarthDistance(date time.Time) float64 {
2020-12-31 09:07:54 +08:00
jde := basic.Date2JDE(date.UTC())
2020-07-14 15:38:51 +08:00
jde = basic.TD2UT(jde, true)
return basic.EarthAway(jde)
2019-10-24 10:44:21 +08:00
}