From 98ed1980ff21a299f03d5a91343dea0a799e3266 Mon Sep 17 00:00:00 2001 From: Starainrt Date: Fri, 17 Jan 2025 20:11:08 +0800 Subject: [PATCH] update --- astro/astro.go | 74 ++ astro/calendar.go | 431 +++++++++ astro/calendar_test.go | 37 + astro/chineseday.go | 691 ++++++++++++++ astro/city.json | 2024 ++++++++++++++++++++++++++++++++++++++++ astro/cmd.go | 197 ++++ astro/moon.go | 130 +++ astro/star.go | 101 ++ astro/sun.go | 76 ++ go.mod | 4 +- go.sum | 17 + main.go | 3 +- nmon/cpu.go | 28 + nmon/cpu_test.go | 7 + 14 files changed, 3818 insertions(+), 2 deletions(-) create mode 100644 astro/astro.go create mode 100644 astro/calendar.go create mode 100644 astro/calendar_test.go create mode 100644 astro/chineseday.go create mode 100644 astro/city.json create mode 100644 astro/cmd.go create mode 100644 astro/moon.go create mode 100644 astro/star.go create mode 100644 astro/sun.go create mode 100644 nmon/cpu.go create mode 100644 nmon/cpu_test.go diff --git a/astro/astro.go b/astro/astro.go new file mode 100644 index 0000000..332dffb --- /dev/null +++ b/astro/astro.go @@ -0,0 +1,74 @@ +package astro + +import ( + _ "embed" + "encoding/json" + "errors" + "fmt" + "os" + "strings" + "time" +) + +//go:embed city.json +var cityByte []byte + +type City struct { + Code int `json:"code"` + CityName string `json:"city_name"` + Lat float64 `json:"lat"` + Lon float64 `json:"lon"` +} + +var lon, lat, height, loc float64 +var city string + +func SetLonLatHeight(lo, la, he float64) error { + lon, lat, height = lo, la, he + return os.WriteFile(".ast.env", []byte(fmt.Sprintf("%f,%f,%f,%f", lon, lat, height, loc)), 0644) +} + +func LoadLonLatHeight() error { + if _, err := os.Stat(".ast.env"); errors.Is(err, os.ErrNotExist) { + return nil + } + b, err := os.ReadFile(".ast.env") + if err != nil { + return err + } + _, err = fmt.Sscanf(string(b), "%f,%f,%f,%f", &lon, &lat, &height, &loc) + return err +} + +func GetLonLatHeight() (float64, float64, float64) { + return lon, lat, height +} + +func Lon() float64 { + return lon +} + +func Lat() float64 { + return lat +} + +func Height() float64 { + return height +} + +func GetFromCity(name string) bool { + var c []City + err := json.Unmarshal(cityByte, &c) + if err != nil { + return false + } + for _, v := range c { + if strings.Contains(v.CityName, name) { + lon, lat = v.Lon, v.Lat + loc = 8 + time.Local = time.FixedZone("Local", int(loc*3600)) + return true + } + } + return false +} diff --git a/astro/calendar.go b/astro/calendar.go new file mode 100644 index 0000000..dbba147 --- /dev/null +++ b/astro/calendar.go @@ -0,0 +1,431 @@ +package astro + +import ( + "b612.me/astro/calendar" + "b612.me/staros" + "fmt" + "github.com/spf13/cobra" + "golang.org/x/term" + "os" + "strconv" + "strings" + "time" +) + +var year int +var nowDay string +var isTimestamp bool +var isLunar, isLive, isLeap bool + +func init() { + CmdDateInfo.Flags().StringVarP(&nowDay, "now", "n", "", "指定现在的时间") + CmdDateInfo.Flags().BoolVarP(&isTimestamp, "timestamp", "t", false, "是否为时间戳") + CmdDateInfo.Flags().BoolVarP(&isLunar, "lunar", "l", false, "是否为农历") + CmdDateInfo.Flags().BoolVarP(&isLive, "live", "v", false, "是否为实时") + CmdDateInfo.Flags().BoolVarP(&isLeap, "leap", "L", false, "是否为农历闰月") + CmdHoliday.Flags().IntVarP(&year, "year", "y", 0, "年份") + CmdCal.AddCommand(CmdHoliday, CmdDateInfo) +} + +var CmdCal = &cobra.Command{ + Use: "cal", + Args: cobra.MaximumNArgs(100), + Short: "简洁日历与日期相关方法", + Long: "简洁日历,支持多个月份,多个年份,支持年份月份混合输入,日期方法请查看子命令", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + now := time.Now() + fmt.Println(now.Format("2006年01月")) + fmt.Println("------------------------") + ShowCalendar(now.Year(), int(now.Month())) + return + } + for _, v := range args { + if len(v) < 4 { + fmt.Println("输入错误,年份至少4位") + return + } + year, err := strconv.Atoi(v[:4]) + if err != nil { + fmt.Println("输入错误:", err) + return + } + if len(v) == 4 { + for i := 1; i <= 12; i++ { + fmt.Printf("%d年%d月\n", year, i) + fmt.Println("------------------------") + ShowCalendar(year, i) + fmt.Println() + fmt.Println() + } + continue + } + month, err := strconv.Atoi(v[4:]) + if err != nil { + fmt.Println("输入错误:", err) + return + } + fmt.Printf("%d年%d月\n", year, month) + fmt.Println("------------------------") + ShowCalendar(year, month) + fmt.Println() + } + }, +} + +var CmdHoliday = &cobra.Command{ + Use: "hol", + Short: "中国法定节日放假安排", + Long: "中国法定节日放假安排", + Run: func(cmd *cobra.Command, args []string) { + if year == 0 { + year = time.Now().Year() + } + fmt.Printf("%d年放假安排\n", year) + for _, v := range args { + fmt.Println("------------------------") + var d Holiday + switch v { + case "1", "元旦": + d = YuanDan(year) + case "2", "春节": + d = ChunJie(year) + case "3", "清明", "清明节": + d = QingMing(year) + case "4", "劳动", "劳动节": + d = LaoDongJie(year) + case "5", "端午", "端午节": + d = DuanWu(year) + case "6", "中秋", "中秋节": + d = ZhongQiu(year) + case "7", "国庆", "国庆节": + d = GuoQing(year) + } + d.BasicInfo() + d.Detail() + } + if len(args) == 0 { + for _, v := range ChineseHoliday(year) { + fmt.Println("------------------------") + v.BasicInfo() + v.Detail() + fmt.Println(" ") + } + } + }, +} + +var CmdDateInfo = &cobra.Command{ + Use: "info", + Short: "指定时刻的详情", + Long: "指定时刻的详情,格式:info [时间] [选项]", + Run: func(cmd *cobra.Command, args []string) { + var now = time.Now() + var target = now + var err error + if nowDay != "" { + now, err = parseDate(time.Time{}, nowDay, isTimestamp) + if err != nil { + fmt.Println(err) + return + } + } + if len(args) > 0 { + target, err = parseDate(now, args[0], isTimestamp) + if err != nil { + fmt.Println(err) + return + } + } + for { + if isLunar { + LDateInfo(now, target, isLeap) + } else { + DateInfo(now, target) + } + if !isLive { + break + } + time.Sleep(time.Nanosecond* + time.Duration(1000000000-time.Now().Nanosecond()) + 1) + if nowDay == "" { + now = time.Now() + now = now.Add(time.Duration(now.Nanosecond()*-1) * time.Nanosecond) + } else { + now = now.Add(time.Second) + } + ClearScreen() + } + }, +} + +func ClearScreen() { + fmt.Print("\033[H\033[2J") +} + +func GenerateCalendar(year int, month int) []string { + var days []string + date := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local) + firstWeekday := int(date.Weekday()) - 1 + if firstWeekday < 0 { + firstWeekday += 7 + } + count := 0 + for i := 0; i < firstWeekday; i++ { + days = append(days, " ") + count++ + } + for i := 1; i <= 32; i++ { + insertLunar := func(start int) { + if start < 0 { + start += 7 + } + for j := start; j >= 0; j-- { + if i-j < 1 { + days = append(days, "\u3000\u3000") + continue + } + date = time.Date(year, time.Month(month), i-j, 0, 0, 0, 0, time.Local) + _, d, _, str := calendar.RapidSolarToLunar(date) + if d != 1 { + str = str[strings.Index(str, "月")+3:] + + } else { + str = str[:strings.Index(str, "月")+3] + } + days = append(days, str) + } + } + date = time.Date(year, time.Month(month), i, 0, 0, 0, 0, time.Local) + if date.Month() != time.Month(month) { + if (count)%7 != 0 { + i-- + insertLunar(count%7 - 1) + } + break + } + days = append(days, fmt.Sprintf("%d", i)) + count++ + if count%7 == 0 { + insertLunar(6) + } + } + return days +} + +func ShowCalendar(year int, month int) { + days := GenerateCalendar(year, month) + fd := int(os.Stdout.Fd()) + width, _, err := term.GetSize(fd) + if err != nil { + fmt.Println("Error getting terminal size:", err) + return + } + spark := 4 + if width > 45 { + spark = 5 + } + if width < 30 { + fmt.Println("Terminal too small") + return + } + for _, v := range []string{"\u3000一", "\u3000二", "\u3000三", "\u3000四", "\u3000五", "\u3000六", "\u3000日"} { + fmt.Printf("%*s", spark-1, v) + } + fmt.Println() + ct := 0 + doBreak := false + for i, v := range days { + if len(days)-i < 7 && i%7 == len(days)-i && !doBreak { + doBreak = true + ct++ + if ct%2 == 1 { + spark -= 2 + } else { + spark += 2 + } + fmt.Println() + fmt.Print(" ") + } + if i%7 == 0 && i != 0 && !doBreak { + fmt.Println() + ct++ + if ct%2 == 1 { + fmt.Print(" ") + spark -= 2 + } else { + spark += 2 + } + } + fmt.Printf("%*s ", spark, v) + } +} + +func LDateInfo(now, date time.Time, isLeap bool) { + sdate := calendar.RapidLunarToSolar(date.Year(), int(date.Month()), date.Day(), isLeap) + DateInfo(now, sdate) +} +func DateInfo(now, date time.Time) { + if now.IsZero() { + now = time.Now() + } + _, m, _, str := calendar.RapidSolarToLunar(date) + gz := calendar.GanZhi(date.Year()) + if m > 10 && int(date.Month()) < 3 { + gz = calendar.GanZhi(date.Year() - 1) + } + fmt.Println("现在:", now.Format("2006年01月02日 15:04:05")) + fmt.Println("-------------------------") + xq := []string{"日", "一", "二", "三", "四", "五", "六"} + fmt.Printf("公历:%s 星期%s\n", date.Format("2006年01月02日 15:04:05"), xq[date.Weekday()]) + fmt.Println("农历:", gz+str) + fmt.Printf("时间戳:%v\n", date.Unix()) + fmt.Println("-------------------------") + diff := date.Sub(now) + fmt.Printf("距今: %.5f秒\n", diff.Seconds()) + fmt.Printf("距今: %.5f分钟\n", diff.Minutes()) + fmt.Printf("距今: %.5f小时\n", diff.Hours()) + fmt.Printf("距今: %.5f天\n", diff.Hours()/24) + fmt.Printf("距今: %.5f年\n", diff.Hours()/24/365.2425) + fmt.Println("距今:", dayDiff(now, date)) +} + +func dayDiff(date1, date2 time.Time) string { + // 提取年、月、日 + pr := "" + if date1.After(date2) { + pr = "-" + date1, date2 = date2, date1 + } + years, months, days := date2.Date() + yearDiff := years - date1.Year() + monthDiff := int(months) - int(date1.Month()) + dayDiff := days - date1.Day() + + // 处理负的月份和日期差 + if dayDiff < 0 { + monthDiff-- + // 计算上个月的天数 + prevMonth := date2.AddDate(0, -1, 0) + dayDiff += time.Date(prevMonth.Year(), prevMonth.Month(), 0, 0, 0, 0, 0, time.UTC).Day() + } + if monthDiff < 0 { + yearDiff-- + monthDiff += 12 + } + + // 提取小时、分钟和秒 + hours := date2.Hour() - date1.Hour() + minutes := date2.Minute() - date1.Minute() + seconds := date2.Second() - date1.Second() + + // 处理负的小时、分钟和秒差 + if seconds < 0 { + minutes-- + seconds += 60 + } + if minutes < 0 { + hours-- + minutes += 60 + } + if hours < 0 { + days-- + hours += 24 + } + + return fmt.Sprintf("%s%d年%d月%d日%d时%d分%d秒", pr, yearDiff, monthDiff, dayDiff, hours, minutes, seconds) +} + +func parseDate(base time.Time, date string, isTimestamp bool) (time.Time, error) { + if isTimestamp { + i, err := strconv.Atoi(date) + if err != nil { + return time.Time{}, err + } + return time.Unix(int64(i), 0), nil + } + if base.IsZero() { + base = time.Now() + } + if strings.HasPrefix(date, "+") || strings.HasPrefix(date, "p") { + val, err := staros.Calc(date[1:]) + if err != nil { + return time.Time{}, err + } + for val > 9.22e09 { + val = val - 9.22e09 + base = base.Add(9.22e09 * time.Second) + } + return base.Add(time.Second * time.Duration(int(val))), nil + } + if strings.HasPrefix(date, "-") || strings.HasPrefix(date, "—") || + strings.HasPrefix(date, "~") || strings.HasPrefix(date, "!") || + strings.HasPrefix(date, "m") { + val, err := staros.Calc(date[1:]) + if err != nil { + return time.Time{}, err + } + for val > 9.22e09 { + val = val - 9.22e09 + base = base.Add(-9.22e09 * time.Second) + } + return base.Add(-1 * time.Second * time.Duration(int(val))), nil + } + if strings.Contains(date, "-") { + + d, err := time.ParseInLocation("2006-01-02 15:04:05", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("2006-01-02", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("2006-01-02T15:04:05-0700", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("2006-01-02T15:04:05Z", date, time.Local) + if err == nil { + return d, nil + } + return time.Time{}, err + } + if strings.Contains(date, "/") { + d, err := time.ParseInLocation("2006/01/02 15:04:05", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("2006/01/02", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("02/01/2006 15:04:05", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("02/01/2006", date, time.Local) + if err == nil { + return d, nil + } + + d, err = time.ParseInLocation("01/02/2006 15:04:05", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("01/02/2006", date, time.Local) + if err == nil { + return d, nil + } + return time.Time{}, err + } + d, err := time.ParseInLocation("20060102150405", date, time.Local) + if err == nil { + return d, nil + } + d, err = time.ParseInLocation("20060102", date, time.Local) + if err == nil { + return d, nil + } + return time.Time{}, fmt.Errorf("无法解析日期") +} diff --git a/astro/calendar_test.go b/astro/calendar_test.go new file mode 100644 index 0000000..dd174dc --- /dev/null +++ b/astro/calendar_test.go @@ -0,0 +1,37 @@ +package astro + +import ( + "fmt" + "testing" + "time" +) + +func TestCal(t *testing.T) { + //LDateInfo(time.Time{}, time.Date(2021, 1, 1, 0, 0, 0, 0, time.Local), false) + //DateInfo(time.Time{}, time.Now().Add(time.Second*-5)) + for y := 2008; y < 2028; y++ { + zq := GuoQing(y) + zq.BasicInfo() + zq.Detail() + fmt.Println("--------") + } + +} + +func TestChineseHoliday(t *testing.T) { + legalData := [][]Holiday{ + //year 2000 + { + { + Start: time.Date(1999, 12, 31, 0, 0, 0, 0, time.Local), + End: time.Date(2000, 1, 2, 0, 0, 0, 0, time.Local), + Core: time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local), + Total: 3, + Instead: nil, + Name: "元旦", + LegalDays: 1, + }, + }, + } + _ = legalData +} diff --git a/astro/chineseday.go b/astro/chineseday.go new file mode 100644 index 0000000..b360729 --- /dev/null +++ b/astro/chineseday.go @@ -0,0 +1,691 @@ +package astro + +import ( + "b612.me/astro/calendar" + "fmt" + "time" +) + +type Holiday struct { + //假日开始时间 + Start time.Time + //假日结束时间 + End time.Time + //节日所在日期 + Core time.Time + //假日总天数 + Total int + //调休日期 + Instead []time.Time + //假日名称 + Name string + //法定假日天数 + LegalDays int + Comment string +} + +func (h Holiday) BasicInfo() { + xq := []string{"日", "一", "二", "三", "四", "五", "六"} + _, m, _, str := calendar.RapidSolarToLunar(h.Core) + gz := calendar.GanZhi(h.Core.Year()) + if m > 10 && int(h.Core.Month()) < 3 { + gz = calendar.GanZhi(h.Core.Year() - 1) + } + if h.Start.IsZero() { + fmt.Println(h.Name + "无假期") + return + } + fmt.Printf("节日: %s 法定假期: %d天 放假天数: %d天\n", h.Name, h.LegalDays, h.Total) + fmt.Println("公历:", h.Core.Format("2006年01月02日"), "星期"+xq[h.Core.Weekday()]) + fmt.Println("农历:", gz+str) + if h.Comment != "" { + fmt.Println(h.Comment) + } +} + +func (h Holiday) Detail() { + if h.Start.IsZero() { + return + } + xq := []string{"日", "一", "二", "三", "四", "五", "六"} + if h.Start.Equal(h.End) || h.End.IsZero() { + fmt.Printf("假期: %s(星期%s) 共%d天\n", + h.Start.Format("2006年01月02日"), xq[h.Start.Weekday()], h.Total) + } else { + fmt.Printf("假期: %s(星期%s) - %s(星期%s) 共%d天\n", + h.Start.Format("2006年01月02日"), xq[h.Start.Weekday()], + h.End.Format("2006年01月02日"), xq[h.End.Weekday()], h.Total) + } + if len(h.Instead) > 0 { + fmt.Print("调休: ") + for idx, v := range h.Instead { + fmt.Printf("%s(星期%s)", v.Format("01月02日"), xq[v.Weekday()]) + if idx != len(h.Instead)-1 { + fmt.Print("、") + } + } + fmt.Println(" 上班") + return + } + fmt.Println("不调休") +} + +func target3Day1(date time.Time) Holiday { + switch date.Weekday() { + case 0: + return Holiday{ + Core: date, + Start: date.Add(-24 * time.Hour), + End: date.Add(24 * time.Hour), + Total: 3, + LegalDays: 1, + } + case 1: + return Holiday{ + Core: date, + Start: date.Add(-48 * time.Hour), + End: date, + Total: 3, + LegalDays: 1, + } + case 5, 6: + return Holiday{ + Core: date, + Start: date, + End: date.Add(48 * time.Hour), + Total: 3, + LegalDays: 1, + } + case 3: + return Holiday{ + Core: date, + Start: date, + End: date, + Total: 1, + LegalDays: 1, + } + case 2: + return Holiday{ + Core: date, + Start: date.Add(-48 * time.Hour), + End: date, + Total: 3, + Instead: []time.Time{date.Add(-72 * time.Hour)}, + LegalDays: 1, + } + case 4: + return Holiday{ + Core: date, + Start: date, + End: date.Add(48 * time.Hour), + Total: 3, + Instead: []time.Time{date.Add(72 * time.Hour)}, + LegalDays: 1, + } + } + return Holiday{} +} + +func target5Day1(date time.Time) Holiday { + switch date.Weekday() { + case 1: + return Holiday{ + Start: date.Add(time.Hour * -48), + End: date.Add(time.Hour * 48), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 8), date.Add(time.Hour * 24 * 5)}, + Name: "", + LegalDays: 1, + } + case 2: + return Holiday{ + Start: date, + End: date.Add(time.Hour * -24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 2), date.Add(time.Hour * 24 * 5)}, + Name: "", + LegalDays: 1, + } + case 3: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 3), date.Add(time.Hour * 24 * 10)}, + Name: "", + LegalDays: 1, + } + case 4: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 4), date.Add(time.Hour * 24 * 9)}, + Name: "", + LegalDays: 1, + } + case 5: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 5), date.Add(time.Hour * 24 * 8)}, + Name: "", + LegalDays: 1, + } + case 6: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 6), date.Add(time.Hour * 24 * 7)}, + Name: "", + LegalDays: 1, + } + case 0: + return Holiday{ + Start: date.Add(time.Hour * -24), + End: date.Add(time.Hour * 24 * 3), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 7), date.Add(time.Hour * 24 * 6)}, + Name: "", + LegalDays: 1, + } + } + return Holiday{} +} + +func target5Day2(date time.Time) Holiday { + switch date.Weekday() { + case 1: + return Holiday{ + Start: date.Add(time.Hour * -48), + End: date.Add(time.Hour * 48), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * 24 * 5)}, + Name: "", + LegalDays: 2, + } + case 2: + return Holiday{ + Start: date, + End: date.Add(time.Hour * -24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 2)}, + Name: "", + LegalDays: 2, + } + case 3: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 3)}, + Name: "", + LegalDays: 2, + } + case 4: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * -24 * 4)}, + Name: "", + LegalDays: 2, + } + case 5: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * 24 * 8)}, + Name: "", + LegalDays: 2, + } + case 6: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 24 * 4), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * 24 * 7)}, + Name: "", + LegalDays: 2, + } + case 0: + return Holiday{ + Start: date.Add(time.Hour * -24), + End: date.Add(time.Hour * 24 * 3), + Core: date, + Total: 5, + Instead: []time.Time{date.Add(time.Hour * 24 * 6)}, + Name: "", + LegalDays: 2, + } + } + return Holiday{} +} + +func target7Day3(date time.Time) Holiday { + switch date.Weekday() { + case 1: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -2), date.Add(time.Hour * 24 * -1)}, + Name: "", + LegalDays: 3, + } + case 2: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -2), date.Add(time.Hour * 24 * 11)}, + Name: "", + LegalDays: 3, + } + case 3: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -3), date.Add(time.Hour * 24 * 10)}, + Name: "", + LegalDays: 3, + } + case 4: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -4), date.Add(time.Hour * 24 * 9)}, + Name: "", + LegalDays: 3, + } + case 5: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -5), date.Add(time.Hour * 24 * 8)}, + Name: "", + LegalDays: 3, + } + case 6: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * 7), date.Add(time.Hour * 24 * 8)}, + Name: "", + LegalDays: 3, + } + case 0: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 6 * 24), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(time.Hour * 24 * -1), date.Add(time.Hour * 24 * 7)}, + Name: "", + LegalDays: 3, + } + } + return Holiday{} +} + +func target8Day4(date time.Time) Holiday { + switch date.Weekday() { + case 1: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -2), date.Add(time.Hour * 24 * -1)}, + Name: "", + LegalDays: 4, + } + case 2: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -2), date.Add(time.Hour * 24 * 11)}, + Name: "", + LegalDays: 4, + } + case 3: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -3), date.Add(time.Hour * 24 * 10)}, + Name: "", + LegalDays: 4, + } + case 4: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -4), date.Add(time.Hour * 24 * 9)}, + Name: "", + LegalDays: 4, + } + case 5: + if date.Year() >= 2025 { + return Holiday{ + Start: date, + End: date.Add(time.Hour * 8 * 24), + Core: date, + Total: 9, + Instead: []time.Time{date.Add(time.Hour * 24 * -5), date.Add(time.Hour * 24 * 9)}, + Name: "", + LegalDays: 4, + } + } + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * 8), date.Add(time.Hour * 24 * 9)}, + Name: "", + LegalDays: 4, + } + case 6: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -6), date.Add(time.Hour * 24 * 8)}, + Name: "", + LegalDays: 2, + } + case 0: + return Holiday{ + Start: date, + End: date.Add(time.Hour * 7 * 24), + Core: date, + Total: 8, + Instead: []time.Time{date.Add(time.Hour * 24 * -1)}, + Name: "", + LegalDays: 2, + } + } + return Holiday{} +} + +// 元旦 +func YuanDan(year int) Holiday { + name := "元旦" + date := time.Date(year, 1, 1, 0, 0, 0, 0, time.Local) + if year > 2007 || year == 2005 { + d := target3Day1(date) + d.Name = name + return d + } + switch year { + case 2007: + return Holiday{ + Start: date, + End: date.Add(3 * 24 * time.Hour), + Core: date, + Total: 3, + Instead: []time.Time{date.Add(-24 * time.Hour), date.Add(-2 * 24 * time.Hour)}, + Name: name, + LegalDays: 1, + } + case 2006: + return Holiday{ + Start: date, + End: date.Add(3 * 24 * time.Hour), + Core: date, + Total: 3, + Instead: []time.Time{date.Add(-24 * time.Hour)}, + Name: name, + LegalDays: 1, + } + case 2004, 2003: + return Holiday{ + Start: date, + End: date, + Core: date, + Total: 1, + Instead: nil, + Name: name, + LegalDays: 1, + } + case 2002: + return Holiday{ + Start: date, + End: date.Add(3 * 24 * time.Hour), + Core: date, + Total: 3, + Instead: []time.Time{date.Add(-3 * 24 * time.Hour), date.Add(-2 * 24 * time.Hour)}, + Name: name, + LegalDays: 1, + } + } + return Holiday{Name: name} +} + +// 春节 +func ChunJie(year int) Holiday { + name := "春节" + chineseNewYear := calendar.RapidLunarToSolar(year, 1, 1, false) + chuxi := chineseNewYear.AddDate(0, 0, -1) + if year <= 2007 || year == 2014 { + d := target7Day3(chineseNewYear) + d.Name = name + return d + } + if year >= 2008 && year < 2024 { + d := target7Day3(chuxi) + d.Name = name + if year == 2020 { + d.Comment = "因新冠疫情防控,2020年春节延长至2月2日" + } + return d + } + if year == 2024 { + d := target8Day4(chineseNewYear) + d.LegalDays = 3 + d.Name = name + return d + } + d := target8Day4(chuxi) + d.Name = name + return d +} + +func QingMing(year int) Holiday { + name := "清明节" + if year < 2008 { + return Holiday{Name: name} + } + qingming := calendar.JieQi(year, calendar.JQ_清明) + d := target3Day1(qingming) + d.Name = name + return d +} + +func LaoDongJie(year int) Holiday { + name := "劳动节" + date := time.Date(year, 5, 1, 0, 0, 0, 0, time.Local) + if year < 2008 { + d := target7Day3(date) + d.Name = name + return d + } + if year == 2019 { + return Holiday{ + Start: date, + End: date.Add(4 * 24 * time.Hour), + Core: date, + Total: 4, + Instead: []time.Time{date.Add(-24 * 3 * time.Hour), date.Add(24 * time.Hour * 5)}, + Name: name, + LegalDays: 1, + Comment: "", + } + } + if year >= 2008 && year < 2020 { + d := target3Day1(date) + d.Name = name + return d + } + if year >= 2020 && year < 2025 { + d := target5Day1(date) + d.Name = name + return d + } + d := target5Day2(date) + d.Name = name + return d +} + +func DuanWu(year int) Holiday { + name := "端午节" + if year < 2008 { + return Holiday{Name: name} + } + date := calendar.RapidLunarToSolar(year, 5, 5, false) + d := target3Day1(date) + d.Name = name + return d +} + +func ZhongQiu(year int) Holiday { + name := "中秋节" + if year < 2008 { + return Holiday{Name: name} + } + date := calendar.RapidLunarToSolar(year, 8, 15, false) + if date.Month() == 9 && date.Day() >= 28 { + d := target8Day4(date) + d.Name = "国庆中秋连假" + return d + } else if date.Month() == 10 { + d := target8Day4(time.Date(year, 10, 1, 0, 0, 0, 0, time.Local)) + d.Name = "国庆中秋连假" + return d + } + d := target3Day1(date) + d.Name = name + if date.Month() == 9 && date.Day() <= 20 { + return d + } + if date.Weekday() == 3 { + d.Instead = []time.Time{date.Add(-24 * 3 * time.Hour), date.Add(24 * 3 * time.Hour)} + d.End = date.Add(2 * 24 * time.Hour) + d.Total = 3 + } + gq := target7Day3(time.Date(year, 10, 1, 0, 0, 0, 0, time.Local)) + for _, v := range gq.Instead { + if v.Before(d.End) || v.Equal(d.End) { + if v.Equal(date) { + d.Total = d.Total - 1 + d.End = d.End.Add(-24 * time.Hour) + } else { + if v.Equal(d.Start) { + d.Total = d.Total - 1 + d.Start = d.Start.Add(24 * time.Hour) + } else if v.Equal(d.End) { + d.Total = d.Total - 1 + d.End = d.End.Add(-24 * time.Hour) + } + } + } + } + return d +} + +func GuoQing(year int) Holiday { + name := "国庆节" + date := time.Date(year, 10, 1, 0, 0, 0, 0, time.Local) + zq := calendar.RapidLunarToSolar(year, 8, 15, false) + if year == 2008 { + return Holiday{ + Start: date.Add(-24 * 2 * time.Hour), + End: date.Add(4 * 24 * time.Hour), + Core: date, + Total: 7, + Instead: []time.Time{date.Add(-24 * 4 * time.Hour), date.Add(24 * -3 * time.Hour)}, + Name: name, + LegalDays: 3, + } + } + if year < 2008 || (zq.Month() == 9 && zq.Day() <= 20) { + d := target7Day3(date) + d.Name = name + return d + } + + if zq.Month() == 9 && zq.Day() >= 28 { + d := target8Day4(zq) + d.Name = "国庆中秋连假" + return d + } else if zq.Month() == 10 { + d := target8Day4(date) + d.Name = "国庆中秋连假" + return d + } + zqd := target3Day1(zq) + if date.Weekday() == 3 { + zqd.Instead = []time.Time{date.Add(-24 * 3 * time.Hour), date.Add(24 * 3 * time.Hour)} + zqd.End = date.Add(2 * 24 * time.Hour) + zqd.Total = 3 + } + d := target7Day3(date) + d.Name = name + for k, v := range d.Instead { + if v.Before(zqd.End) || v.Equal(zqd.End) { + if v.Equal(zq) { + d.Instead = append(d.Instead[:k], d.Instead[k+1:]...) + } + } + } + return d +} + +func ChineseHoliday(year int) []Holiday { + d := []Holiday{ + YuanDan(year), + ChunJie(year), + QingMing(year), + LaoDongJie(year), + DuanWu(year), + ZhongQiu(year), + GuoQing(year), + } + if d[len(d)-1].Name == "国庆中秋连假" { + return d[:len(d)-1] + } + return d +} diff --git a/astro/city.json b/astro/city.json new file mode 100644 index 0000000..1b024aa --- /dev/null +++ b/astro/city.json @@ -0,0 +1,2024 @@ +[ + { + "code": 340800, + "city_name": "安徽省安庆市", + "lat": 30.537898, + "lon": 117.058739 + }, + { + "code": 340300, + "city_name": "安徽省蚌埠市", + "lat": 32.929499, + "lon": 117.35708 + }, + { + "code": 341400, + "city_name": "安徽省巢湖市", + "lat": 31.608733, + "lon": 117.88049 + }, + { + "code": 341700, + "city_name": "安徽省池州市", + "lat": 30.660019, + "lon": 117.494477 + }, + { + "code": 341100, + "city_name": "安徽省滁州市", + "lat": 32.317351, + "lon": 118.32457 + }, + { + "code": 341200, + "city_name": "安徽省阜阳市", + "lat": 32.901211, + "lon": 115.820932 + }, + { + "code": 340100, + "city_name": "安徽省合肥市", + "lat": 31.866942, + "lon": 117.282699 + }, + { + "code": 340600, + "city_name": "安徽省淮北市", + "lat": 33.960023, + "lon": 116.791447 + }, + { + "code": 340400, + "city_name": "安徽省淮南市", + "lat": 32.642812, + "lon": 117.018639 + }, + { + "code": 341000, + "city_name": "安徽省黄山市", + "lat": 29.734435, + "lon": 118.29357 + }, + { + "code": 341500, + "city_name": "安徽省六安市", + "lat": 31.755558, + "lon": 116.505253 + }, + { + "code": 340500, + "city_name": "安徽省马鞍山市", + "lat": 31.688528, + "lon": 118.515882 + }, + { + "code": 341300, + "city_name": "安徽省宿州市", + "lat": 33.636772, + "lon": 116.988692 + }, + { + "code": 340700, + "city_name": "安徽省铜陵市", + "lat": 30.94093, + "lon": 117.819429 + }, + { + "code": 340200, + "city_name": "安徽省芜湖市", + "lat": 31.36602, + "lon": 118.384108 + }, + { + "code": 341800, + "city_name": "安徽省宣城市", + "lat": 30.951642, + "lon": 118.752096 + }, + { + "code": 341600, + "city_name": "安徽省亳州市", + "lat": 33.871211, + "lon": 115.787928 + }, + { + "code": 110100, + "city_name": "北京市", + "lat": 39.929986, + "lon": 116.395645 + }, + { + "code": 500100, + "city_name": "重庆市", + "lat": 29.544606, + "lon": 106.530635 + }, + { + "code": 350100, + "city_name": "福建省福州市", + "lat": 26.047125, + "lon": 119.330221 + }, + { + "code": 350800, + "city_name": "福建省龙岩市", + "lat": 25.078685, + "lon": 117.017997 + }, + { + "code": 350700, + "city_name": "福建省南平市", + "lat": 26.643626, + "lon": 118.181883 + }, + { + "code": 350900, + "city_name": "福建省宁德市", + "lat": 26.656527, + "lon": 119.542082 + }, + { + "code": 350300, + "city_name": "福建省莆田市", + "lat": 25.44845, + "lon": 119.077731 + }, + { + "code": 350500, + "city_name": "福建省泉州市", + "lat": 24.901652, + "lon": 118.600362 + }, + { + "code": 350400, + "city_name": "福建省三明市", + "lat": 26.270835, + "lon": 117.642194 + }, + { + "code": 350200, + "city_name": "福建省厦门市", + "lat": 24.489231, + "lon": 118.103886 + }, + { + "code": 350600, + "city_name": "福建省漳州市", + "lat": 24.517065, + "lon": 117.676205 + }, + { + "code": 620400, + "city_name": "甘肃省白银市", + "lat": 36.546682, + "lon": 104.171241 + }, + { + "code": 621100, + "city_name": "甘肃省定西市", + "lat": 35.586056, + "lon": 104.626638 + }, + { + "code": 623000, + "city_name": "甘肃省甘南藏族自治州", + "lat": 34.992211, + "lon": 102.917442 + }, + { + "code": 620200, + "city_name": "甘肃省嘉峪关市", + "lat": 39.802397, + "lon": 98.281635 + }, + { + "code": 620300, + "city_name": "甘肃省金昌市", + "lat": 38.516072, + "lon": 102.208126 + }, + { + "code": 620900, + "city_name": "甘肃省酒泉市", + "lat": 39.741474, + "lon": 98.508415 + }, + { + "code": 620100, + "city_name": "甘肃省兰州市", + "lat": 36.064226, + "lon": 103.823305 + }, + { + "code": 622900, + "city_name": "甘肃省临夏回族自治州", + "lat": 35.598514, + "lon": 103.215249 + }, + { + "code": 621200, + "city_name": "甘肃省陇南市", + "lat": 33.39448, + "lon": 104.934573 + }, + { + "code": 620800, + "city_name": "甘肃省平凉市", + "lat": 35.55011, + "lon": 106.688911 + }, + { + "code": 621000, + "city_name": "甘肃省庆阳市", + "lat": 35.726801, + "lon": 107.644227 + }, + { + "code": 620500, + "city_name": "甘肃省天水市", + "lat": 34.584319, + "lon": 105.736932 + }, + { + "code": 620600, + "city_name": "甘肃省武威市", + "lat": 37.933172, + "lon": 102.640147 + }, + { + "code": 620700, + "city_name": "甘肃省张掖市", + "lat": 38.93932, + "lon": 100.459892 + }, + { + "code": 445100, + "city_name": "广东省潮州市", + "lat": 23.661812, + "lon": 116.630076 + }, + { + "code": 441900, + "city_name": "广东省东莞市", + "lat": 23.043024, + "lon": 113.763434 + }, + { + "code": 440600, + "city_name": "广东省佛山市", + "lat": 23.035095, + "lon": 113.134026 + }, + { + "code": 440100, + "city_name": "广东省广州市", + "lat": 23.120049, + "lon": 113.30765 + }, + { + "code": 441600, + "city_name": "广东省河源市", + "lat": 23.757251, + "lon": 114.713721 + }, + { + "code": 441300, + "city_name": "广东省惠州市", + "lat": 23.11354, + "lon": 114.410658 + }, + { + "code": 440700, + "city_name": "广东省江门市", + "lat": 22.575117, + "lon": 113.078125 + }, + { + "code": 445200, + "city_name": "广东省揭阳市", + "lat": 23.547999, + "lon": 116.379501 + }, + { + "code": 440900, + "city_name": "广东省茂名市", + "lat": 21.668226, + "lon": 110.931245 + }, + { + "code": 441400, + "city_name": "广东省梅州市", + "lat": 24.304571, + "lon": 116.126403 + }, + { + "code": 441800, + "city_name": "广东省清远市", + "lat": 23.698469, + "lon": 113.040773 + }, + { + "code": 440500, + "city_name": "广东省汕头市", + "lat": 23.383908, + "lon": 116.72865 + }, + { + "code": 441500, + "city_name": "广东省汕尾市", + "lat": 22.778731, + "lon": 115.372924 + }, + { + "code": 440200, + "city_name": "广东省韶关市", + "lat": 24.80296, + "lon": 113.594461 + }, + { + "code": 440300, + "city_name": "广东省深圳市", + "lat": 22.546054, + "lon": 114.025974 + }, + { + "code": 441700, + "city_name": "广东省阳江市", + "lat": 21.871517, + "lon": 111.97701 + }, + { + "code": 445300, + "city_name": "广东省云浮市", + "lat": 22.937976, + "lon": 112.050946 + }, + { + "code": 440800, + "city_name": "广东省湛江市", + "lat": 21.257463, + "lon": 110.365067 + }, + { + "code": 441200, + "city_name": "广东省肇庆市", + "lat": 23.078663, + "lon": 112.479653 + }, + { + "code": 442000, + "city_name": "广东省中山市", + "lat": 22.545178, + "lon": 113.42206 + }, + { + "code": 440400, + "city_name": "广东省珠海市", + "lat": 22.256915, + "lon": 113.562447 + }, + { + "code": 451000, + "city_name": "广西百色市", + "lat": 23.901512, + "lon": 106.631821 + }, + { + "code": 450500, + "city_name": "广西北海市", + "lat": 21.472718, + "lon": 109.122628 + }, + { + "code": 451400, + "city_name": "广西崇左市", + "lat": 22.415455, + "lon": 107.357322 + }, + { + "code": 450600, + "city_name": "广西防城港市", + "lat": 21.617398, + "lon": 108.351791 + }, + { + "code": 450300, + "city_name": "广西桂林市", + "lat": 25.262901, + "lon": 110.26092 + }, + { + "code": 450800, + "city_name": "广西贵港市", + "lat": 23.103373, + "lon": 109.613708 + }, + { + "code": 451200, + "city_name": "广西河池市", + "lat": 24.699521, + "lon": 108.069948 + }, + { + "code": 451100, + "city_name": "广西贺州市", + "lat": 24.411054, + "lon": 111.552594 + }, + { + "code": 451300, + "city_name": "广西来宾市", + "lat": 23.741166, + "lon": 109.231817 + }, + { + "code": 450200, + "city_name": "广西柳州市", + "lat": 24.329053, + "lon": 109.422402 + }, + { + "code": 450100, + "city_name": "广西南宁市", + "lat": 22.806493, + "lon": 108.297234 + }, + { + "code": 450700, + "city_name": "广西钦州市", + "lat": 21.97335, + "lon": 108.638798 + }, + { + "code": 450400, + "city_name": "广西梧州市", + "lat": 23.485395, + "lon": 111.305472 + }, + { + "code": 450900, + "city_name": "广西玉林市", + "lat": 22.643974, + "lon": 110.151676 + }, + { + "code": 520400, + "city_name": "贵州省安顺市", + "lat": 26.228595, + "lon": 105.92827 + }, + { + "code": 522400, + "city_name": "贵州省毕节地区", + "lat": 27.302612, + "lon": 105.300492 + }, + { + "code": 520100, + "city_name": "贵州省贵阳市", + "lat": 26.629907, + "lon": 106.709177 + }, + { + "code": 520200, + "city_name": "贵州省六盘水市", + "lat": 26.591866, + "lon": 104.852087 + }, + { + "code": 522600, + "city_name": "贵州省黔东南苗族侗族自治州", + "lat": 26.583992, + "lon": 107.985353 + }, + { + "code": 522700, + "city_name": "贵州省黔南布依族苗族自治州", + "lat": 26.264536, + "lon": 107.523205 + }, + { + "code": 522300, + "city_name": "贵州省黔西南布依族苗族自治州", + "lat": 25.095148, + "lon": 104.900558 + }, + { + "code": 522200, + "city_name": "贵州省铜仁地区", + "lat": 27.726271, + "lon": 109.196161 + }, + { + "code": 520300, + "city_name": "贵州省遵义市", + "lat": 27.699961, + "lon": 106.93126 + }, + { + "code": 460100, + "city_name": "海南省海口市", + "lat": 20.022071, + "lon": 110.330802 + }, + { + "code": 460200, + "city_name": "海南省三亚市", + "lat": 18.257776, + "lon": 109.522771 + }, + { + "code": 130600, + "city_name": "河北省保定市", + "lat": 38.886565, + "lon": 115.49481 + }, + { + "code": 130900, + "city_name": "河北省沧州市", + "lat": 38.297615, + "lon": 116.863806 + }, + { + "code": 130800, + "city_name": "河北省承德市", + "lat": 40.992521, + "lon": 117.933822 + }, + { + "code": 130400, + "city_name": "河北省邯郸市", + "lat": 36.609308, + "lon": 114.482694 + }, + { + "code": 131100, + "city_name": "河北省衡水市", + "lat": 37.746929, + "lon": 115.686229 + }, + { + "code": 131000, + "city_name": "河北省廊坊市", + "lat": 39.518611, + "lon": 116.703602 + }, + { + "code": 130300, + "city_name": "河北省秦皇岛市", + "lat": 39.945462, + "lon": 119.604368 + }, + { + "code": 130100, + "city_name": "河北省石家庄市", + "lat": 38.048958, + "lon": 114.522082 + }, + { + "code": 130200, + "city_name": "河北省唐山市", + "lat": 39.650531, + "lon": 118.183451 + }, + { + "code": 130500, + "city_name": "河北省邢台市", + "lat": 37.069531, + "lon": 114.520487 + }, + { + "code": 130700, + "city_name": "河北省张家口市", + "lat": 40.811188, + "lon": 114.893782 + }, + { + "code": 410500, + "city_name": "河南省安阳市", + "lat": 36.110267, + "lon": 114.351807 + }, + { + "code": 410600, + "city_name": "河南省鹤壁市", + "lat": 35.755426, + "lon": 114.29777 + }, + { + "code": 410800, + "city_name": "河南省焦作市", + "lat": 35.234608, + "lon": 113.211836 + }, + { + "code": 410200, + "city_name": "河南省开封市", + "lat": 34.801854, + "lon": 114.351642 + }, + { + "code": 410300, + "city_name": "河南省洛阳市", + "lat": 34.657368, + "lon": 112.447525 + }, + { + "code": 411300, + "city_name": "河南省南阳市", + "lat": 33.01142, + "lon": 112.542842 + }, + { + "code": 410400, + "city_name": "河南省平顶山市", + "lat": 33.745301, + "lon": 113.300849 + }, + { + "code": 411200, + "city_name": "河南省三门峡市", + "lat": 34.78332, + "lon": 111.181262 + }, + { + "code": 411400, + "city_name": "河南省商丘市", + "lat": 34.438589, + "lon": 115.641886 + }, + { + "code": 410700, + "city_name": "河南省新乡市", + "lat": 35.307258, + "lon": 113.91269 + }, + { + "code": 411500, + "city_name": "河南省信阳市", + "lat": 32.128582, + "lon": 114.085491 + }, + { + "code": 411000, + "city_name": "河南省许昌市", + "lat": 34.02674, + "lon": 113.835312 + }, + { + "code": 410100, + "city_name": "河南省郑州市", + "lat": 34.75661, + "lon": 113.649644 + }, + { + "code": 411600, + "city_name": "河南省周口市", + "lat": 33.623741, + "lon": 114.654102 + }, + { + "code": 411700, + "city_name": "河南省驻马店市", + "lat": 32.983158, + "lon": 114.049154 + }, + { + "code": 411100, + "city_name": "河南省漯河市", + "lat": 33.576279, + "lon": 114.046061 + }, + { + "code": 410900, + "city_name": "河南省濮阳市", + "lat": 35.753298, + "lon": 115.026627 + }, + { + "code": 230600, + "city_name": "黑龙江省大庆市", + "lat": 46.596709, + "lon": 125.02184 + }, + { + "code": 232700, + "city_name": "黑龙江省大兴安岭地区", + "lat": 51.991789, + "lon": 124.196104 + }, + { + "code": 230100, + "city_name": "黑龙江省哈尔滨市", + "lat": 45.773225, + "lon": 126.657717 + }, + { + "code": 230400, + "city_name": "黑龙江省鹤岗市", + "lat": 47.338666, + "lon": 130.292472 + }, + { + "code": 231100, + "city_name": "黑龙江省黑河市", + "lat": 50.25069, + "lon": 127.50083 + }, + { + "code": 230300, + "city_name": "黑龙江省鸡西市", + "lat": 45.32154, + "lon": 130.941767 + }, + { + "code": 230800, + "city_name": "黑龙江省佳木斯市", + "lat": 46.81378, + "lon": 130.284735 + }, + { + "code": 231000, + "city_name": "黑龙江省牡丹江市", + "lat": 44.588521, + "lon": 129.608035 + }, + { + "code": 230900, + "city_name": "黑龙江省七台河市", + "lat": 45.775005, + "lon": 131.019048 + }, + { + "code": 230200, + "city_name": "黑龙江省齐齐哈尔市", + "lat": 47.3477, + "lon": 123.987289 + }, + { + "code": 230500, + "city_name": "黑龙江省双鸭山市", + "lat": 46.655102, + "lon": 131.171402 + }, + { + "code": 231200, + "city_name": "黑龙江省绥化市", + "lat": 46.646064, + "lon": 126.989095 + }, + { + "code": 230700, + "city_name": "黑龙江省伊春市", + "lat": 47.734685, + "lon": 128.910766 + }, + { + "code": 420700, + "city_name": "湖北省鄂州市", + "lat": 30.384439, + "lon": 114.895594 + }, + { + "code": 422800, + "city_name": "湖北省恩施土家族苗族自治州", + "lat": 30.285888, + "lon": 109.491923 + }, + { + "code": 421100, + "city_name": "湖北省黄冈市", + "lat": 30.446109, + "lon": 114.906618 + }, + { + "code": 420200, + "city_name": "湖北省黄石市", + "lat": 30.216127, + "lon": 115.050683 + }, + { + "code": 420800, + "city_name": "湖北省荆门市", + "lat": 31.042611, + "lon": 112.21733 + }, + { + "code": 421000, + "city_name": "湖北省荆州市", + "lat": 30.332591, + "lon": 112.241866 + }, + { + "code": 420300, + "city_name": "湖北省十堰市", + "lat": 32.636994, + "lon": 110.801229 + }, + { + "code": 421300, + "city_name": "湖北省随州市", + "lat": 31.717858, + "lon": 113.379358 + }, + { + "code": 420100, + "city_name": "湖北省武汉市", + "lat": 30.581084, + "lon": 114.3162 + }, + { + "code": 421200, + "city_name": "湖北省咸宁市", + "lat": 29.880657, + "lon": 114.300061 + }, + { + "code": 420600, + "city_name": "湖北省襄阳市", + "lat": 32.229169, + "lon": 112.250093 + }, + { + "code": 420900, + "city_name": "湖北省孝感市", + "lat": 30.927955, + "lon": 113.935734 + }, + { + "code": 420500, + "city_name": "湖北省宜昌市", + "lat": 30.732758, + "lon": 111.310981 + }, + { + "code": 430700, + "city_name": "湖南省常德市", + "lat": 29.012149, + "lon": 111.653718 + }, + { + "code": 430100, + "city_name": "湖南省长沙市", + "lat": 28.213478, + "lon": 112.979353 + }, + { + "code": 431000, + "city_name": "湖南省郴州市", + "lat": 25.782264, + "lon": 113.037704 + }, + { + "code": 430400, + "city_name": "湖南省衡阳市", + "lat": 26.898164, + "lon": 112.583819 + }, + { + "code": 431200, + "city_name": "湖南省怀化市", + "lat": 27.557483, + "lon": 109.986959 + }, + { + "code": 431300, + "city_name": "湖南省娄底市", + "lat": 27.741073, + "lon": 111.996396 + }, + { + "code": 430500, + "city_name": "湖南省邵阳市", + "lat": 27.236811, + "lon": 111.461525 + }, + { + "code": 430300, + "city_name": "湖南省湘潭市", + "lat": 27.835095, + "lon": 112.935556 + }, + { + "code": 433100, + "city_name": "湖南省湘西土家族苗族自治州", + "lat": 28.317951, + "lon": 109.745746 + }, + { + "code": 430900, + "city_name": "湖南省益阳市", + "lat": 28.588088, + "lon": 112.366547 + }, + { + "code": 431100, + "city_name": "湖南省永州市", + "lat": 26.435972, + "lon": 111.614648 + }, + { + "code": 430600, + "city_name": "湖南省岳阳市", + "lat": 29.378007, + "lon": 113.146196 + }, + { + "code": 430800, + "city_name": "湖南省张家界市", + "lat": 29.124889, + "lon": 110.48162 + }, + { + "code": 430200, + "city_name": "湖南省株洲市", + "lat": 27.827433, + "lon": 113.131695 + }, + { + "code": 220800, + "city_name": "吉林省白城市", + "lat": 45.621086, + "lon": 122.840777 + }, + { + "code": 220600, + "city_name": "吉林省白山市", + "lat": 41.945859, + "lon": 126.435798 + }, + { + "code": 220100, + "city_name": "吉林省长春市", + "lat": 43.898338, + "lon": 125.313642 + }, + { + "code": 220200, + "city_name": "吉林省吉林市", + "lat": 43.871988, + "lon": 126.564544 + }, + { + "code": 220400, + "city_name": "吉林省辽源市", + "lat": 42.923303, + "lon": 125.133686 + }, + { + "code": 220300, + "city_name": "吉林省四平市", + "lat": 43.175525, + "lon": 124.391382 + }, + { + "code": 220700, + "city_name": "吉林省松原市", + "lat": 45.136049, + "lon": 124.832995 + }, + { + "code": 220500, + "city_name": "吉林省通化市", + "lat": 41.736397, + "lon": 125.94265 + }, + { + "code": 222400, + "city_name": "吉林省延边朝鲜族自治州", + "lat": 42.896414, + "lon": 129.485902 + }, + { + "code": 320400, + "city_name": "江苏省常州市", + "lat": 31.771397, + "lon": 119.981861 + }, + { + "code": 320800, + "city_name": "江苏省淮安市", + "lat": 33.606513, + "lon": 119.030186 + }, + { + "code": 320700, + "city_name": "江苏省连云港市", + "lat": 34.601549, + "lon": 119.173872 + }, + { + "code": 320100, + "city_name": "江苏省南京市", + "lat": 32.057236, + "lon": 118.778074 + }, + { + "code": 320600, + "city_name": "江苏省南通市", + "lat": 32.014665, + "lon": 120.873801 + }, + { + "code": 320500, + "city_name": "江苏省苏州市", + "lat": 31.317987, + "lon": 120.619907 + }, + { + "code": 321300, + "city_name": "江苏省宿迁市", + "lat": 33.95205, + "lon": 118.296893 + }, + { + "code": 321200, + "city_name": "江苏省泰州市", + "lat": 32.476053, + "lon": 119.919606 + }, + { + "code": 320200, + "city_name": "江苏省无锡市", + "lat": 31.570037, + "lon": 120.305456 + }, + { + "code": 320300, + "city_name": "江苏省徐州市", + "lat": 34.271553, + "lon": 117.188107 + }, + { + "code": 320900, + "city_name": "江苏省盐城市", + "lat": 33.379862, + "lon": 120.148872 + }, + { + "code": 321000, + "city_name": "江苏省扬州市", + "lat": 32.408505, + "lon": 119.427778 + }, + { + "code": 321100, + "city_name": "江苏省镇江市", + "lat": 32.204409, + "lon": 119.455835 + }, + { + "code": 361000, + "city_name": "江西省抚州市", + "lat": 27.954545, + "lon": 116.360919 + }, + { + "code": 360700, + "city_name": "江西省赣州市", + "lat": 25.845296, + "lon": 114.935909 + }, + { + "code": 360800, + "city_name": "江西省吉安市", + "lat": 27.113848, + "lon": 114.992039 + }, + { + "code": 360200, + "city_name": "江西省景德镇市", + "lat": 29.303563, + "lon": 117.186523 + }, + { + "code": 360400, + "city_name": "江西省九江市", + "lat": 29.71964, + "lon": 115.999848 + }, + { + "code": 360100, + "city_name": "江西省南昌市", + "lat": 28.689578, + "lon": 115.893528 + }, + { + "code": 360300, + "city_name": "江西省萍乡市", + "lat": 27.639544, + "lon": 113.859917 + }, + { + "code": 361100, + "city_name": "江西省上饶市", + "lat": 28.457623, + "lon": 117.955464 + }, + { + "code": 360500, + "city_name": "江西省新余市", + "lat": 27.822322, + "lon": 114.947117 + }, + { + "code": 360900, + "city_name": "江西省宜春市", + "lat": 27.81113, + "lon": 114.400039 + }, + { + "code": 360600, + "city_name": "江西省鹰潭市", + "lat": 28.24131, + "lon": 117.03545 + }, + { + "code": 210300, + "city_name": "辽宁省鞍山市", + "lat": 41.118744, + "lon": 123.007763 + }, + { + "code": 210500, + "city_name": "辽宁省本溪市", + "lat": 41.325838, + "lon": 123.778062 + }, + { + "code": 211300, + "city_name": "辽宁省朝阳市", + "lat": 41.571828, + "lon": 120.446163 + }, + { + "code": 210200, + "city_name": "辽宁省大连市", + "lat": 38.94871, + "lon": 121.593478 + }, + { + "code": 210600, + "city_name": "辽宁省丹东市", + "lat": 40.129023, + "lon": 124.338543 + }, + { + "code": 210400, + "city_name": "辽宁省抚顺市", + "lat": 41.877304, + "lon": 123.92982 + }, + { + "code": 210900, + "city_name": "辽宁省阜新市", + "lat": 42.01925, + "lon": 121.660822 + }, + { + "code": 211400, + "city_name": "辽宁省葫芦岛市", + "lat": 40.74303, + "lon": 120.860758 + }, + { + "code": 210700, + "city_name": "辽宁省锦州市", + "lat": 41.130879, + "lon": 121.147749 + }, + { + "code": 211000, + "city_name": "辽宁省辽阳市", + "lat": 41.273339, + "lon": 123.172451 + }, + { + "code": 211100, + "city_name": "辽宁省盘锦市", + "lat": 41.141248, + "lon": 122.073228 + }, + { + "code": 210100, + "city_name": "辽宁省沈阳市", + "lat": 41.808645, + "lon": 123.432791 + }, + { + "code": 211200, + "city_name": "辽宁省铁岭市", + "lat": 42.299757, + "lon": 123.85485 + }, + { + "code": 210800, + "city_name": "辽宁省营口市", + "lat": 40.668651, + "lon": 122.233391 + }, + { + "code": 152900, + "city_name": "内蒙古阿拉善盟", + "lat": 43.468238, + "lon": 114.415868 + }, + { + "code": 150800, + "city_name": "内蒙古巴彦淖尔市", + "lat": 40.76918, + "lon": 107.423807 + }, + { + "code": 150200, + "city_name": "内蒙古包头市", + "lat": 40.647119, + "lon": 109.846239 + }, + { + "code": 150400, + "city_name": "内蒙古赤峰市", + "lat": 42.297112, + "lon": 118.930761 + }, + { + "code": 150600, + "city_name": "内蒙古鄂尔多斯市", + "lat": 39.81649, + "lon": 109.993706 + }, + { + "code": 150100, + "city_name": "内蒙古呼和浩特市", + "lat": 40.828319, + "lon": 111.660351 + }, + { + "code": 150700, + "city_name": "内蒙古呼伦贝尔市", + "lat": 49.201636, + "lon": 119.760822 + }, + { + "code": 150500, + "city_name": "内蒙古通辽市", + "lat": 43.633756, + "lon": 122.260363 + }, + { + "code": 150300, + "city_name": "内蒙古乌海市", + "lat": 39.683177, + "lon": 106.831999 + }, + { + "code": 150900, + "city_name": "内蒙古乌兰察布市", + "lat": 41.022363, + "lon": 113.112846 + }, + { + "code": 152500, + "city_name": "内蒙古锡林郭勒盟", + "lat": 43.468238, + "lon": 114.415868 + }, + { + "code": 152200, + "city_name": "内蒙古兴安盟", + "lat": 43.468238, + "lon": 114.415868 + }, + { + "code": 640400, + "city_name": "宁夏固原市", + "lat": 36.021523, + "lon": 106.285268 + }, + { + "code": 640200, + "city_name": "宁夏石嘴山市", + "lat": 39.020223, + "lon": 106.379337 + }, + { + "code": 640300, + "city_name": "宁夏吴忠市", + "lat": 37.993561, + "lon": 106.208254 + }, + { + "code": 640100, + "city_name": "宁夏银川市", + "lat": 38.502621, + "lon": 106.206479 + }, + { + "code": 640500, + "city_name": "宁夏中卫市", + "lat": 37.521124, + "lon": 105.196754 + }, + { + "code": 632600, + "city_name": "青海省果洛藏族自治州", + "lat": 34.480485, + "lon": 100.223723 + }, + { + "code": 632200, + "city_name": "青海省海北藏族自治州", + "lat": 36.960654, + "lon": 100.879802 + }, + { + "code": 632100, + "city_name": "青海省海东地区", + "lat": 36.51761, + "lon": 102.085207 + }, + { + "code": 632500, + "city_name": "青海省海南藏族自治州", + "lat": 36.284364, + "lon": 100.624066 + }, + { + "code": 632800, + "city_name": "青海省海西蒙古族藏族自治州", + "lat": 37.373799, + "lon": 97.342625 + }, + { + "code": 632300, + "city_name": "青海省黄南藏族自治州", + "lat": 35.522852, + "lon": 102.0076 + }, + { + "code": 630100, + "city_name": "青海省西宁市", + "lat": 36.640739, + "lon": 101.767921 + }, + { + "code": 632700, + "city_name": "青海省玉树藏族自治州", + "lat": 33.00624, + "lon": 97.013316 + }, + { + "code": 371600, + "city_name": "山东省滨州市", + "lat": 37.405314, + "lon": 117.968292 + }, + { + "code": 371400, + "city_name": "山东省德州市", + "lat": 37.460826, + "lon": 116.328161 + }, + { + "code": 370500, + "city_name": "山东省东营市", + "lat": 37.487121, + "lon": 118.583926 + }, + { + "code": 371700, + "city_name": "山东省菏泽市", + "lat": 35.26244, + "lon": 115.46336 + }, + { + "code": 370100, + "city_name": "山东省济南市", + "lat": 36.682785, + "lon": 117.024967 + }, + { + "code": 370800, + "city_name": "山东省济宁市", + "lat": 35.402122, + "lon": 116.600798 + }, + { + "code": 371200, + "city_name": "山东省莱芜市", + "lat": 36.233654, + "lon": 117.684667 + }, + { + "code": 371500, + "city_name": "山东省聊城市", + "lat": 36.455829, + "lon": 115.986869 + }, + { + "code": 371300, + "city_name": "山东省临沂市", + "lat": 35.072409, + "lon": 118.340768 + }, + { + "code": 370200, + "city_name": "山东省青岛市", + "lat": 36.105215, + "lon": 120.384428 + }, + { + "code": 371100, + "city_name": "山东省日照市", + "lat": 35.420225, + "lon": 119.50718 + }, + { + "code": 370900, + "city_name": "山东省泰安市", + "lat": 36.188078, + "lon": 117.089415 + }, + { + "code": 371000, + "city_name": "山东省威海市", + "lat": 37.528787, + "lon": 122.093958 + }, + { + "code": 370700, + "city_name": "山东省潍坊市", + "lat": 36.716115, + "lon": 119.142634 + }, + { + "code": 370600, + "city_name": "山东省烟台市", + "lat": 37.536562, + "lon": 121.309555 + }, + { + "code": 370400, + "city_name": "山东省枣庄市", + "lat": 34.807883, + "lon": 117.279305 + }, + { + "code": 370300, + "city_name": "山东省淄博市", + "lat": 36.804685, + "lon": 118.059134 + }, + { + "code": 140400, + "city_name": "山西省长治市", + "lat": 36.201664, + "lon": 113.120292 + }, + { + "code": 140200, + "city_name": "山西省大同市", + "lat": 40.113744, + "lon": 113.290509 + }, + { + "code": 140500, + "city_name": "山西省晋城市", + "lat": 35.499834, + "lon": 112.867333 + }, + { + "code": 140700, + "city_name": "山西省晋中市", + "lat": 37.693362, + "lon": 112.738514 + }, + { + "code": 141000, + "city_name": "山西省临汾市", + "lat": 36.099745, + "lon": 111.538788 + }, + { + "code": 141100, + "city_name": "山西省吕梁市", + "lat": 37.527316, + "lon": 111.143157 + }, + { + "code": 140600, + "city_name": "山西省朔州市", + "lat": 39.337672, + "lon": 112.479928 + }, + { + "code": 140100, + "city_name": "山西省太原市", + "lat": 37.890277, + "lon": 112.550864 + }, + { + "code": 140900, + "city_name": "山西省忻州市", + "lat": 38.461031, + "lon": 112.727939 + }, + { + "code": 140300, + "city_name": "山西省阳泉市", + "lat": 37.869529, + "lon": 113.569238 + }, + { + "code": 140800, + "city_name": "山西省运城市", + "lat": 35.038859, + "lon": 111.006854 + }, + { + "code": 610900, + "city_name": "陕西省安康市", + "lat": 32.70437, + "lon": 109.038045 + }, + { + "code": 610300, + "city_name": "陕西省宝鸡市", + "lat": 34.364081, + "lon": 107.170645 + }, + { + "code": 610700, + "city_name": "陕西省汉中市", + "lat": 33.081569, + "lon": 107.045478 + }, + { + "code": 611000, + "city_name": "陕西省商洛市", + "lat": 33.873907, + "lon": 109.934208 + }, + { + "code": 610200, + "city_name": "陕西省铜川市", + "lat": 34.908368, + "lon": 108.968067 + }, + { + "code": 610500, + "city_name": "陕西省渭南市", + "lat": 34.502358, + "lon": 109.483933 + }, + { + "code": 610100, + "city_name": "陕西省西安市", + "lat": 34.2778, + "lon": 108.953098 + }, + { + "code": 610400, + "city_name": "陕西省咸阳市", + "lat": 34.345373, + "lon": 108.707509 + }, + { + "code": 610600, + "city_name": "陕西省延安市", + "lat": 36.60332, + "lon": 109.50051 + }, + { + "code": 610800, + "city_name": "陕西省榆林市", + "lat": 38.279439, + "lon": 109.745926 + }, + { + "code": 310100, + "city_name": "上海市", + "lat": 31.249162, + "lon": 121.487899 + }, + { + "code": 513200, + "city_name": "四川省阿坝藏族羌族自治州", + "lat": 31.905763, + "lon": 102.228565 + }, + { + "code": 511900, + "city_name": "四川省巴中市", + "lat": 31.869189, + "lon": 106.757916 + }, + { + "code": 510100, + "city_name": "四川省成都市", + "lat": 30.679943, + "lon": 104.067923 + }, + { + "code": 511700, + "city_name": "四川省达州市", + "lat": 31.214199, + "lon": 107.494973 + }, + { + "code": 510600, + "city_name": "四川省德阳市", + "lat": 31.13114, + "lon": 104.402398 + }, + { + "code": 513300, + "city_name": "四川省甘孜藏族自治州", + "lat": 30.055144, + "lon": 101.969232 + }, + { + "code": 511600, + "city_name": "四川省广安市", + "lat": 30.463984, + "lon": 106.63572 + }, + { + "code": 510800, + "city_name": "四川省广元市", + "lat": 32.44104, + "lon": 105.819687 + }, + { + "code": 511100, + "city_name": "四川省乐山市", + "lat": 29.600958, + "lon": 103.760824 + }, + { + "code": 513400, + "city_name": "四川省凉山彝族自治州", + "lat": 27.892393, + "lon": 102.259591 + }, + { + "code": 511400, + "city_name": "四川省眉山市", + "lat": 30.061115, + "lon": 103.84143 + }, + { + "code": 510700, + "city_name": "四川省绵阳市", + "lat": 31.504701, + "lon": 104.705519 + }, + { + "code": 511300, + "city_name": "四川省南充市", + "lat": 30.800965, + "lon": 106.105554 + }, + { + "code": 511000, + "city_name": "四川省内江市", + "lat": 29.599462, + "lon": 105.073056 + }, + { + "code": 510400, + "city_name": "四川省攀枝花市", + "lat": 26.587571, + "lon": 101.722423 + }, + { + "code": 510900, + "city_name": "四川省遂宁市", + "lat": 30.557491, + "lon": 105.564888 + }, + { + "code": 511800, + "city_name": "四川省雅安市", + "lat": 29.999716, + "lon": 103.009356 + }, + { + "code": 511500, + "city_name": "四川省宜宾市", + "lat": 28.769675, + "lon": 104.633019 + }, + { + "code": 512000, + "city_name": "四川省资阳市", + "lat": 30.132191, + "lon": 104.63593 + }, + { + "code": 510300, + "city_name": "四川省自贡市", + "lat": 29.359157, + "lon": 104.776071 + }, + { + "code": 510500, + "city_name": "四川省泸州市", + "lat": 28.89593, + "lon": 105.44397 + }, + { + "code": 120100, + "city_name": "天津市", + "lat": 39.14393, + "lon": 117.210813 + }, + { + "code": 542500, + "city_name": "西藏阿里地区", + "lat": 30.404557, + "lon": 81.107669 + }, + { + "code": 542100, + "city_name": "西藏昌都地区", + "lat": 31.140576, + "lon": 97.185582 + }, + { + "code": 540100, + "city_name": "西藏拉萨市", + "lat": 29.662557, + "lon": 91.111891 + }, + { + "code": 542600, + "city_name": "西藏林芝地区", + "lat": 29.666941, + "lon": 94.349985 + }, + { + "code": 542400, + "city_name": "西藏那曲地区", + "lat": 31.48068, + "lon": 92.067018 + }, + { + "code": 542300, + "city_name": "西藏日喀则地区", + "lat": 29.269023, + "lon": 88.891486 + }, + { + "code": 542200, + "city_name": "西藏山南地区", + "lat": 29.229027, + "lon": 91.750644 + }, + { + "code": 652900, + "city_name": "新疆阿克苏地区", + "lat": 41.171731, + "lon": 80.269846 + }, + { + "code": 654300, + "city_name": "新疆阿勒泰地区", + "lat": 47.839744, + "lon": 88.137915 + }, + { + "code": 652800, + "city_name": "新疆巴音郭楞蒙古自治州", + "lat": 41.771362, + "lon": 86.121688 + }, + { + "code": 652700, + "city_name": "新疆博尔塔拉蒙古自治州", + "lat": 44.913651, + "lon": 82.052436 + }, + { + "code": 652300, + "city_name": "新疆昌吉回族自治州", + "lat": 44.007058, + "lon": 87.296038 + }, + { + "code": 652200, + "city_name": "新疆哈密地区", + "lat": 42.858596, + "lon": 93.528355 + }, + { + "code": 653200, + "city_name": "新疆和田地区", + "lat": 37.116774, + "lon": 79.930239 + }, + { + "code": 653100, + "city_name": "新疆喀什地区", + "lat": 39.470627, + "lon": 75.992973 + }, + { + "code": 650200, + "city_name": "新疆克拉玛依市", + "lat": 45.594331, + "lon": 84.88118 + }, + { + "code": 652100, + "city_name": "新疆克拉玛依市吐鲁番地区", + "lat": 45.594331, + "lon": 84.88118 + }, + { + "code": 653000, + "city_name": "新疆克孜勒苏柯尔克孜自治州", + "lat": 39.750346, + "lon": 76.137564 + }, + { + "code": 654200, + "city_name": "新疆塔城地区", + "lat": 46.758684, + "lon": 82.974881 + }, + { + "code": 650100, + "city_name": "新疆乌鲁木齐市", + "lat": 43.84038, + "lon": 87.564988 + }, + { + "code": 654000, + "city_name": "新疆伊犁哈萨克自治州", + "lat": 43.922248, + "lon": 81.297854 + }, + { + "code": 530500, + "city_name": "云南省保山市", + "lat": 25.120489, + "lon": 99.177996 + }, + { + "code": 532300, + "city_name": "云南省楚雄彝族自治州", + "lat": 25.066356, + "lon": 101.529382 + }, + { + "code": 532900, + "city_name": "云南省大理白族自治州", + "lat": 25.5969, + "lon": 100.223675 + }, + { + "code": 533100, + "city_name": "云南省德宏傣族景颇族自治州", + "lat": 24.44124, + "lon": 98.589434 + }, + { + "code": 533400, + "city_name": "云南省迪庆藏族自治州", + "lat": 27.831029, + "lon": 99.713682 + }, + { + "code": 532500, + "city_name": "云南省红河哈尼族彝族自治州", + "lat": 23.367718, + "lon": 103.384065 + }, + { + "code": 530100, + "city_name": "云南省昆明市", + "lat": 25.049153, + "lon": 102.714601 + }, + { + "code": 530700, + "city_name": "云南省丽江市", + "lat": 26.875351, + "lon": 100.229628 + }, + { + "code": 530900, + "city_name": "云南省临沧市", + "lat": 23.887806, + "lon": 100.092613 + }, + { + "code": 533300, + "city_name": "云南省怒江傈僳族自治州", + "lat": 25.860677, + "lon": 98.859932 + }, + { + "code": 530800, + "city_name": "云南省普洱市", + "lat": 22.788778, + "lon": 100.980058 + }, + { + "code": 530300, + "city_name": "云南省曲靖市", + "lat": 25.520758, + "lon": 103.782539 + }, + { + "code": 532600, + "city_name": "云南省文山壮族苗族自治州", + "lat": 23.374087, + "lon": 104.246294 + }, + { + "code": 532800, + "city_name": "云南省西双版纳傣族自治州", + "lat": 22.009433, + "lon": 100.803038 + }, + { + "code": 530400, + "city_name": "云南省玉溪市", + "lat": 24.370447, + "lon": 102.545068 + }, + { + "code": 530600, + "city_name": "云南省昭通市", + "lat": 27.340633, + "lon": 103.725021 + }, + { + "code": 330100, + "city_name": "浙江省杭州市", + "lat": 30.259244, + "lon": 120.219375 + }, + { + "code": 330500, + "city_name": "浙江省湖州市", + "lat": 30.877925, + "lon": 120.137243 + }, + { + "code": 330400, + "city_name": "浙江省嘉兴市", + "lat": 30.773992, + "lon": 120.760428 + }, + { + "code": 330700, + "city_name": "浙江省金华市", + "lat": 29.102899, + "lon": 119.652576 + }, + { + "code": 331100, + "city_name": "浙江省丽水市", + "lat": 28.4563, + "lon": 119.929576 + }, + { + "code": 330200, + "city_name": "浙江省宁波市", + "lat": 29.885259, + "lon": 121.579006 + }, + { + "code": 330600, + "city_name": "浙江省绍兴市", + "lat": 30.002365, + "lon": 120.592467 + }, + { + "code": 331000, + "city_name": "浙江省台州市", + "lat": 28.668283, + "lon": 121.440613 + }, + { + "code": 330300, + "city_name": "浙江省温州市", + "lat": 28.002838, + "lon": 120.690635 + }, + { + "code": 330900, + "city_name": "浙江省舟山市", + "lat": 30.03601, + "lon": 122.169872 + }, + { + "code": 330800, + "city_name": "浙江省衢州市", + "lat": 28.95691, + "lon": 118.875842 + } +] \ No newline at end of file diff --git a/astro/cmd.go b/astro/cmd.go new file mode 100644 index 0000000..b77c8a4 --- /dev/null +++ b/astro/cmd.go @@ -0,0 +1,197 @@ +package astro + +import ( + "fmt" + "github.com/spf13/cobra" + "time" +) + +var isFormat bool + +func init() { + Cmd.PersistentFlags().Float64Var(&lon, "lon", -273, "经度,WGS84坐标系") + Cmd.PersistentFlags().Float64Var(&lat, "lat", -273, "纬度,WGS84坐标系") + Cmd.PersistentFlags().Float64Var(&height, "height", 0, "海拔高度") + CmdSun.Flags().StringVarP(&nowDay, "now", "n", "", "指定现在的时间") + CmdSun.Flags().BoolVarP(&isTimestamp, "timestamp", "t", false, "是否为时间戳") + CmdSun.Flags().BoolVarP(&isLive, "live", "v", false, "是否为实时") + CmdSun.Flags().BoolVarP(&isFormat, "format", "f", false, "格式化输出") + CmdSun.Flags().StringVarP(&city, "city", "c", "", "城市名") + + CmdMoon.Flags().StringVarP(&nowDay, "now", "n", "", "指定现在的时间") + CmdMoon.Flags().BoolVarP(&isTimestamp, "timestamp", "t", false, "是否为时间戳") + CmdMoon.Flags().BoolVarP(&isLive, "live", "v", false, "是否为实时") + CmdMoon.Flags().BoolVarP(&isFormat, "format", "f", false, "格式化输出") + CmdMoon.Flags().StringVarP(&city, "city", "c", "", "城市名") + + CmdStar.Flags().StringVarP(&nowDay, "now", "n", "", "指定现在的时间") + CmdStar.Flags().BoolVarP(&isTimestamp, "timestamp", "t", false, "是否为时间戳") + CmdStar.Flags().BoolVarP(&isLive, "live", "v", false, "是否为实时") + CmdStar.Flags().BoolVarP(&isFormat, "format", "f", false, "格式化输出") + CmdStar.Flags().StringVarP(&city, "city", "c", "", "城市名") + + Cmd.AddCommand(CmdCal, CmdSun, CmdMoon, CmdStar) +} + +var Cmd = &cobra.Command{ + Use: "astro", + Short: "天文计算", +} + +var CmdSun = &cobra.Command{ + Use: "sun", + Short: "太阳计算", + Run: func(cmd *cobra.Command, args []string) { + format := 0 + if isFormat { + format = 1 + } + isSet := CliLoadLonLatHeight() + var now = time.Now() + var err error + if nowDay != "" { + now, err = parseDate(now, nowDay, isTimestamp) + if err != nil { + fmt.Println(err) + return + } + } + for { + if isSet { + fmt.Printf("经度: %f 纬度: %f 海拔: %f\n", lon, lat, height) + } + BasicSun(now, uint8(format)) + if isSet { + SunDetail(now, lon, lat, height, uint8(format)) + } + if !isLive { + break + } + time.Sleep(time.Nanosecond* + time.Duration(1000000000-time.Now().Nanosecond()) + 1) + if nowDay == "" { + now = time.Now() + now = now.Add(time.Duration(now.Nanosecond()*-1) * time.Nanosecond) + } else { + now = now.Add(time.Second) + } + ClearScreen() + } + }, +} + +var CmdMoon = &cobra.Command{ + Use: "moon", + Short: "月亮计算", + Run: func(cmd *cobra.Command, args []string) { + format := 0 + if isFormat { + format = 1 + } + isSet := CliLoadLonLatHeight() + var now = time.Now() + var err error + if nowDay != "" { + now, err = parseDate(now, nowDay, isTimestamp) + if err != nil { + fmt.Println(err) + return + } + } + for { + if isSet { + fmt.Printf("经度: %f 纬度: %f 海拔: %f\n", lon, lat, height) + } + BasicMoon(now, uint8(format)) + if isSet { + MoonDetail(now, lon, lat, height, uint8(format)) + } + if !isLive { + break + } + time.Sleep(time.Nanosecond* + time.Duration(1000000000-time.Now().Nanosecond()) + 1) + if nowDay == "" { + now = time.Now() + now = now.Add(time.Duration(now.Nanosecond()*-1) * time.Nanosecond) + } else { + now = now.Add(time.Second) + } + ClearScreen() + } + }, +} + +var CmdStar = &cobra.Command{ + Use: "star", + Short: "星星计算", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + fmt.Println("请输入星星名字") + return + } + format := 0 + if isFormat { + format = 1 + } + isSet := CliLoadLonLatHeight() + var now = time.Now() + var err error + if nowDay != "" { + now, err = parseDate(now, nowDay, isTimestamp) + if err != nil { + fmt.Println(err) + return + } + } + for { + if isSet { + fmt.Printf("经度: %f 纬度: %f 海拔: %f\n", lon, lat, height) + } + BasicStar(now, args[0], uint8(format)) + if isSet { + StarDetail(now, args[0], lon, lat, height, uint8(format)) + } + if !isLive { + break + } + time.Sleep(time.Nanosecond* + time.Duration(1000000000-time.Now().Nanosecond()) + 1) + if nowDay == "" { + now = time.Now() + now = now.Add(time.Duration(now.Nanosecond()*-1) * time.Nanosecond) + } else { + now = now.Add(time.Second) + } + ClearScreen() + } + }, +} + +func CliLoadLonLatHeight() bool { + if city != "" { + if !GetFromCity(city) { + fmt.Println("城市名错误") + return false + } + fmt.Println("城市名: ", city) + SetLonLatHeight(lon, lat, height) + return true + } + tlon, tlat, theight := lon, lat, height + LoadLonLatHeight() + if lon == -273 && lon != tlon { + lon = tlon + } + if lat == -273 && lat != tlat { + lat = tlat + } + if height == 0 && height != theight { + height = theight + } + SetLonLatHeight(lon, lat, height) + if lon == -273 || lat == -273 { + return false + } + return true +} diff --git a/astro/moon.go b/astro/moon.go new file mode 100644 index 0000000..6298181 --- /dev/null +++ b/astro/moon.go @@ -0,0 +1,130 @@ +package astro + +import ( + "b612.me/astro/moon" + "b612.me/astro/star" + "b612.me/astro/sun" + "b612.me/astro/tools" + "fmt" + "time" +) + +func BasicMoon(date time.Time, format uint8) { + fmt.Printf("时间: %s\n", date.Format("2006-01-02 15:04:05")) + lo := moon.ApparentLo(date) + eo := moon.Phase(date) + bo := moon.TrueBo(date) + fmt.Println("月亮") + fmt.Println("------------------------") + switch format { + case 0: + fmt.Printf("黄经: %f\n", lo) + fmt.Printf("黄纬: %f\n", bo) + case 1: + flo := tools.Format(lo, 0) + fbo := tools.Format(bo, 0) + fmt.Printf("黄经: %s\n", flo) + fmt.Printf("黄纬: %s\n", fbo) + } + phaseStr := "" + mslo := tools.Limit360(lo - sun.ApparentLo(date)) + if mslo >= 0 && mslo <= 30 { + phaseStr = "新月" + } else if mslo > 30 && mslo <= 75 { + phaseStr = "上峨眉月" + } else if mslo > 75 && mslo <= 135 { + phaseStr = "上弦月" + } else if mslo > 135 && mslo < 170 { + phaseStr = "盈凸月" + } else if mslo >= 170 && mslo <= 190 { + phaseStr = "满月" + } else if mslo > 190 && mslo < 225 { + phaseStr = "亏凸月" + } else if mslo >= 225 && mslo < 285 { + phaseStr = "下弦月" + } else if mslo >= 285 && mslo < 330 { + phaseStr = "下峨眉月" + } else { + phaseStr = "残月" + } + + fmt.Printf("月相: %.2f%% %s\n", eo*100, phaseStr) + sx := moon.NextShangXianYue(date) + xx := moon.NextXiaXianYue(date) + wang := moon.NextWangYue(date) + shuo := moon.NextShuoYue(date) + fmt.Printf("朔月: %s\n", shuo.Format("2006-01-02 15:04:05")) + fmt.Printf("上弦: %s\n", sx.Format("2006-01-02 15:04:05")) + fmt.Printf("望月: %s\n", wang.Format("2006-01-02 15:04:05")) + fmt.Printf("下弦: %s\n", xx.Format("2006-01-02 15:04:05")) + +} + +func MoonDetail(date time.Time, lon, lat, height float64, format uint8) { + var err error + ra, dec := moon.ApparentRaDec(date, lon, lat) + tmp := new(time.Time) + *tmp, err = moon.RiseTime(date, lon, lat, height, true) + if err != nil { + if err == moon.ERR_NOT_TODAY { + *tmp, err = moon.RiseTime(date.AddDate(0, 0, -1), lon, lat, 0, true) + if err != nil { + *tmp = time.Time{} + } + } + } + rise := *tmp + tmp = new(time.Time) + *tmp, err = moon.DownTime(date, lon, lat, 0, true) + if err != nil { + if err == moon.ERR_NOT_TODAY { + *tmp, err = moon.DownTime(date.AddDate(0, 0, 1), lon, lat, 0, true) + if err != nil { + *tmp = time.Time{} + } + } + } + if tmp.Before(rise) { + tmp = new(time.Time) + *tmp, err = moon.DownTime(date.AddDate(0, 0, 1), lon, lat, 0, true) + if err != nil { + if err == moon.ERR_NOT_TODAY { + *tmp, err = moon.DownTime(date.AddDate(0, 0, 2), lon, lat, 0, true) + if err != nil { + *tmp = time.Time{} + } + } + } + } + set := tmp + cst := star.Constellation(ra, dec, date) + switch format { + case 0: + fmt.Printf("视赤经: %s\n", ra) + fmt.Printf("视赤纬: %s\n", dec) + case 1: + fra := tools.Format(ra/15, 1) + fdec := tools.Format(dec, 0) + fmt.Printf("视赤经: %s\n", fra) + fmt.Printf("视赤纬: %s\n", fdec) + } + fmt.Printf("星座: %s\n", cst) + fmt.Printf("升起: %s\n", rise.Format("2006-01-02 15:04:05")) + fmt.Printf("落下: %s\n", set.Format("2006-01-02 15:04:05")) + az := moon.Azimuth(date, lon, lat) + alt := moon.Zenith(date, lon, lat) + ta := moon.HourAngle(date, lon, lat) + switch format { + case 0: + fmt.Printf("方位角: %f\n", az) + fmt.Printf("高度角: %f\n", alt) + fmt.Printf("时角: %f\n", ta) + case 1: + faz := tools.Format(az, 0) + falt := tools.Format(alt, 0) + fta := tools.Format(ta/15, 1) + fmt.Printf("方位角: %s\n", faz) + fmt.Printf("高度角: %s\n", falt) + fmt.Printf("时角: %s\n", fta) + } +} diff --git a/astro/star.go b/astro/star.go new file mode 100644 index 0000000..ba50f4c --- /dev/null +++ b/astro/star.go @@ -0,0 +1,101 @@ +package astro + +import ( + "b612.me/astro/star" + "b612.me/astro/tools" + "fmt" + "time" +) + +func BasicStar(date time.Time, name string, format uint8) { + fmt.Printf("时间: %s\n", date.Format("2006-01-02 15:04:05")) + s, err := star.StarDataByName(name) + if err != nil { + fmt.Println(err) + return + } + ra, dec := s.RaDecByDate(date) + fmt.Printf("%s %s 星等:%.2f\n", s.ChineseName, s.Name, s.Mag) + fmt.Println("------------------------") + switch format { + case 0: + fmt.Printf("视赤经: %f\n", ra) + fmt.Printf("视赤纬: %f\n", dec) + case 1: + fra := tools.Format(ra/15, 1) + fdec := tools.Format(dec, 0) + fmt.Printf("视赤经: %s\n", fra) + fmt.Printf("视赤纬: %s\n", fdec) + } + cst := star.Constellation(ra, dec, date) + fmt.Printf("星座: %s\n", cst) +} + +func StarDetail(date time.Time, name string, lon, lat, height float64, format uint8) { + s, err := star.StarDataByName(name) + if err != nil { + fmt.Println(err) + return + } + ra, dec := s.RaDecByDate(date) + alt := star.Zenith(date, ra, dec, lon, lat) + ta := star.HourAngle(date, ra, lon) + zt := star.CulminationTime(date, ra, lon) + az := star.Azimuth(date, ra, dec, lon, lat) + var rise, set time.Time + var duration time.Duration + for { + nk := date.Add(duration) + rise, err = star.RiseTime(nk, ra, dec, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + if alt > 0 && rise.After(nk) { + rise, err = star.RiseTime(nk.Add(time.Hour*-24), ra, dec, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + } else if alt < 0 && rise.Before(nk) { + rise, err = star.RiseTime(nk.Add(time.Hour*24), ra, dec, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + + } + set, err = star.DownTime(nk, ra, dec, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + if set.Before(rise) { + set, err = star.DownTime(nk.Add(time.Hour*24), ra, dec, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + } + if set.Before(date) { + duration += time.Hour * 24 + continue + } + if zt.Before(rise) { + zt = star.CulminationTime(nk.Add(time.Hour*24), ra, lon) + } + break + } + + fmt.Printf("升起: %s\n", rise.Format("2006-01-02 15:04:05")) + fmt.Printf("中天: %s\n", zt.Format("2006-01-02 15:04:05")) + fmt.Printf("落下: %s\n", set.Format("2006-01-02 15:04:05")) + switch format { + case 0: + fmt.Printf("方位角: %f\n", az) + fmt.Printf("高度角: %f\n", alt) + fmt.Printf("时角: %f\n", ta) + case 1: + faz := tools.Format(az, 0) + falt := tools.Format(alt, 0) + fta := tools.Format(ta/15, 1) + fmt.Printf("方位角: %s\n", faz) + fmt.Printf("高度角: %s\n", falt) + fmt.Printf("时角: %s\n", fta) + } +} diff --git a/astro/sun.go b/astro/sun.go new file mode 100644 index 0000000..e652f7c --- /dev/null +++ b/astro/sun.go @@ -0,0 +1,76 @@ +package astro + +import ( + "b612.me/astro/star" + "b612.me/astro/sun" + "b612.me/astro/tools" + "fmt" + "time" +) + +func BasicSun(date time.Time, format uint8) { + fmt.Printf("时间: %s\n", date.Format("2006-01-02 15:04:05")) + ra, dec := sun.ApparentRaDec(date) + lo := sun.ApparentLo(date) + eo := sun.EclipticObliquity(date, true) + fmt.Println("太阳") + fmt.Println("------------------------") + switch format { + case 0: + fmt.Printf("视赤经: %f\n", ra) + fmt.Printf("视赤纬: %f\n", dec) + fmt.Printf("视黄经: %f\n", lo) + fmt.Printf("黄赤交角: %f\n", eo) + case 1: + fra := tools.Format(ra/15, 1) + fdec := tools.Format(dec, 0) + flo := tools.Format(lo, 0) + feo := tools.Format(eo, 0) + fmt.Printf("视赤经: %s\n", fra) + fmt.Printf("视赤纬: %s\n", fdec) + fmt.Printf("视黄经: %s\n", flo) + fmt.Printf("黄赤交角: %s\n", feo) + } + cst := star.Constellation(ra, dec, date) + fmt.Printf("星座: %s\n", cst) +} + +func SunDetail(date time.Time, lon, lat, height float64, format uint8) { + rise, err := sun.RiseTime(date, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + set, err := sun.DownTime(date, lon, lat, height, true) + if err != nil { + fmt.Println(err) + } + morning, err := sun.MorningTwilight(date, lon, lat, -6) + if err != nil { + fmt.Println(err) + } + evening, err := sun.EveningTwilight(date, lon, lat, -6) + if err != nil { + fmt.Println(err) + + } + fmt.Printf("晨朦影: %s\n", morning.Format("2006-01-02 15:04:05")) + fmt.Printf("升起: %s\n", rise.Format("2006-01-02 15:04:05")) + fmt.Printf("落下: %s\n", set.Format("2006-01-02 15:04:05")) + fmt.Printf("昏朦影: %s\n", evening.Format("2006-01-02 15:04:05")) + az := sun.Azimuth(date, lon, lat) + alt := sun.Zenith(date, lon, lat) + ta := sun.HourAngle(date, lon, lat) + switch format { + case 0: + fmt.Printf("方位角: %f\n", az) + fmt.Printf("高度角: %f\n", alt) + fmt.Printf("时角: %f\n", ta) + case 1: + faz := tools.Format(az, 0) + falt := tools.Format(alt, 0) + fta := tools.Format(ta/15, 1) + fmt.Printf("方位角: %s\n", faz) + fmt.Printf("高度角: %s\n", falt) + fmt.Printf("时角: %s\n", fta) + } +} diff --git a/go.mod b/go.mod index c7351c3..4699783 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module b612.me/apps/b612 -go 1.20 +go 1.21.2 require ( b612.me/bcap v0.0.4 @@ -32,6 +32,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/things-go/go-socks5 v0.0.5 github.com/vbauerster/mpb/v8 v8.8.3 + github.com/wayneashleyberry/terminal-dimensions v1.1.0 golang.org/x/crypto v0.26.0 golang.org/x/net v0.28.0 golang.org/x/sys v0.26.0 @@ -39,6 +40,7 @@ require ( ) require ( + b612.me/astro v0.0.4 // indirect b612.me/win32api v0.0.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect diff --git a/go.sum b/go.sum index 63c47a6..1ce510c 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +b612.me/astro v0.0.3 h1:MjZ6iAG28qEtZxzg1WFlTligu56b1O64hw1hl5wh/HI= +b612.me/astro v0.0.3/go.mod h1:yC1arIa79Q5ztQgWphj5mX5UvM/gddwTP+jGneojPt4= +b612.me/astro v0.0.4 h1:i60vJ3Dq+9U16ryMqmnjE0uXB28poRBx8boIMbP8VH8= +b612.me/astro v0.0.4/go.mod h1:yC1arIa79Q5ztQgWphj5mX5UvM/gddwTP+jGneojPt4= b612.me/bcap v0.0.4 h1:iY2Oz+uyG/mue6a/dJiU82ci5Xwkj4xHhre/q0O8G60= b612.me/bcap v0.0.4/go.mod h1:tpus+4iMpsnxb98Pck70s87Zt4sIWuRZjK23MmmzmoY= b612.me/notify v0.0.0-20240818092352-85803f75dfa0 h1:PaLuNLMM0HBM7qPdk4igtNvqT2CDgdm52sL+KA9I3so= @@ -35,9 +39,11 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aov github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0 h1:8iR6OLffWWorFdzL2JFCab5xpD8VKEE2DUBBl+HNTDY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0/go.mod h1:copqlcjMWc/wgQ1N2fzsJFQxDdqKGg1EQt8T5wJMOGE= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2/go.mod h1:FbdwsQ2EzwvXxOPcMFYO8ogEc9uMMIj3YkmCdXdAFmk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0 h1:rR8ZW79lE/ppfXTfiYSnMFv5EzmVuY4pfZWIkscIJ64= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0/go.mod h1:y2zXtLSMM/X5Mfawq0lOftpWn3f4V6OCsRdINsvWBPI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= @@ -57,6 +63,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE= github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M= @@ -68,6 +75,7 @@ github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTe github.com/emersion/go-smtp v0.20.2 h1:peX42Qnh5Q0q3vrAnRy43R/JwTnnv75AebxbkTL7Ia4= github.com/emersion/go-smtp v0.20.2/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/florianl/go-nfqueue/v2 v2.0.0 h1:NTCxS9b0GSbHkWv1a7oOvZn679fsyDkaSkRvOYpQ9Oo= github.com/florianl/go-nfqueue/v2 v2.0.0/go.mod h1:M2tBLIj62QpwqjwV0qfcjqGOqP3qiTuXr2uSRBXH9Qk= github.com/go-acme/lego/v4 v4.16.1 h1:JxZ93s4KG0jL27rZ30UsIgxap6VGzKuREsSkkyzeoCQ= @@ -98,11 +106,14 @@ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= @@ -129,7 +140,9 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= @@ -170,6 +183,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 h1:mmz27tVi2r70JYnm5y0Zk8w0Qzsx+vfUw3oqSyrEfP8= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 h1:g9SWTaTy/rEuhMErC2jWq9Qt5ci+jBYSvXnJsLq4adg= @@ -178,6 +192,8 @@ github.com/things-go/go-socks5 v0.0.5 h1:qvKaGcBkfDrUL33SchHN93srAmYGzb4CxSM2DPY github.com/things-go/go-socks5 v0.0.5/go.mod h1:mtzInf8v5xmsBpHZVbIw2YQYhc4K0jRwzfsH64Uh0IQ= github.com/vbauerster/mpb/v8 v8.8.3 h1:dTOByGoqwaTJYPubhVz3lO5O6MK553XVgUo33LdnNsQ= github.com/vbauerster/mpb/v8 v8.8.3/go.mod h1:JfCCrtcMsJwP6ZwMn9e5LMnNyp3TVNpUWWkN+nd4EWk= +github.com/wayneashleyberry/terminal-dimensions v1.1.0 h1:EB7cIzBdsOzAgmhTUtTTQXBByuPheP/Zv1zL2BRPY6g= +github.com/wayneashleyberry/terminal-dimensions v1.1.0/go.mod h1:2lc/0eWCObmhRczn2SdGSQtgBooLUzIotkkEGXqghyg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -287,6 +303,7 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go index 0027ca8..27f82f8 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "b612.me/apps/b612/aes" + "b612.me/apps/b612/astro" "b612.me/apps/b612/attach" "b612.me/apps/b612/base64" "b612.me/apps/b612/base85" @@ -54,7 +55,7 @@ func init() { base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd, ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd, calc.Cmd, net.Cmd, rmt.Cmds, rmt.Cmdc, keygen.Cmd, dns.Cmd, whois.Cmd, socks5.Cmd, httproxy.Cmd, smtpserver.Cmd, smtpclient.Cmd, - cert.Cmd, aes.Cmd, tls.Cmd, mget.Cmd, tcpkill.Cmd, tcm.Cmd) + cert.Cmd, aes.Cmd, tls.Cmd, mget.Cmd, tcpkill.Cmd, tcm.Cmd, astro.CmdCal, astro.Cmd) } func main() { diff --git a/nmon/cpu.go b/nmon/cpu.go new file mode 100644 index 0000000..610dfdc --- /dev/null +++ b/nmon/cpu.go @@ -0,0 +1,28 @@ +package nmon + +import ( + "fmt" + "github.com/shirou/gopsutil/v4/cpu" + "time" +) + +func Cpu() { + go func() { + flat, err := cpu.Percent(time.Second, false) + if err != nil { + return + } + fmt.Println(flat) + }() + flat, err := cpu.Percent(time.Second, true) + if err != nil { + return + } + c := 0.0000 + for _, v := range flat { + c += v + } + fmt.Println(flat) + fmt.Println(c / float64(len(flat))) + time.Sleep(time.Millisecond * 200) +} diff --git a/nmon/cpu_test.go b/nmon/cpu_test.go new file mode 100644 index 0000000..a3b00e5 --- /dev/null +++ b/nmon/cpu_test.go @@ -0,0 +1,7 @@ +package nmon + +import "testing" + +func TestCpu(t *testing.T) { + Cpu() +}