package utils import ( "encoding/binary" "flag" "log" "net" "time" ) const ntpEpochOffset = 2208988800 type packet struct { Settings uint8 Stratum uint8 Poll int8 Precision int8 RootDelay uint32 RootDispersion uint32 ReferenceID uint32 RefTimeSec uint32 RefTimeFrac uint32 OrigTimeSec uint32 OrigTimeFrac uint32 RxTimeSec uint32 RxTimeFrac uint32 TxTimeSec uint32 TxTimeFrac uint32 } // day 当天凌晨0点 func ZeroHourTimeOfDay(day time.Time) time.Time { dayStr := day.Format("2006-01-02") zeroHourTime, _ := ParseTimeStringToTime("2006-01-02", dayStr) return *zeroHourTime } // day 当月一号凌晨0点 func BeginningOfMonth(day time.Time) time.Time { dayStr := day.Format("2006-01") monthTime, _ := ParseTimeStringToTime("2006-01", dayStr) return *monthTime } // 指定年月的月份的月初凌晨0点和月末23点59分59秒 func MonthBeginningToEnd(year int, month int) (time.Time, time.Time) { beginningOfMonth := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local) beginningOfNextMonth := beginningOfMonth.AddDate(0, 1, 0) endOfMonth := beginningOfNextMonth.Add(time.Duration(-1)) return beginningOfMonth, endOfMonth } func GetNetTime() string { var host string flag.StringVar(&host, "e", "182.92.12.11:123", "NTP host") flag.Parse() conn, err := net.Dial("udp", host) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() if err := conn.SetDeadline(time.Now().Add(15 * time.Second)); err != nil { log.Fatalf("failed to set deadline: %v", err) } req := &packet{Settings: 0x1B} if err := binary.Write(conn, binary.BigEndian, req); err != nil { log.Fatalf("failed to send request: %v", err) } rsp := &packet{} if err := binary.Read(conn, binary.BigEndian, rsp); err != nil { log.Fatalf("failed to read server response: %v", err) } secs := float64(rsp.TxTimeSec) - ntpEpochOffset nanos := (int64(rsp.TxTimeFrac) * 1e9) >> 32 showtime := time.Unix(int64(secs), nanos) return time.Unix(showtime.Unix(), 0).Format("2006-01-02 15:04:05") }