fix:时区转换问题

master
兔子 4 days ago
parent d479d39352
commit 616cd54222

@ -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) {

@ -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))
} }

@ -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…
Cancel
Save