update
This commit is contained in:
commit
94aeb84da5
@ -197,10 +197,14 @@ func JDE2Date(JD float64) time.Time {
|
|||||||
Days = math.Floor(Days)
|
Days = math.Floor(Days)
|
||||||
tz, _ := time.LoadLocation("Local")
|
tz, _ := time.LoadLocation("Local")
|
||||||
dates := time.Date(int(Years), time.Month(int(Months)), int(Days), 0, 0, 0, 0, tz)
|
dates := time.Date(int(Years), time.Month(int(Months)), int(Days), 0, 0, 0, 0, tz)
|
||||||
dates = time.Unix(dates.Unix()+int64(tms), int64((tms-math.Floor(tms))*1000000000))
|
return time.Unix(dates.Unix()+int64(tms), int64((tms-math.Floor(tms))*1000000000))
|
||||||
return dates
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JDE2DateByZone JDE(儒略日)转日期
|
||||||
|
// JD: 儒略日
|
||||||
|
// tz: 目标时区
|
||||||
|
// byZone: (true: 传入的儒略日视为目标时区当地时间的儒略日,false: 传入的儒略日视为UTC时间的儒略日)
|
||||||
|
// 回参:转换后的日期,时区始终为目标时区
|
||||||
func JDE2DateByZone(JD float64, tz *time.Location, byZone bool) time.Time {
|
func JDE2DateByZone(JD float64, tz *time.Location, byZone bool) time.Time {
|
||||||
JD = JD + 0.5
|
JD = JD + 0.5
|
||||||
Z := float64(int(JD))
|
Z := float64(int(JD))
|
||||||
@ -231,12 +235,12 @@ func JDE2DateByZone(JD float64, tz *time.Location, byZone bool) time.Time {
|
|||||||
}
|
}
|
||||||
tms := (Days - math.Floor(Days)) * 24 * 3600
|
tms := (Days - math.Floor(Days)) * 24 * 3600
|
||||||
Days = math.Floor(Days)
|
Days = math.Floor(Days)
|
||||||
|
var transTz = tz
|
||||||
if !byZone {
|
if !byZone {
|
||||||
dates := time.Date(int(Years), time.Month(int(Months)), int(Days), 0, 0, 0, 0, time.UTC)
|
transTz = time.UTC
|
||||||
return time.Unix(dates.Unix()+int64(tms), int64((tms-math.Floor(tms))*1000000000)).In(tz)
|
|
||||||
}
|
}
|
||||||
dates := time.Date(int(Years), time.Month(int(Months)), int(Days), 0, 0, 0, 0, tz)
|
return time.Date(int(Years), time.Month(int(Months)), int(Days), 0, 0, 0, 0, transTz).
|
||||||
return time.Unix(dates.Unix()+int64(tms), int64((tms-math.Floor(tms))*1000000000))
|
Add(time.Duration(int64(1000000000 * tms))).In(tz)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLunar(year, month, day int, tz float64) (lmonth, lday int, leap bool, result string) {
|
func GetLunar(year, month, day int, tz float64) (lmonth, lday int, leap bool, result string) {
|
||||||
|
@ -143,6 +143,9 @@ recalc:
|
|||||||
magic := int32(upper[idx])<<8 + int32(lower[idx])
|
magic := int32(upper[idx])<<8 + int32(lower[idx])
|
||||||
springMonth := (magic&0x800000)>>23 + 1
|
springMonth := (magic&0x800000)>>23 + 1
|
||||||
springDay := (magic & 0x7FFFFF) >> 18
|
springDay := (magic & 0x7FFFFF) >> 18
|
||||||
|
if !useGoto && springMonth == int32(month) && springDay == int32(day) {
|
||||||
|
return 1, 1, false, "正月初一"
|
||||||
|
}
|
||||||
if !useGoto && (springMonth > int32(month) || (springMonth == int32(month) && springDay > int32(day))) {
|
if !useGoto && (springMonth > int32(month) || (springMonth == int32(month) && springDay > int32(day))) {
|
||||||
year--
|
year--
|
||||||
useGoto = true
|
useGoto = true
|
||||||
|
@ -18,6 +18,7 @@ type lunarSolar struct {
|
|||||||
|
|
||||||
func Test_ChineseCalendar(t *testing.T) {
|
func Test_ChineseCalendar(t *testing.T) {
|
||||||
var testData = []lunarSolar{
|
var testData = []lunarSolar{
|
||||||
|
{Lyear: 1995, Lmonth: 12, Lday: 12, Leap: false, Year: 1996, Month: 1, Day: 31},
|
||||||
{Lyear: 2034, Lmonth: 1, Lday: 1, Leap: false, Year: 2034, Month: 2, Day: 19},
|
{Lyear: 2034, Lmonth: 1, Lday: 1, Leap: false, Year: 2034, Month: 2, Day: 19},
|
||||||
{Lyear: 2033, Lmonth: 12, Lday: 30, Leap: false, Year: 2034, Month: 2, Day: 18},
|
{Lyear: 2033, Lmonth: 12, Lday: 30, Leap: false, Year: 2034, Month: 2, Day: 18},
|
||||||
{Lyear: 2033, Lmonth: 11, Lday: 27, Leap: true, Year: 2034, Month: 1, Day: 17},
|
{Lyear: 2033, Lmonth: 11, Lday: 27, Leap: true, Year: 2034, Month: 1, Day: 17},
|
||||||
@ -37,19 +38,37 @@ func Test_ChineseCalendar(t *testing.T) {
|
|||||||
{Lyear: 2021, Lmonth: 12, Lday: 29, Leap: false, Year: 2022, Month: 1, Day: 31},
|
{Lyear: 2021, Lmonth: 12, Lday: 29, Leap: false, Year: 2022, Month: 1, Day: 31},
|
||||||
}
|
}
|
||||||
for _, v := range testData {
|
for _, v := range testData {
|
||||||
var lyear int = v.Year
|
{
|
||||||
lmonth, lday, leap, desp := SolarToLunar(time.Date(v.Year, time.Month(v.Month), v.Day, 0, 0, 0, 0, time.Local))
|
var lyear int = v.Year
|
||||||
if lmonth > v.Month {
|
lmonth, lday, leap, desp := SolarToLunar(time.Date(v.Year, time.Month(v.Month), v.Day, 0, 0, 0, 0, time.Local))
|
||||||
lyear--
|
if lmonth > v.Month {
|
||||||
}
|
lyear--
|
||||||
fmt.Println(lyear, desp, v.Year, v.Month, v.Day)
|
}
|
||||||
if lyear != v.Lyear || lmonth != v.Lmonth || lday != v.Lday || leap != v.Leap {
|
fmt.Println(lyear, desp, v.Year, v.Month, v.Day)
|
||||||
t.Fatal(v, lyear, lmonth, lday, leap, desp)
|
if lyear != v.Lyear || lmonth != v.Lmonth || lday != v.Lday || leap != v.Leap {
|
||||||
}
|
t.Fatal(v, lyear, lmonth, lday, leap, desp)
|
||||||
|
}
|
||||||
|
|
||||||
date := LunarToSolar(v.Lyear, v.Lmonth, v.Lday, v.Leap)
|
date := LunarToSolar(v.Lyear, v.Lmonth, v.Lday, v.Leap)
|
||||||
if date.Year() != v.Year || int(date.Month()) != v.Month || date.Day() != v.Day {
|
if date.Year() != v.Year || int(date.Month()) != v.Month || date.Day() != v.Day {
|
||||||
t.Fatal(v, date)
|
t.Fatal(v, date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var lyear int = v.Year
|
||||||
|
lmonth, lday, leap, desp := RapidSolarToLunar(time.Date(v.Year, time.Month(v.Month), v.Day, 0, 0, 0, 0, time.Local))
|
||||||
|
if lmonth > v.Month {
|
||||||
|
lyear--
|
||||||
|
}
|
||||||
|
fmt.Println(lyear, desp, v.Year, v.Month, v.Day)
|
||||||
|
if lyear != v.Lyear || lmonth != v.Lmonth || lday != v.Lday || leap != v.Leap {
|
||||||
|
t.Fatal(v, lyear, lmonth, lday, leap, desp)
|
||||||
|
}
|
||||||
|
|
||||||
|
date := RapidLunarToSolar(v.Lyear, v.Lmonth, v.Lday, v.Leap)
|
||||||
|
if date.Year() != v.Year || int(date.Month()) != v.Month || date.Day() != v.Day {
|
||||||
|
t.Fatal(v, date)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMercury(t *testing.T) {
|
func TestMercury(t *testing.T) {
|
||||||
date := time.Now().Add(time.Hour * -24)
|
tz := time.FixedZone("CST", 8*3600)
|
||||||
fmt.Println(CulminationTime(date, 115))
|
date := time.Date(2022, 01, 20, 00, 00, 00, 00, tz)
|
||||||
fmt.Println(RiseTime(date, 115, 23, 0, false))
|
if NextConjunction(date).Unix() != 1642933683 {
|
||||||
fmt.Println(DownTime(date, 115, 23, 0, false))
|
t.Fatal(NextConjunction(date).Unix())
|
||||||
|
}
|
||||||
|
if CulminationTime(date, 115).Unix() != 1642654651 {
|
||||||
|
t.Fatal(CulminationTime(date, 115).Unix())
|
||||||
|
}
|
||||||
|
date, err := (RiseTime(date, 115, 40, 0, false))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if date.Unix() != 1642636481 {
|
||||||
|
t.Fatal(date.Unix())
|
||||||
|
}
|
||||||
|
fmt.Println(DownTime(date, 115, 40, 0, false))
|
||||||
}
|
}
|
||||||
|
@ -209,11 +209,14 @@ func Phase(date time.Time) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ShuoYue 朔月
|
// ShuoYue 朔月
|
||||||
|
// 返回Date对应UTC世界时的月相大小
|
||||||
func ShuoYue(year float64) time.Time {
|
func ShuoYue(year float64) time.Time {
|
||||||
jde := basic.TD2UT(basic.CalcMoonSH(year, 0), false)
|
jde := basic.TD2UT(basic.CalcMoonSH(year, 0), false)
|
||||||
return basic.JDE2DateByZone(jde, time.UTC, false)
|
return basic.JDE2DateByZone(jde, time.UTC, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextShuoYue 下次朔月时间
|
||||||
|
// 返回date之后的下一个朔月时间(UTC时间)
|
||||||
func NextShuoYue(date time.Time) time.Time {
|
func NextShuoYue(date time.Time) time.Time {
|
||||||
return nextMoonPhase(date, 0)
|
return nextMoonPhase(date, 0)
|
||||||
}
|
}
|
||||||
|
@ -13,38 +13,38 @@ func Test_MoonPhaseDate(t *testing.T) {
|
|||||||
//指定日期后的下一个朔月
|
//指定日期后的下一个朔月
|
||||||
moonPhase01 := NextShuoYue(date)
|
moonPhase01 := NextShuoYue(date)
|
||||||
fmt.Println("下一朔月", moonPhase01)
|
fmt.Println("下一朔月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1643694349 {
|
if moonPhase01.Unix() != 1643694356 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//指定日期后的上一个朔月
|
//指定日期后的上一个朔月
|
||||||
moonPhase01 = LastShuoYue(date)
|
moonPhase01 = LastShuoYue(date)
|
||||||
fmt.Println("上一朔月", moonPhase01)
|
fmt.Println("上一朔月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1641148399 {
|
if moonPhase01.Unix() != 1641148406 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//离指定日期最近的朔月
|
//离指定日期最近的朔月
|
||||||
moonPhase01 = ClosestShuoYue(date)
|
moonPhase01 = ClosestShuoYue(date)
|
||||||
fmt.Println("最近朔月", moonPhase01)
|
fmt.Println("最近朔月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1643694349 {
|
if moonPhase01.Unix() != 1643694356 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//离指定日期最近的望月时间
|
//离指定日期最近的望月时间
|
||||||
moonPhase01 = ClosestWangYue(date)
|
moonPhase01 = ClosestWangYue(date)
|
||||||
fmt.Println("最近望月", moonPhase01)
|
fmt.Println("最近望月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1642463294 {
|
if moonPhase01.Unix() != 1642463301 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//离指定日期最近的上弦月时间
|
//离指定日期最近的上弦月时间
|
||||||
moonPhase01 = ClosestShangXianYue(date)
|
moonPhase01 = ClosestShangXianYue(date)
|
||||||
fmt.Println("最近上弦月", moonPhase01)
|
fmt.Println("最近上弦月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1641751864 {
|
if moonPhase01.Unix() != 1641751871 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//离指定日期最近的下弦月时间
|
//离指定日期最近的下弦月时间
|
||||||
moonPhase01 = ClosestXiaXianYue(date)
|
moonPhase01 = ClosestXiaXianYue(date)
|
||||||
fmt.Println("最近下弦月", moonPhase01)
|
fmt.Println("最近下弦月", moonPhase01)
|
||||||
if moonPhase01.Unix() != 1643118043 {
|
if moonPhase01.Unix() != 1643118050 {
|
||||||
t.Fatal(moonPhase01)
|
t.Fatal(moonPhase01.Unix())
|
||||||
}
|
}
|
||||||
//-------------------
|
//-------------------
|
||||||
for i := 0; i < 26; i++ {
|
for i := 0; i < 26; i++ {
|
||||||
@ -52,10 +52,3 @@ func Test_MoonPhaseDate(t *testing.T) {
|
|||||||
fmt.Println("上一朔月", moonPhase01)
|
fmt.Println("上一朔月", moonPhase01)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMoon(t *testing.T) {
|
|
||||||
now := time.Now()
|
|
||||||
fmt.Println(RiseTime(now, 115, 40, 0, true))
|
|
||||||
fmt.Println(CulminationTime(now, 115, 40))
|
|
||||||
fmt.Println(DownTime(now, 115, 40, 0, true))
|
|
||||||
}
|
|
||||||
|
@ -7,8 +7,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNeptune(t *testing.T) {
|
func TestNeptune(t *testing.T) {
|
||||||
date := time.Now().Add(time.Hour * -24)
|
tz := time.FixedZone("CST", 8*3600)
|
||||||
fmt.Println(CulminationTime(date, 115))
|
date := time.Date(2022, 01, 20, 00, 00, 00, 00, tz)
|
||||||
fmt.Println(RiseTime(date, 115, 23, 0, false))
|
if NextConjunction(date).Unix() != 1647171796 {
|
||||||
fmt.Println(DownTime(date, 115, 23, 0, false))
|
t.Fatal(NextConjunction(date).Unix())
|
||||||
|
}
|
||||||
|
if CulminationTime(date, 115).Unix() != 1642665021 {
|
||||||
|
t.Fatal(CulminationTime(date, 115).Unix())
|
||||||
|
}
|
||||||
|
date, err := (RiseTime(date, 115, 40, 0, false))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if date.Unix() != 1642644398 {
|
||||||
|
t.Fatal(date.Unix())
|
||||||
|
}
|
||||||
|
fmt.Println(DownTime(date, 115, 40, 0, false))
|
||||||
}
|
}
|
||||||
|
16
sun/sun.go
16
sun/sun.go
@ -2,7 +2,6 @@ package sun
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"b612.me/astro/basic"
|
"b612.me/astro/basic"
|
||||||
@ -38,9 +37,11 @@ func RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, e
|
|||||||
if date.Hour() > 12 {
|
if date.Hour() > 12 {
|
||||||
date = date.Add(time.Hour * -12)
|
date = date.Add(time.Hour * -12)
|
||||||
}
|
}
|
||||||
|
//忽略时区的字面量时间
|
||||||
jde := basic.Date2JDE(date)
|
jde := basic.Date2JDE(date)
|
||||||
_, loc := date.Zone()
|
_, loc := date.Zone()
|
||||||
timezone := float64(loc) / 3600.0
|
timezone := float64(loc) / 3600.0
|
||||||
|
//risedate 时区修正后的时间,转换应当包括时区
|
||||||
riseJde := basic.GetSunRiseTime(jde, lon, lat, timezone, aeroFloat, height)
|
riseJde := basic.GetSunRiseTime(jde, lon, lat, timezone, aeroFloat, height)
|
||||||
if riseJde == -2 {
|
if riseJde == -2 {
|
||||||
err = ERR_SUN_NEVER_RISE
|
err = ERR_SUN_NEVER_RISE
|
||||||
@ -80,7 +81,7 @@ func DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MorningTwilight 晨朦影
|
// MorningTwilight 晨朦影
|
||||||
// date,当地时区日期
|
// date,当地时区日期,返回的时间时区与此参数中的时区一致
|
||||||
// lon,经度,东正西负
|
// lon,经度,东正西负
|
||||||
// lat,纬度,北正南负
|
// lat,纬度,北正南负
|
||||||
// angle,朦影角度:可选-6 -12 -18(民用、航海、天文)
|
// angle,朦影角度:可选-6 -12 -18(民用、航海、天文)
|
||||||
@ -99,11 +100,11 @@ func MorningTwilight(date time.Time, lon, lat, angle float64) (time.Time, error)
|
|||||||
if calcJde == -1 {
|
if calcJde == -1 {
|
||||||
err = ERR_TWILIGHT_NOT_EXISTS
|
err = ERR_TWILIGHT_NOT_EXISTS
|
||||||
}
|
}
|
||||||
return basic.JDE2Date(calcJde), err
|
return basic.JDE2DateByZone(calcJde, date.Location(), true), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EveningTwilight 昏朦影
|
// EveningTwilight 昏朦影
|
||||||
// date,当地时区日期
|
// date,当地时区日期,返回的时间时区与此参数中的时区一致
|
||||||
// lon,经度,东正西负
|
// lon,经度,东正西负
|
||||||
// lat,纬度,北正南负
|
// lat,纬度,北正南负
|
||||||
// angle,朦影角度:可选-6 -12 -18(民用、航海、天文)
|
// angle,朦影角度:可选-6 -12 -18(民用、航海、天文)
|
||||||
@ -123,7 +124,7 @@ func EveningTwilight(date time.Time, lon, lat, angle float64) (time.Time, error)
|
|||||||
if calcJde == -1 {
|
if calcJde == -1 {
|
||||||
err = ERR_TWILIGHT_NOT_EXISTS
|
err = ERR_TWILIGHT_NOT_EXISTS
|
||||||
}
|
}
|
||||||
return basic.JDE2Date(calcJde), err
|
return basic.JDE2DateByZone(calcJde, date.Location(), true), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EclipticObliquity 黄赤交角
|
// EclipticObliquity 黄赤交角
|
||||||
@ -256,10 +257,7 @@ func Zenith(date time.Time, lon, lat float64) float64 {
|
|||||||
// CulminationTime 太阳中天时间
|
// CulminationTime 太阳中天时间
|
||||||
// 返回给定经纬度、对应date时区date时刻的太阳中天日期
|
// 返回给定经纬度、对应date时区date时刻的太阳中天日期
|
||||||
func CulminationTime(date time.Time, lon float64) time.Time {
|
func CulminationTime(date time.Time, lon float64) time.Time {
|
||||||
jde := basic.Date2JDE(date)
|
jde := basic.Date2JDE(date.Add(time.Duration(-1*date.Hour())*time.Hour)) + 0.5
|
||||||
if jde-math.Floor(jde) > 0.5 {
|
|
||||||
jde++
|
|
||||||
}
|
|
||||||
_, loc := date.Zone()
|
_, loc := date.Zone()
|
||||||
timezone := float64(loc) / 3600.0
|
timezone := float64(loc) / 3600.0
|
||||||
calcJde := basic.GetSunTZTime(jde, lon, timezone) - timezone/24.00
|
calcJde := basic.GetSunTZTime(jde, lon, timezone) - timezone/24.00
|
||||||
|
@ -7,8 +7,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSun(t *testing.T) {
|
func TestSun(t *testing.T) {
|
||||||
now := time.Now()
|
ja, err := time.LoadLocation("Asia/Tokyo")
|
||||||
fmt.Println(RiseTime(now, 115, 40, 0, true))
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
now, err := time.ParseInLocation("2006-01-02 15:04:05", "2020-01-01 00:00:00", ja)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
d, err := RiseTime(now, 115, 40, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if d.Format("2006-01-02 15:04:05") != "2020-01-01 08:41:45" {
|
||||||
|
t.Fatal(d.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
fmt.Println(CulminationTime(now, 115))
|
fmt.Println(CulminationTime(now, 115))
|
||||||
fmt.Println(DownTime(now, 115, 40, 0, true))
|
fmt.Println(DownTime(now, 115, 40, 0, true))
|
||||||
|
fmt.Println(MorningTwilight(now, 115, 40, -6))
|
||||||
|
fmt.Println(EveningTwilight(now, 115, 40, -6))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user