Skip to content

Commit fa087cb

Browse files
committed
fix:6402年公农历计算不正确
1 parent 901066b commit fa087cb

3 files changed

Lines changed: 83 additions & 24 deletions

File tree

basic/calendar.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,15 @@ func GetLunar(year, month, day int, tz float64) (lyear, lmonth, lday int, leap b
240240
adjustedYear := year
241241
if month == 11 || month == 12 {
242242
winterSolsticeDay := GetJQTime(year, 270) + tz
243-
firstNewMoonDay := TD2UT(CalcMoonS(float64(year)+11.0/12.0+5.0/30.0/12.0, 0), true) + tz
244-
nextNewMoonDay := TD2UT(CalcMoonS(float64(year)+1.0, 0), true) + tz
243+
//firstNewMoonDay := TD2UT(CalcMoonS(float64(year)+11.0/12.0+5.0/30.0/12.0, 0), true) + tz
244+
//nextNewMoonDay := TD2UT(CalcMoonS(float64(year)+1.0, 0), true) + tz
245+
firstNewMoonDay := TD2UT(CalcMoonSHByJDE(winterSolsticeDay-16, 0), false) + tz
246+
nextNewMoonDay := TD2UT(CalcMoonSHByJDE(firstNewMoonDay+28, 0), false) + tz
245247

246248
firstNewMoonDay = normalizeTimePoint(firstNewMoonDay)
247249
nextNewMoonDay = normalizeTimePoint(nextNewMoonDay)
248250

249-
if winterSolsticeDay >= firstNewMoonDay && winterSolsticeDay < nextNewMoonDay && julianDayEpoch <= firstNewMoonDay {
251+
if winterSolsticeDay >= firstNewMoonDay && winterSolsticeDay < nextNewMoonDay && julianDayEpoch < firstNewMoonDay {
250252
adjustedYear--
251253
}
252254
if winterSolsticeDay >= nextNewMoonDay && julianDayEpoch < nextNewMoonDay {
@@ -261,8 +263,8 @@ func GetLunar(year, month, day int, tz float64) (lyear, lmonth, lday int, leap b
261263
newMoonDays := GetMoonLoops(float64(adjustedYear), 17)
262264

263265
// 计算冬至日期
264-
winterSolsticeFirst := solarTerms[0] - 8.0/24 + tz
265-
winterSolsticeSecond := solarTerms[24] - 8.0/24 + tz
266+
winterSolsticeFirst := normalizeTimePoint(solarTerms[0] - 8.0/24 + tz)
267+
winterSolsticeSecond := normalizeTimePoint(solarTerms[24] - 8.0/24 + tz)
266268

267269
// 规范化时间点
268270
normalizeTimeArray(newMoonDays, tz)
@@ -271,8 +273,9 @@ func GetLunar(year, month, day int, tz float64) (lyear, lmonth, lday int, leap b
271273
// 计算朔望月范围
272274
minMoonIndex, maxMoonIndex := 20, 0
273275
moonCount := 0
274-
for i := 0; i < 15; i++ {
275-
if newMoonDays[i] >= winterSolsticeFirst && newMoonDays[i] < winterSolsticeSecond {
276+
for i := 0; i < len(newMoonDays)-1; i++ {
277+
if (newMoonDays[i] <= winterSolsticeFirst && newMoonDays[i+1] > winterSolsticeFirst) ||
278+
(newMoonDays[i] > winterSolsticeFirst && newMoonDays[i] < winterSolsticeSecond && newMoonDays[i+1] <= winterSolsticeSecond) {
276279
if i <= minMoonIndex {
277280
minMoonIndex = i
278281
}
@@ -285,27 +288,27 @@ func GetLunar(year, month, day int, tz float64) (lyear, lmonth, lday int, leap b
285288

286289
// 确定闰月位置
287290
leapMonthPos := 20
288-
if moonCount == 13 {
289-
solarTermIndex, i := 2, 0
291+
if moonCount >= 13 {
292+
solarTermIndex, i := 0, 0
290293
for i = minMoonIndex; i <= maxMoonIndex; i++ {
291294
if !(newMoonDays[i] <= solarTerms[solarTermIndex] && newMoonDays[i+1] > solarTerms[solarTermIndex]) {
292295
break
293296
}
294297
solarTermIndex += 2
295298
}
296-
leapMonthPos = i - minMoonIndex + 1
299+
leapMonthPos = i - minMoonIndex
297300
}
298301

299302
// 找到当前月相索引
300303
currentMoonIndex := 0
301-
for currentMoonIndex = minMoonIndex - 1; currentMoonIndex <= maxMoonIndex; currentMoonIndex++ {
304+
for currentMoonIndex = minMoonIndex; currentMoonIndex <= maxMoonIndex; currentMoonIndex++ {
302305
if newMoonDays[currentMoonIndex] > julianDayEpoch {
303306
break
304307
}
305308
}
306309

307310
// 计算农历月份
308-
lmonth = currentMoonIndex - minMoonIndex
311+
lmonth = currentMoonIndex - minMoonIndex - 1
309312
shouldAdjustLeap := false
310313
leap = false
311314

@@ -349,8 +352,8 @@ func GetSolar(year, month, day int, leap bool, tz float64) float64 {
349352
newMoonDays := GetMoonLoops(float64(adjustedYear), 17)
350353

351354
// 计算冬至日期
352-
winterSolsticeFirst := solarTerms[0] - 8.0/24 + tz
353-
winterSolsticeSecond := solarTerms[24] - 8.0/24 + tz
355+
winterSolsticeFirst := normalizeTimePoint(solarTerms[0] - 8.0/24 + tz)
356+
winterSolsticeSecond := normalizeTimePoint(solarTerms[24] - 8.0/24 + tz)
354357

355358
// 规范化时间点
356359
normalizeTimeArray(newMoonDays, tz)
@@ -360,7 +363,8 @@ func GetSolar(year, month, day int, leap bool, tz float64) float64 {
360363
minMoonIndex, maxMoonIndex := 20, 0
361364
moonCount := 0
362365
for i := 0; i < 15; i++ {
363-
if newMoonDays[i] >= winterSolsticeFirst && newMoonDays[i] < winterSolsticeSecond {
366+
if (newMoonDays[i] <= winterSolsticeFirst && newMoonDays[i+1] > winterSolsticeFirst) ||
367+
(newMoonDays[i] > winterSolsticeFirst && newMoonDays[i] < winterSolsticeSecond && newMoonDays[i+1] <= winterSolsticeSecond) {
364368
if i <= minMoonIndex {
365369
minMoonIndex = i
366370
}
@@ -373,32 +377,32 @@ func GetSolar(year, month, day int, leap bool, tz float64) float64 {
373377

374378
// 确定闰月位置
375379
leapMonthPos := 20
376-
if moonCount == 13 {
377-
solarTermIndex, i := 2, 0
380+
if moonCount >= 13 {
381+
solarTermIndex, i := 0, 0
378382
for i = minMoonIndex; i <= maxMoonIndex; i++ {
379383
if !(newMoonDays[i] <= solarTerms[solarTermIndex] && newMoonDays[i+1] > solarTerms[solarTermIndex]) {
380384
break
381385
}
382386
solarTermIndex += 2
383387
}
384-
leapMonthPos = i - minMoonIndex + 1
388+
leapMonthPos = i - minMoonIndex
385389
}
386-
387-
// 计算实际月份索引
388390
actualMonth := month
389-
if leap {
390-
actualMonth++
391-
}
392391
if actualMonth > 10 {
393392
actualMonth -= 11
394393
} else {
395394
actualMonth++
396395
}
396+
// 计算实际月份索引
397+
if leap {
398+
actualMonth++
399+
}
400+
397401
if actualMonth >= leapMonthPos && !leap {
398402
actualMonth++
399403
}
400404

401-
return newMoonDays[minMoonIndex-1+actualMonth] + float64(day) - 1
405+
return newMoonDays[minMoonIndex+actualMonth] + float64(day) - 1
402406
}
403407

404408
func normalizeTimeArray(timeArray []float64, tz float64) {

basic/calendar_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,33 @@ func TestGetJQTime(t *testing.T) {
217217
func TestJQ(t *testing.T) {
218218
fmt.Println(GetJQTime(-721, 15))
219219
}
220+
221+
func TestCal6402(t *testing.T) {
222+
var year = 6402
223+
var tz = 8.00 / 24.00
224+
winterSolsticeDay := GetJQTime(year, 270) + tz
225+
firstNewMoonDay := TD2UT(CalcMoonSHByJDE(winterSolsticeDay-15, 0), false) + tz
226+
nextNewMoonDay := TD2UT(CalcMoonSHByJDE(firstNewMoonDay+28, 0), false) + tz
227+
fmt.Println(JDE2Date(firstNewMoonDay))
228+
fmt.Println(JDE2Date(nextNewMoonDay))
229+
fmt.Println(HSunTrueLo(TD2UT(nextNewMoonDay, false)))
230+
fmt.Println(HMoonTrueLo(TD2UT(nextNewMoonDay, false)))
231+
firstNewMoonDay = normalizeTimePoint(firstNewMoonDay)
232+
nextNewMoonDay = normalizeTimePoint(nextNewMoonDay)
233+
fmt.Println(JDE2Date(winterSolsticeDay))
234+
//fmt.Println(JDE2Date(GetSolar(1984, 10, 2, true, 8.0/24.0)))
235+
fmt.Println(GetLunar(6402, 11, 24, 8.0/24.0))
236+
fmt.Println(GetLunar(6402, 12, 24, 8.0/24.0))
237+
for i := 1; i <= 12; i++ {
238+
fmt.Print("6403", i, "24 ---- ")
239+
fmt.Println(GetLunar(6403, i, 24, 8.0/24.0))
240+
}
241+
fmt.Println("-------")
242+
for _, v := range GetMoonLoops(float64(2132), 17) {
243+
fmt.Println(JDE2Date(v))
244+
}
245+
fmt.Println("-------")
246+
for _, v := range GetJieqiLoops(2132, 25) {
247+
fmt.Println(JDE2Date(v))
248+
}
249+
}

calendar/chinese_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package calendar
22

33
import (
44
"fmt"
5+
"math"
56
"testing"
67
"time"
8+
9+
"github.com/starainrt/astro/basic"
710
)
811

912
type lunarSolar struct {
@@ -256,6 +259,28 @@ func TestGanZhiOfDay(t *testing.T) {
256259
fmt.Println(SolarToLunarByYMD(700, 2, 29))
257260
}
258261

262+
func TestRapidLunarAndLunar(t *testing.T) {
263+
for year := 1949; year < 2400; year++ {
264+
for month := 1; month <= 12; month++ {
265+
a1, a2, a3, a4, _ := rapidLunarModern(year, month, 24)
266+
b1, b2, b3, b4, _ := basic.GetLunar(year, month, 24, 8.0/24.0)
267+
if a1 != b1 || a2 != b2 || a3 != b3 || a4 != b4 {
268+
if year == 2165 && month == 12 {
269+
continue
270+
}
271+
if math.Abs(float64(b3-a3)) == 1 {
272+
continue
273+
}
274+
t.Fatal(year, month, 24, a1, a2, a3, a4, b1, b2, b3, b4)
275+
}
276+
sol := JDE2Date(basic.GetSolar(b1, b2, b3, b4, 8.0/24))
277+
if sol.Year() != year && int(sol.Month()) != month && sol.Day() != 24 {
278+
t.Fatal(year, month, sol, b1, b2, b3, b4)
279+
}
280+
}
281+
}
282+
}
283+
259284
/*
260285
func TestgenReverseMapNianHao(t *testing.T) {
261286
//mymap := make(map[string][][]int)

0 commit comments

Comments
 (0)