golang 获取NTP服务器时间并自动设置
发布时间:2023-03-31, 02:53:06 分类:Go | 编辑 off 网址 | 辅助
正文 3302字数 95,480阅读
package main
import (
"encoding/binary"
"flag"
"fmt"
"log"
"net"
"runtime"
"time"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/os/gproc"
"github.com/gogf/gf/text/gstr"
)
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
}
func main() {
var timeLayoutStr = "2006-01-02 15:04:05"
ntime := getremotetime()
ts := ntime.Format(timeLayoutStr) //time转string
fmt.Print(ts)
// 2021-08-29 15:53:35.922579627 +0800 CST
UpdateSystemDate(ts)
}
func getremotetime() time.Time {
var host string
// 182.92.12.11:123 是阿里的ntp服务器,可以换成其他域名的
flag.StringVar(&host, "e", "time.windows.com: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 showtime
}
func UpdateSystemDate(dateTime string) bool {
system := runtime.GOOS
switch system {
case "windows":
{
_, err1 := gproc.ShellExec(`date ` + gstr.Split(dateTime, " ")[0])
_, err2 := gproc.ShellExec(`time ` + gstr.Split(dateTime, " ")[1])
if err1 != nil && err2 != nil {
glog.Info("更新系统时间错误:请用管理员身份启动程序!")
return false
}
return true
}
case "linux":
{
_, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`)
if err1 != nil {
glog.Info("更新系统时间错误:", err1.Error())
return false
}
return true
}
case "darwin":
{
_, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`)
if err1 != nil {
glog.Info("更新系统时间错误:", err1.Error())
return false
}
return true
}
}
return false
}
Run code
Cut to clipboard
(支付宝)给作者钱财以资鼓励 (微信)→
有过 4 条评论 »
package main import ( "encoding/binary" "flag" "fmt" "log" "net" "runtime" "time" "github.com/gogf/gf/os/glog" "github.com/gogf/gf/os/gproc" "github.com/gogf/gf/text/gstr" "github.com/lxn/walk" ) 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 } func main() { var timeLayoutStr = "2006-01-02 15:04:05" ntime := getremotetime() ts := ntime.Format(timeLayoutStr) //time转string fmt.Print(ts) // 2021-08-29 15:53:35.922579627 +0800 CST UpdateSystemDate(ts) } func getremotetime() time.Time { var host string // 182.92.12.11:123 是阿里的ntp服务器,可以换成其他域名的 flag.StringVar(&host, "e", "ntp.aliyun.com: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 showtime } func UpdateSystemDate(dateTime string) bool { system := runtime.GOOS switch system { case "windows": { _, err1 := gproc.ShellExec(`date ` + gstr.Split(dateTime, " ")[0]) _, err2 := gproc.ShellExec(`time ` + gstr.Split(dateTime, " ")[1]) if err1 != nil && err2 != nil { glog.Info("更新系统时间错误:请用管理员身份启动程序!") walk.MsgBox(nil, "出错啦!!!", "更新系统时间错误,请右键,选择以管理员身份运行程序!", walk.MsgBoxIconInformation) return false } return true } case "linux": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } case "darwin": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } } return false }
// 接收UDP时间广播,并设置系统时间 func (sl *Slaver) masTimeSync(ch chan int) { // 开始监听广播时间 log.Printf("time sync listen [%s]", sl.Node.Port.PortUdpSlaTimeSync) for { (func() { // 监听 mas 发来的同步时间 lis, err := socket.NewListen("", sl.Node.Port.PortUdpSlaTimeSync, 3).ListenUDP() // 判断监听是否建立成功 if err != nil { // 异常抛出 log.Fatalln(err) } // 保证监听正常关闭 defer lis.Close() // 循环接收 for { // 每个时间戳大小不超过32字节 data := make([]byte, 32) // 读取时间戳 read, addr, err := lis.ReadFromUDP(data) // 检查是否接收错误 if err != nil { // 错误时从新接收 continue } // 判断是否为注册服务器所发 if addr != nil && strings.HasPrefix(addr.String(), sl.MasAddr) { // 转换远程时间戳 l, _ := strconv.ParseInt(fmt.Sprintf("%s", data[0:read]), 10, 64) //// 转换时间格式 //time := syscall.NsecToTimeval(l) //// 设置系统时间 "Linux Private Settimeofday" //if err := syscall.Settimeofday(&time); err != nil { // // 异常抛出 // log.Fatalln(err) //} // 设置到系统 cmd := exec.Command("date", "-s", time.Unix(0, l).Format("01/02/2006 15:04:05.999999999")) // 设置 cmd.Run() } } })() } }
package main import ( "github.com/gogf/gf/os/glog" "github.com/gogf/gf/os/gproc" "github.com/gogf/gf/text/gstr" "runtime" ) func main() { UpdateSystemDate("2020-03-20 15:02:41.372") } func UpdateSystemDate(dateTime string) bool { system := runtime.GOOS switch system { case "windows": { _, err1 := gproc.ShellExec(`date ` + gstr.Split(dateTime, " ")[0]) _, err2 := gproc.ShellExec(`time ` + gstr.Split(dateTime, " ")[1]) if err1 != nil && err2 != nil { glog.Info("更新系统时间错误:请用管理员身份启动程序!") return false } return true } case "linux": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } case "darwin": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } } return false }
go 修改操作系统时间 https://www.cnblogs.com/Kingram/p/12627709.html go 作为 ntp 客户端接收时间 https://github.com/vladimirvivien/go-ntp-client/blob/master/time.go 时间格式化 https://www.cnblogs.com/-xuzhankun/p/10812048.html package main import ( "encoding/binary" "flag" "fmt" "log" "net" "runtime" "time" "github.com/gogf/gf/os/glog" "github.com/gogf/gf/os/gproc" "github.com/gogf/gf/text/gstr" ) 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 } func main() { var timeLayoutStr = "2006-01-02 15:04:05" ntime := getremotetime() ts := ntime.Format(timeLayoutStr) //time转string fmt.Print(ts) // 2021-08-29 15:53:35.922579627 +0800 CST UpdateSystemDate(ts) } func getremotetime() time.Time { var host string // 182.92.12.11:123 是阿里的ntp服务器,可以换成其他域名的 flag.StringVar(&host, "e", "time.windows.com: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 showtime } func UpdateSystemDate(dateTime string) bool { system := runtime.GOOS switch system { case "windows": { _, err1 := gproc.ShellExec(`date ` + gstr.Split(dateTime, " ")[0]) _, err2 := gproc.ShellExec(`time ` + gstr.Split(dateTime, " ")[1]) if err1 != nil && err2 != nil { glog.Info("更新系统时间错误:请用管理员身份启动程序!") return false } return true } case "linux": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } case "darwin": { _, err1 := gproc.ShellExec(`date -s "` + dateTime + `"`) if err1 != nil { glog.Info("更新系统时间错误:", err1.Error()) return false } return true } } return false }