493 lines
37 KiB
Go
493 lines
37 KiB
Go
|
package calendar
|
|||
|
|
|||
|
import (
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
var ERR_NIANHAO_NOT_FOUND = errors.New("ERROR:未找到对应的年号")
|
|||
|
|
|||
|
func getHanQingCals() []uint32 {
|
|||
|
return []uint32{
|
|||
|
2865769984, 1431610368, 3310368000, 1788881408, 2874351360, 2865771008, 1431316224, 1789500416, 1520447232, 2866160640, 2862626304, 3578800896, 1521262848, 1436562432, 2863671296, 1431477760, 3041931264, 1436558848, 2863700480, 2862624000, 3042255360, 2907714816, 1432365568, 2863374080, 1788883456, 2907711232, 1432984576, 1431318272, 2863506432, 1520449280, 2865769216, 1432101120, 1431319552, 1520445696, 2874318080, 2863673344, 1431315968, 1520999168, 1453337856, 2863964672, 2862626048, 3578800640, 1454087936, 1432367616, 2862622464, 3578928128, 2907713024, 1437475840, 1431320320, 2862623744, 2907971584, 2874159872, 1431316736, 2863308288, 1788882944, 2874156288, 1431902976, 1431318016, 1789731328, 1453339904, 2865768960, 1431511040, 3578802432, 1453336320, 2865863680, 2862624512, 3579192064, 3041932800, 1436560384, 2863407360, 2862625536, 3041929216, 1437212160, 1432367360, 2862621952, 3041958400, 2874158336, 1433215744, 1431319808, 1788881408, 2907905792, 2865771008, 1431316224, 1789500416, 1520447232, 2866160640, 2863674880, 1431317504, 1521262848, 1436562432, 2863671296, 1431477760, 3041931264, 1453336064, 2863700480, 2862624000, 3042255360, 2907714816, 1432365568, 2863374080, 2862625280, 2907711232, 1432984576, 1431318272, 2863506432, 1520449280, 2874157824, 1432101120, 1431319552, 1520445696, 2874318080, 2863673344, 1431315968, 1789434624, 1453337856, 2863964672, 2862626048, 3578800640, 1454087936, 1436561920, 2862622464, 3578928128, 2907713024, 1437475840, 1431320320, 2862623744, 3042189312, 2874159872, 1431316736, 2863308288, 1788882944, 2874156288, 1432951552, 1431318016, 1789731328, 1453339904, 2865768960, 1431511040, 3578802432, 1520445184, 2865863680, 2862624512, 3579192064, 3041932800, 1436560384, 2863931648, 2862625536, 3041929216, 1437212160, 1432367360, 2862621952, 3041958400, 2907712768, 1433215744, 1431319808, 1788881408, 2907905792, 2865771008, 1431316224, 2863242240, 1520447232, 2866160640, 2863674880, 1431317504, 1521262848, 1453339648, 2863671296, 1431477760, 3041931264, 1453336064, 2863700480, 2862624000, 3579126272, 2907714816, 1432365568, 2863374080, 2862625280, 2907711232, 1437178880, 1431318272, 2863506432, 1520449280, 2874157824, 1432101120, 1431319552, 1788881152, 2874318080, 2863673344, 1431315968, 1788910336, 2862623744, 3042255104, 2874160128, 1432365568, 2863373824, 1788883200, 2907710976, 1432984576, 1431318016, 1789764352, 1520449024, 2865769216, 1432100864, 1431319296, 1520445440, 2865929472, 2863673088, 1431315712, 1520998912, 1453337856, 2863964416, 2862625792, 3041929472, 1454087936, 1432367360, 2862622208, 3578927872, 2907713024, 1433281280, 1431320064, 2862623488, 2907971584, 2874159616, 1431316480, 2863308032, 1520447488, 2874156032, 1431902720, 1431317760, 1789731328, 1453339648, 2863671552, 1431510784, 3578802432, 1453336064, 2865863424, 2862624256, 3579192064, 2907714816, 1436560128, 2863407104, 2862625536, 3041928960, 1437211904, 1431318528, 2862621952, 3041958144, 2874158080, 1433215488, 1431319808, 1788881152, 2874351104, 2865770752, 1431316224, 1789500160, 1453338112, 2866160384, 2862626304, 3578800640, 1521262592, 1436562176, 2862622720, 3578960896, 3041931008, 1436558592, 2863700480, 2862623744, 3042255104, 2874160128, 1432365568, 2863373824, 1788883200, 2907710976, 1432984576, 1431318016, 1789764352, 1520449024, 2865769216, 1432100864, 1431319296, 1520445440, 2865929472, 2863673088, 1431315712, 1520998912, 1453337856, 2863964416, 2862625792, 3041929472, 1454087936, 1432367360, 2862622208, 3578927872, 2907713024, 1433281280, 1431320064, 2862623488, 2907971584, 2874159616, 1431316480, 2863308032, 1520447488, 2874156032, 1431902720, 1431317760, 1789731328, 1453339648, 2863671552, 1431510784, 3578802432, 1453336064, 2865863424, 2862624256, 3579192064, 2907714816, 1436560128, 2863407104, 2862625536, 3041928960, 1437211904, 1431318528, 2862621952, 3041958144, 2874158080, 1433215488, 1431319808, 1788881152, 2874351104, 2865770752, 1431316224, 1789500160, 1453338112, 2866160384, 2862626304, 3578800640, 1521262592, 1436562176, 2862622720, 3578960896, 3041931008, 1436558592, 2
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 处理公元-105-1912年间的农历
|
|||
|
// 返回:农历年,农历月,农历月干支(闰月从上月),农历日,是否闰月,农历日期字符串
|
|||
|
func rapidLunarHan2Qing(year, month, day int, diff int, options func() map[int]uint32) (int, int, string, int, bool, string) {
|
|||
|
useGoto := false
|
|||
|
beijingTime := time.FixedZone("CST", 8*3600)
|
|||
|
recalc:
|
|||
|
idx := year + 105
|
|||
|
magic := getHanQingCals()[idx]
|
|||
|
if options != nil {
|
|||
|
if v, ok := options()[year]; ok {
|
|||
|
magic = v
|
|||
|
}
|
|||
|
}
|
|||
|
springDays := int8((magic >> 7)) >> 1
|
|||
|
if springDays>>6 == 1 {
|
|||
|
springDays = -(springDays << 2 >> 2)
|
|||
|
}
|
|||
|
springDate := time.Date(year-1, 12, 31, 0, 0, 0, 0, beijingTime).AddDate(0, 0, int(springDays))
|
|||
|
if !useGoto && (int(springDate.Month()) > month || ((int(springDate.Month()) == month) && springDate.Day() > day)) {
|
|||
|
year--
|
|||
|
useGoto = true
|
|||
|
goto recalc
|
|||
|
}
|
|||
|
calcYear := year
|
|||
|
if useGoto {
|
|||
|
calcYear++
|
|||
|
}
|
|||
|
target := time.Date(calcYear, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
|||
|
diffDay := int(target.Sub(springDate).Hours() / 24)
|
|||
|
//go语言在; 1582年10月4日前,使用的是逆推格里高利历,与实际使用的儒略历有所不同,主要体现在百年闰年计算上!
|
|||
|
//儒略历修正
|
|||
|
if springDate.Year()%100 == 0 && springDate.Year()%400 != 0 && springDate.Year() < 1582 && (target.Month() >= 3 || (target.Year() > springDate.Year())) {
|
|||
|
diffDay++
|
|||
|
}
|
|||
|
//儒略历转格里高历修正
|
|||
|
if calcYear == 1582 && ((month == 10 && day >= 15) || month > 10) {
|
|||
|
diffDay -= 10
|
|||
|
}
|
|||
|
if calcYear == 1583 && month == 1 && day <= 23 {
|
|||
|
diffDay -= 10
|
|||
|
}
|
|||
|
lunarMonth := 1
|
|||
|
totalDay := 0
|
|||
|
isLeap := false
|
|||
|
leapMonth := int(uint8(magic>>15) & 0xF)
|
|||
|
for i := 0; i < 13; i++ {
|
|||
|
var dayofLunar = 29
|
|||
|
if uint8(magic>>(31-i))&1 == 1 {
|
|||
|
dayofLunar++
|
|||
|
}
|
|||
|
if totalDay+dayofLunar > diffDay {
|
|||
|
lday := diffDay - totalDay + 1
|
|||
|
|
|||
|
format := formatLunarDateString(lunarMonth, lday, isLeap, diff)
|
|||
|
ganzhiOfMonth := commonGanZhiOfMonth(year, lunarMonth)
|
|||
|
|
|||
|
if diff == 255 {
|
|||
|
diff = 2
|
|||
|
}
|
|||
|
if diff != 0 {
|
|||
|
lunarMonth += diff
|
|||
|
if lunarMonth > 12 {
|
|||
|
lunarMonth -= 12
|
|||
|
year++
|
|||
|
}
|
|||
|
}
|
|||
|
return year, lunarMonth, ganzhiOfMonth, lday, isLeap, format
|
|||
|
}
|
|||
|
totalDay += dayofLunar
|
|||
|
lunarMonth++
|
|||
|
if lunarMonth-leapMonth == 1 && !isLeap {
|
|||
|
isLeap = true
|
|||
|
lunarMonth--
|
|||
|
} else {
|
|||
|
isLeap = false
|
|||
|
}
|
|||
|
}
|
|||
|
return 0, 0, "", 0, false, "无法获取农历信息"
|
|||
|
}
|
|||
|
|
|||
|
func rapidSolarHan2Qing(year, month, day int, isLeap bool, diff int, options func() map[int]uint32) time.Time {
|
|||
|
useGoto := false
|
|||
|
beijingTime := time.FixedZone("CST", 8*3600)
|
|||
|
recalc:
|
|||
|
idx := year + 105
|
|||
|
magic := getHanQingCals()[idx]
|
|||
|
if options != nil {
|
|||
|
if v, ok := options()[year]; ok {
|
|||
|
magic = v
|
|||
|
}
|
|||
|
}
|
|||
|
springDays := int8((magic >> 7)) >> 1
|
|||
|
if springDays>>6 == 1 {
|
|||
|
springDays = -(springDays << 2 >> 2)
|
|||
|
}
|
|||
|
springDate := time.Date(year-1, 12, 31, 0, 0, 0, 0, beijingTime).AddDate(0, 0, int(springDays))
|
|||
|
if diff == 255 {
|
|||
|
diff = 2
|
|||
|
}
|
|||
|
if diff > 0 && !useGoto {
|
|||
|
month = month - diff
|
|||
|
if month <= 0 {
|
|||
|
month += 12
|
|||
|
year--
|
|||
|
useGoto = true
|
|||
|
goto recalc
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
lunarMonth := 1
|
|||
|
totalDay := 0
|
|||
|
leap := false
|
|||
|
leapMonth := int(uint8(magic>>15) & 0xF)
|
|||
|
for i := 0; i < 13; i++ {
|
|||
|
if lunarMonth == month && isLeap == leap {
|
|||
|
target := springDate.AddDate(0, 0, totalDay+day-1)
|
|||
|
if target.Year() == 1582 && ((target.Month() == 10 && target.Day() > 4) || target.Month() > 10) {
|
|||
|
target = target.AddDate(0, 0, 10)
|
|||
|
}
|
|||
|
//go语言在; 1582年10月4日前,使用的是逆推格里高利历,与实际使用的儒略历有所不同,主要体现在百年闰年计算上!
|
|||
|
//儒略历修正
|
|||
|
if springDate.Year()%100 == 0 && springDate.Year()%400 != 0 && springDate.Year() < 1582 && (target.Month() >= 3 || (target.Year() > springDate.Year())) {
|
|||
|
target = target.AddDate(0, 0, -1)
|
|||
|
}
|
|||
|
return target
|
|||
|
}
|
|||
|
var dayofLunar = 29
|
|||
|
if uint8(magic>>(31-i))&1 == 1 {
|
|||
|
dayofLunar++
|
|||
|
}
|
|||
|
totalDay += dayofLunar
|
|||
|
lunarMonth++
|
|||
|
if lunarMonth-leapMonth == 1 && !leap {
|
|||
|
leap = true
|
|||
|
lunarMonth--
|
|||
|
} else {
|
|||
|
leap = false
|
|||
|
}
|
|||
|
}
|
|||
|
return time.Time{}
|
|||
|
}
|
|||
|
|
|||
|
func yearDiff(year, month, day int) int {
|
|||
|
// 王莽改制,公元9年-22年,建丑为正月
|
|||
|
// 注意,公元23年恢复建寅为正月,但是当年还是新朝地皇四年,如果在新朝的角度,当年还是建丑为正月!
|
|||
|
if year == 9 && month == 1 && day < 15 {
|
|||
|
return 0
|
|||
|
}
|
|||
|
if year == 23 && month == 12 && day == 31 {
|
|||
|
return 0
|
|||
|
}
|
|||
|
if year >= 9 && year <= 23 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
//魏明帝改制,公元237年-240年,建丑为正月
|
|||
|
if year == 237 && month > 4 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
if year == 237 && month == 4 && day >= 12 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
if year > 237 && year < 240 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
if year == 240 && month == 1 && day < 12 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
//武则天改制,公元690年-700年,建子为正月
|
|||
|
if year == 689 && month == 12 && day >= 18 {
|
|||
|
return 255
|
|||
|
}
|
|||
|
if year >= 690 && year < 700 {
|
|||
|
return 255
|
|||
|
}
|
|||
|
if year == 700 && (month < 12 || month == 12 && day <= 14) {
|
|||
|
return 255
|
|||
|
}
|
|||
|
//唐肃宗改制,公元761-762年,建寅为正月
|
|||
|
if year == 761 && month == 12 && day >= 2 {
|
|||
|
return 2
|
|||
|
}
|
|||
|
if year == 762 && month < 4 {
|
|||
|
return 2
|
|||
|
}
|
|||
|
if year == 762 && month == 4 && day < 29 {
|
|||
|
return 2
|
|||
|
}
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
func yearDiffLunar(year, month, day int) int {
|
|||
|
// 王莽改制,公元9年-22年,建丑为正月
|
|||
|
// 注意,公元23年恢复建寅为正月,但是当年还是新朝地皇四年,如果在新朝的角度,当年还是建丑为正月!
|
|||
|
if year >= 9 && year <= 23 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
//魏明帝改制,公元237年-240年,建丑为正月
|
|||
|
if year == 237 && month >= 4 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
if year > 237 && year < 240 {
|
|||
|
return 1
|
|||
|
}
|
|||
|
|
|||
|
//武则天改制,公元690年-700年,建子为正月
|
|||
|
if year >= 690 && year < 700 {
|
|||
|
return 255
|
|||
|
}
|
|||
|
//有两个12月
|
|||
|
if year == 700 && month != 11 {
|
|||
|
return 255
|
|||
|
}
|
|||
|
//唐肃宗改制,公元761-762年,建寅为正月
|
|||
|
if year == 762 && month <= 5 {
|
|||
|
return 2
|
|||
|
}
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
func formatLunarDateString(lunarMonth, lunarDay int, isLeap bool, diff int) string {
|
|||
|
monthNames := []string{"十", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"}
|
|||
|
dayNames := []string{"十", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}
|
|||
|
dayPrefixes := []string{"初", "十", "廿", "三"}
|
|||
|
switch diff {
|
|||
|
case 1:
|
|||
|
monthNames = []string{"十", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊", "正"}
|
|||
|
case 2:
|
|||
|
monthNames = []string{"十", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊", "正", "二"}
|
|||
|
case 3:
|
|||
|
monthNames = []string{"十", "四", "五", "六", "七", "八", "九", "十", "冬", "腊", "正", "二", "三"}
|
|||
|
case 255:
|
|||
|
//武则天改制,将冬月成为正月,正月改为一月
|
|||
|
monthNames = []string{"十", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "正", "腊"}
|
|||
|
}
|
|||
|
var dateString string
|
|||
|
|
|||
|
if isLeap {
|
|||
|
dateString += "闰"
|
|||
|
}
|
|||
|
dateString += monthNames[lunarMonth] + "月"
|
|||
|
|
|||
|
if lunarDay == 20 {
|
|||
|
dateString += "二十"
|
|||
|
} else if lunarDay == 10 {
|
|||
|
dateString += "初十"
|
|||
|
} else {
|
|||
|
dateString += dayPrefixes[lunarDay/10] + dayNames[lunarDay%10]
|
|||
|
}
|
|||
|
|
|||
|
return dateString
|
|||
|
}
|
|||
|
|
|||
|
func innerSolarToLunarHanQing(date time.Time) Time {
|
|||
|
year := date.Year()
|
|||
|
month := int(date.Month())
|
|||
|
day := date.Day()
|
|||
|
yeardiff := yearDiff(year, month, day)
|
|||
|
lyear, lmonth, ganzhiMonth, lday, isLeap, ldesc := rapidLunarHan2Qing(year, month, day, yeardiff, nil)
|
|||
|
var eras []EraDesc
|
|||
|
if lyear >= -103 && lyear <= 220 {
|
|||
|
eras = innerEras(lyear, hanEras)
|
|||
|
} else if lyear >= 221 && lyear <= 617 {
|
|||
|
eras = innerEras(lyear, weiJinNanBeiChaoEras)
|
|||
|
} else if lyear >= 618 && lyear <= 907 {
|
|||
|
eras = innerEras(lyear, tangEras)
|
|||
|
} else if lyear > 907 && lyear < 1368 {
|
|||
|
eras = innerEras(lyear, wudaiSongYuanEras)
|
|||
|
} else if lyear <= 1912 {
|
|||
|
eras = innerEras(lyear, mingQingEras)
|
|||
|
}
|
|||
|
ldate := LunarTime{
|
|||
|
solarDate: date,
|
|||
|
year: lyear,
|
|||
|
month: lmonth,
|
|||
|
day: lday,
|
|||
|
leap: isLeap,
|
|||
|
desc: ldesc,
|
|||
|
eras: eras,
|
|||
|
ganzhiMonth: ganzhiMonth,
|
|||
|
comment: "",
|
|||
|
}
|
|||
|
var otherLunars []LunarTime
|
|||
|
//王莽特殊处理
|
|||
|
if lyear == 23 {
|
|||
|
liuxiu := ldate.eras[len(ldate.eras)-1:]
|
|||
|
ldate.eras = ldate.eras[:1]
|
|||
|
if month > 2 || (month == 2 && day >= 10) {
|
|||
|
lyear, lmonth, ganzhiMonth, lday, isLeap, ldesc = rapidLunarHan2Qing(year, month, day, 0, nil)
|
|||
|
otherLunars = append(otherLunars, LunarTime{
|
|||
|
solarDate: date,
|
|||
|
year: lyear,
|
|||
|
month: lmonth,
|
|||
|
day: lday,
|
|||
|
leap: isLeap,
|
|||
|
desc: ldesc,
|
|||
|
eras: liuxiu,
|
|||
|
ganzhiMonth: ganzhiMonth,
|
|||
|
comment: "",
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
result := Time{
|
|||
|
solarTime: date,
|
|||
|
lunars: append([]LunarTime{ldate}, otherLunars...),
|
|||
|
}
|
|||
|
//三国时期
|
|||
|
if year >= 220 && year <= 280 {
|
|||
|
return innerSolarToLunarSanGuo(result)
|
|||
|
}
|
|||
|
//南北朝时期
|
|||
|
if year >= 384 && year <= 589 {
|
|||
|
return innerSolarToLunarNanBeiChao(result)
|
|||
|
}
|
|||
|
//五代十国辽金元
|
|||
|
if year >= 947 && year <= 1279 {
|
|||
|
return innerSolarToLunarLiaoJinYuan(result)
|
|||
|
}
|
|||
|
if year > 1644 && year < 1884 {
|
|||
|
return innerSolarToLunarNanMing(result)
|
|||
|
}
|
|||
|
return result
|
|||
|
}
|
|||
|
|
|||
|
func innerParseLunar(lunar string) ([]time.Time, error) {
|
|||
|
date, err := parseChineseDate(lunar)
|
|||
|
if err != nil {
|
|||
|
return []time.Time{}, err
|
|||
|
}
|
|||
|
if date.year != 0 && date.comment == "" {
|
|||
|
if date.year < -103 || date.year > 3000 {
|
|||
|
return nil, fmt.Errorf("年份超出范围")
|
|||
|
}
|
|||
|
if date.year <= 1912 {
|
|||
|
d := rapidSolarHan2Qing(date.year, date.month, date.day, date.leap, yearDiffLunar(date.year, date.month, date.day), nil)
|
|||
|
return []time.Time{d}, nil
|
|||
|
}
|
|||
|
if date.year < 2400 {
|
|||
|
dates := rapidSolarModern(date.year, date.month, date.day, date.leap)
|
|||
|
return []time.Time{dates}, nil
|
|||
|
}
|
|||
|
dates := Solar(date.year, date.month, date.day, date.leap, 8.0)
|
|||
|
return []time.Time{dates}, nil
|
|||
|
}
|
|||
|
|
|||
|
data, err := innerLunar2SolarHanQing(date, nianHaoMap, nil)
|
|||
|
if err != nil && err != ERR_NIANHAO_NOT_FOUND {
|
|||
|
return data, err
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, shuEraMap, shuCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, wuEraMap, wuCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, houQinEraMap, houQinCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, weiZhouSuiEraMap, weiZhouSuiCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, beiLiangEraMap, beiLiangCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, dongWeiBeiQiEraMap, dongWeiBeiQiCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, liaoJinYuanEraMap, liaoJinYuanCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
if tmp, err := innerLunar2SolarHanQing(date, nanMingEraMap, nanMingCals); err == nil {
|
|||
|
data = append(data, tmp...)
|
|||
|
}
|
|||
|
return data, nil
|
|||
|
}
|
|||
|
|
|||
|
func innerLunar2SolarHanQing(data LunarTime, nianHaoMap func() map[string][][]int, options func() map[int]uint32) ([]time.Time, error) {
|
|||
|
isGanZhiDay := false
|
|||
|
var tgIdx, dzIdex int
|
|||
|
if data.ganzhiMonth != "" && data.day == 0 {
|
|||
|
//日干支求解,先计算此月的初一,然后根据日干支求解
|
|||
|
isGanZhiDay = true
|
|||
|
data.day = 1
|
|||
|
for idx, v := range tiangan {
|
|||
|
if strings.HasPrefix(data.ganzhiMonth, v) {
|
|||
|
tgIdx = idx
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
for idx, v := range dizhi {
|
|||
|
if strings.HasSuffix(data.ganzhiMonth, v) {
|
|||
|
dzIdex = idx
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
years := nianHaoMap()[data.comment]
|
|||
|
if len(years) == 0 {
|
|||
|
return []time.Time{}, ERR_NIANHAO_NOT_FOUND
|
|||
|
}
|
|||
|
var res []time.Time
|
|||
|
for _, y := range years {
|
|||
|
if y[1]-y[0]+1 < data.year {
|
|||
|
continue
|
|||
|
}
|
|||
|
year := y[0] + data.year - 1
|
|||
|
diff := yearDiffLunar(year, data.month, data.day)
|
|||
|
//diff!=0且option!=nil时,只有三国时期存在,此时因为蜀汉和吴国都没有改制,所以不进行处理
|
|||
|
if options != nil {
|
|||
|
diff = 0
|
|||
|
}
|
|||
|
if diff == 255 {
|
|||
|
if year == 700 && data.month == 12 {
|
|||
|
res = append(res, rapidSolarHan2Qing(year, data.month, data.day, data.leap, 0, options))
|
|||
|
}
|
|||
|
data.month = data.month + 2
|
|||
|
if data.month > 12 {
|
|||
|
data.month = data.month - 12
|
|||
|
}
|
|||
|
if data.month == 3 && strings.Contains(data.desc, "正月") {
|
|||
|
data.month = 1
|
|||
|
}
|
|||
|
}
|
|||
|
if year == 23 && data.comment == "更始" {
|
|||
|
diff = 0
|
|||
|
}
|
|||
|
res = append(res, rapidSolarHan2Qing(year, data.month, data.day, data.leap, diff, options))
|
|||
|
//当年两个12月
|
|||
|
if year == 239 && data.month == 12 {
|
|||
|
res = append(res, rapidSolarHan2Qing(year, data.month, data.day, data.leap, 0, options))
|
|||
|
}
|
|||
|
//当年两个4月,5月
|
|||
|
if year == 762 && (data.month == 4 || data.month == 5) {
|
|||
|
res = append(res, rapidSolarHan2Qing(year, data.month, data.day, data.leap, 0, options))
|
|||
|
}
|
|||
|
}
|
|||
|
var realRes []time.Time
|
|||
|
for _, v := range res {
|
|||
|
if v.IsZero() {
|
|||
|
continue
|
|||
|
}
|
|||
|
if !isGanZhiDay {
|
|||
|
realRes = append(realRes, v)
|
|||
|
continue
|
|||
|
}
|
|||
|
//干支日求解
|
|||
|
curTgIdx, curDzIdx := ganZhiOfDayIndex(v)
|
|||
|
tgDiff := (tgIdx - curTgIdx + 10) % 10
|
|||
|
dzDiff := (dzIdex - curDzIdx + 12) % 12
|
|||
|
delta := (dzDiff - tgDiff + 12) % 12
|
|||
|
delta2 := delta / 2
|
|||
|
k := (delta2 * 5) % 6
|
|||
|
d := tgDiff + 10*k
|
|||
|
if d < 0 {
|
|||
|
d += 60
|
|||
|
}
|
|||
|
if d > 30 {
|
|||
|
continue
|
|||
|
}
|
|||
|
oldv := v
|
|||
|
v = v.Add(time.Duration(d) * 24 * time.Hour)
|
|||
|
if v.Year()%100 == 0 && v.Year()%400 != 0 && v.Month() >= 3 && v.Year() < 1582 {
|
|||
|
if oldv.Month() < 3 {
|
|||
|
v = v.AddDate(0, 0, 1)
|
|||
|
}
|
|||
|
}
|
|||
|
if oldv.Year() == 1582 && ((oldv.Month() == 10 && oldv.Day() <= 4) || oldv.Month() < 10) {
|
|||
|
if v.Month() > 10 || (v.Month() == 10 && v.Day() > 4) {
|
|||
|
v = v.AddDate(0, 0, 10)
|
|||
|
}
|
|||
|
}
|
|||
|
realRes = append(realRes, v)
|
|||
|
}
|
|||
|
return realRes, nil
|
|||
|
}
|