时间
时间是非常重要的,离开了时间,几乎没有哪个生产环境数据能够有意义。
在Go语言中,时间定义为Time结构体。
package mainimport ("fmt""time"
)func main() {var t = time.Now()fmt.Println(t) fmt.Printf("%v %+[1]v\n", t)fmt.Printf("%#v\n", t)fmt.Printf("%T, %[1]v\n", t.UTC()) // UTC时间
}
2024-01-13 19:06:34.6726547 +0800 CST m=+0.003070601
2024-01-13 19:06:34.6726547 +0800 CST m=+0.003070601 2024-01-13 19:06:34.6726547 +0800 CST m=+0.003070601
time.Date(2024, time.January, 13, 19, 6, 34, 672654700, time.Local)
time.Time, 2024-01-13 11:06:34.6726547 +0000 UTC
时间格式化
Go语言没有采用%Y%m%d这样的格式化符号,它很特别。
package mainimport ("fmt""time"
)func main() {var t = time.Now()fmt.Printf("%T, %[1]v\n", t)fmt.Println(t.Format("0102 030405 06 pm -0700"))fmt.Println(t.UTC().Format("0102 030405 06 pm"))
}
time.Time, 2024-01-13 19:10:07.3356399 +0800 CST m=+0.003551301
0113 071007 24 pm +0800
0113 111007 24 am
记住一个字符串"010203040506pm-0700",即 1月2日下午3点4分5秒06年西7区 ,改成我们习惯的格式符 2006/01/02 15:04:05 -0700
Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02" 2不补位;_2补空格;02不够补0
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM) 如果写3或03显示为12小时制;15显示为24小时制
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"
"-0700" ±hhmm 时区
0或9匹配小数部分
格式化时,0或9表示小数部分位数,0超出部分补0,9超出部分不补0
var t = time.Now()
fmt.Printf("%T, %[1]v\n", t)
fmt.Println(t.Format("2006/01/02 15:04:05 -0700")) // 带时区
fmt.Println(t.UTC().Format("2006/01/02 15:04:05.0000")) // 不带时区time.Time, 2024-01-13 19:14:51.5891868 +0800 CST m=+0.003472101
2024/01/13 19:14:51 +0800
2024/01/13 11:14:51.5891
时间解析
package mainimport ("fmt""time"
)
func main() {if t, err := time.Parse("2006/01/02 15:04:05 -0700", // 格式字符串"2008/09/08 20:36:50 +0800", // 时间字符串); err == nil {fmt.Println(t)} else {fmt.Println(err)}
}
2008-09-08 20:36:50 +0800 CST
带小数部分解析
.0 解析时,0的位数必须和字符串中的小数部分位数完全一致,否则失败
.9 解析时,可以匹配任意位数小数部分,包括没有小数部分
time.Parse(
"2006/01/02 15:04:05.000000 -0700", // 格式字符串
"2008/09/08 20:36:50.123456 +0800", // 时间字符串
)
time.Parse(
"2006/01/02 15:04:05.9 -0700", // 格式字符串
"2008/09/08 20:36:50.123456 +0800", // 时间字符串
)
时间属性
package mainimport ("fmt""time"
)type Month intconst (January Month = 1 + iotaFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember
)type Weekday intconst (Sunday Weekday = iotaMondayTuesdayWednesdayThursdayFridaySaturday
)func main() {if t, err := time.Parse("2006/01/02 15:04:05 -0700", // 格式字符串"2008/09/08 20:36:50 +0800", // 时间字符串); err == nil {// 2008-09-08 20:36:50 +0800 CST// 时间戳fmt.Println(t.Unix(), t.UnixMilli(), t.UnixMicro(), t.UnixNano())// 年月日fmt.Println(t.Year(), t.Month(), t.Month().String(), // 英文月份,默认走String方法int(t.Month()), // 数字月份 9t.Day(),t.YearDay(), // YearDay本年的第几天)// 时分秒fmt.Println(t.Hour(), t.Minute(), t.Second(), t.Nanosecond()) //Nanosecond纳秒// 星期fmt.Println(t.Weekday(), int(t.Weekday())) // Weekdayfmt.Println(t.ISOWeek()) // 年的第几周}
}1220877410 1220877410000 1220877410000000 1220877410000000000
2008 September September 9 8 252
20 36 50 0
Monday 1
2008 37
市区
package mainimport ("fmt""time"
)func main() {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 UTCfmt.Println(t.Local()) // 2008-09-09 04:36:50 +0800 CST}
}
2008-09-08 20:36:50 +0000 UTC
2008-09-09 04:36:50 +0800 CST如果没有时区,表示UTC,可以简单认为是零时区时间。
注意,这里可能导致时间错误,给出的时间,心里想的是东八区的时间,但是Go语言却认为是零时区
的,如果再转换到东八区,就差了8个小时了。func main() {tz, _ := time.LoadLocation("Asia/Shanghai") // 使用名字if t, err := time.ParseInLocation("2006/01/02 15:04:05", // 格式字符串"2008/09/08 20:36:50", // 时间字符串tz,); err == nil {fmt.Println(t) // 2008-09-08 20:36:50 +0800 CSTfmt.Println(t.Local()) // 2008-09-08 20:36:50 +0800 CST}
}2008-09-08 20:36:50 +0800 CST
2008-09-08 20:36:50 +0800 CST
时间运算
时间 + 时间 = ?
时间 - 时间 = 时间差、时间增量
时间 ± 时间增量 = 时间
package mainimport ("fmt""time"
)func main() {tz, _ := time.LoadLocation("Asia/Shanghai") // 使用名字s1 := "2022/09/08 20:36:50"s2 := "2022/09/08 21:40:51"layout := "2006/01/02 15:04:05"t1, _ := time.ParseInLocation(layout, s1, tz)t2, _ := time.ParseInLocation(layout, s2, tz)fmt.Println(t1)fmt.Println(t2)// 时间差delta := t2.Sub(t1) // t2 - t1fmt.Printf("delta: %v, %[1]T\n", delta) // Duration类型fmt.Println(delta.Seconds()) // 共差多少秒// 构造Durationns3 := time.Duration(3) // 3纳秒s3 := time.Duration(3 * time.Second) // 3秒h3 := time.Duration(3 * time.Hour) // 3小时fmt.Println(ns3, s3, h3)// 时间偏移t3 := t2.Add(h3)fmt.Println(t3)t4 := t2.Add(-h3)fmt.Println(t4)fmt.Println(t3.After(t4))
}2022-09-08 20:36:50 +0800 CST
2022-09-08 21:40:51 +0800 CST
delta: 1h4m1s, time.Duration
3841
3ns 3s 3h0m0s
2022-09-09 00:40:51 +0800 CST
2022-09-08 18:40:51 +0800 CST
true