在Go语言中,时间定义为Time结构体。
var t = time.Now() fmt.Printf("%T\n", t) // time.Time fmt.Printf("%v %+[1]v\n", t) // 2022-10-06 19:35:00.1963422 +0800 CST m=+0.001534601 fmt.Printf("%#v\n", t) // time.Date(2022, time.October, 6, 19, 35, 0, 196342200, time.Local) fmt.Printf("%T, %[1]v\n", t.UTC()) // UTC时间 // time.Time, 2022-10-06 11:35:00.1963422 +0000 UTC
m=+0.001530201为单调时间,利用的是晶体振荡器的间隔时间,很多时间函数计算都舍弃了它。
时间格式化
Go语言没有采用%Y%m%d这样的格式化符号,可以记住一个字符串"010203040506pm-0700",即 1月2日下午3点4分5秒06年西7区 ,改成我们习惯的格式 符 2006/01/02 15:04:05 -0700。
func main() { var t = time.Now() fmt.Printf("%v\n", t) fmt.Println(t.Format("0102 030405 06 pm -0700")) fmt.Println(t.UTC().Format("2006/01/02 03:04:05.000 pm -0700")) // 12小时制显示 fmt.Println(t.Format("06-01-02 15:04:05.0000 -0700")) // 24小时制显示 }
打印结果:
时间解析
if t, err := time.Parse( "2006/01/02 15:04:05 -0700", // 格式字符串 "2008/09/08 20:36:50 +0800", // 时间字符串 ); err == nil { fmt.Println(t) // 2008-09-08 20:36:50 +0800 CST } else { fmt.Println(err) }
带小数部分解析:
.0 解析时,0的位数必须和字符串中的小数部分位数完全一致,否则失败
.9 解析时,可以匹配任意位数小数部分,包括没有小数部分
时间属性
下面时在time.go源码中定义的常量
func main() { t := time.Now() // 时间戳 fmt.Println(t.Unix(), t.UnixMilli(), t.UnixMicro(), t.UnixNano()) fmt.Println(t.Year(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond()) // 当打印t.Month()和t.Weekday()的时候,默认会调Month和Weekday的String方法 fmt.Println(t.Month(), t.Weekday()) fmt.Println(t.Month().String(), t.Weekday().String()) // 由于Month和Weekday是定义的别名int类型,所以通过强制类型转换可获取对于数字 fmt.Println(int(t.Month()), int(t.Weekday())) fmt.Println(t.ISOWeek()) // 判断是否位零值,时间的零值为:January 1, year 1, 00:00:00 UTC fmt.Println(t.IsZero()) }
打印结果:
时区
if t, err := time.Parse( "2006/01/02 15:04:05", // 格式字符串 "2008/09/08 20:36:50", // 时间字符串 ); err == nil { fmt.Println(t) // 2008-09-08 20:36:50 +0000 UTC fmt.Println(t.Local()) // 2008-09-09 04:36:50 +0800 CST }
如果没有时区,表示UTC,可以简单认为是零时区时间。
时间运算
func main() { tz, _ := time.LoadLocation("Asia/Shanghai") layout := "2006/01/02 03:04:05.00000 pm" t0, _ := time.Parse(layout, "2023/07/11 10:48:54.35723 am") t1, _ := time.ParseInLocation(layout, "2023/07/11 10:48:41.35723 am", tz) fmt.Println(t0) fmt.Println(t1) // 计算时间差 delta := t0.Sub(t1) fmt.Printf("%T %[1]v\n", delta) // 相差的秒数、分钟数 fmt.Println(delta.Seconds(), delta.Minutes()) }
执行结果:
func main() { // 根据当前时间,求出八年前的今天的9点30分的时间 t0 := time.Now() tz, _ := time.LoadLocation("Asia/Shanghai") t1 := time.Date(t0.Year()-8, t0.Month(), t0.Day(), 9, 30, t0.Second(), 0, tz) fmt.Printf("当前时间: %v\n", t0) fmt.Printf("八年前的今天的9点30分: %v\n", t1.Format("2006/01/02 15:04:05 +0800")) // 当时的毫秒时间戳 fmt.Println(t1.UnixMilli()) // 当时距离今天有多少天 passedDays := t0.Sub(t1).Hours() / 24 fmt.Println(math.Floor(passedDays)) // 返回ISO 8601年份和周号,周的范围为1-53 fmt.Println(t0.ISOWeek()) fmt.Println(t0.Local()) // 获取时间的时区 fmt.Println(t0.Location(), t1.Location()) // 根据年月日来自由加减 fmt.Println(t0.AddDate(0, 1, -1)) }
打印结果: