import "time"
time
包提供了时间的显示和测量用的函数。日历的计算采用的是公历。
Go
提供以下几种时间类型:
Time
Duration
Location
Ticker
Timer
type Time struct {
// 内含隐藏或非导出字段
}
Time
代表一个纳秒精度的时间点。
程序中应使用 Time
类型值来保存和传递时间,而不能用指针。就是说,表示时间的变量和字段,应为 time.Time
类型,而不是 *time.Time
类型。
时间点可以使用 Before
、 After
和 Equal
方法进行比较。
Sub
方法让两个时间点相减,生成一个 Duration
类型值(代表时间段);Add
方法给一个时间点加上一个时间段,生成一个新的Time类型时间点;Time
零值代表时间点 January 1, year 1, 00:00:00.000000000 UTC。因为本时间点一般不会出现在使用中, IsZero
方法提供了检验时间是否显式初始化的一个简单途径。
每一个时间都具有一个地点信息(及对应地点的时区信息),当计算时间的表示格式时,如 Format
、 Hour
和 Year
等方法,都会考虑该信息。 Local
、 UTC
和 In
方法返回一个指定时区(但指向同一时间点)的 Time
。修改地点/时区信息只是会改变其表示;不会修改被表示的时间点,因此也不会影响其计算。
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Date
返回一个时区为 loc
、当地时间为:
year-month-day hour:min:sec + nsec nanoseconds
的时间点。
代码示例:
func main() {
timeDate := time.Date(2020, 05, 23, 10, 11, 12, 13, time.Local)
fmt.Printf("timeDate is %v, type is %T", timeDate, timeDate)
// timeDate is 2020-05-23 10:11:12.000000013 +0800 CST, type is time.Time
}
func Now() Time
Now
返回当前本地时间。
代码示例:
func main() {
timeNow := time.Now()
fmt.Printf("timeNow is %v, type is %T", timeNow, timeNow)
// timeNow is 2020-05-23 10:23:11.061117 +0800 CST m=+0.005000301, type is time.Time
}
func Parse(layout, value string) (Time, error)
Parse
解析一个格式化的时间字符串并返回它代表的时间。 layout
定义了参考时间:
Mon Jan 2 15:04:05 -0700 MST 2006,注意 layout
必须为 “2006-01-02 15:04:05”,否则会报错误:
parsing time "2020-05-22 10:25:30": month out of range
代码示例:
func main() {
timeParse, err := time.Parse("2006-01-02 15:04:05", "2020-05-22 10:25:30")
if err != nil {
fmt.Println("time parse failed: ", err)
}
fmt.Printf("timeParse is %v, type is %T", timeParse, timeParse)
// timeParse is 2020-05-22 10:25:30 +0000 UTC, type is time.Time
}
func ParseInLocation(layout, value string, loc *Location) (Time, error)
ParseInLocation
类似 Parse
但有两个重要的不同之处:
Parse
将时间解释为 UTC
时间,而 ParseInLocation
将返回值的 Location
设置为 loc
;Parse
会尝试去匹配本地时区,而 ParseInLocation
会去匹配loc代码示例:
func main() {
ParseInLocation, err := time.ParseInLocation("2006-01-02 15:04:05", "2020-05-22 10:25:30", time.Local)
if err != nil {
fmt.Println("time ParseInLocation failed: ", err)
}
fmt.Printf("ParseInLocation is %v, type is %T", ParseInLocation, ParseInLocation)
// ParseInLocation is 2020-05-22 10:25:30 +0800 CST, type is time.Time
}
func Unix(sec int64, nsec int64) Time
Unix
创建一个本地时间,对应 sec
和 nsec
表示的 Unix
时间(从January 1, 1970 UTC至该时间的秒数和纳秒数)。
nsec
的值在 [0, 999999999] 范围外是合法的。
代码示例:
func main() {
timeUnix := time.Unix(322020993, 3939993399848320)
fmt.Printf("timeUnix is %v, type is %T", timeUnix, timeUnix)
// timeUnix is 1980-05-01 00:43:06.39984832 +0800 CST, type is time.Time
}
以上的函数 Date
、 Now
、 Parse
、 ParseInLocation
、 Unix
返回的都是 Time
类型的结构体。
Time
类型有很多结构体方法,如下表所示:
func (t Time) Location() *Location
func (t Time) Zone() (name string, offset int)
func (t Time) IsZero() bool
func (t Time) Local() Time
func (t Time) UTC() Time
func (t Time) In(loc *Location) Time
func (t Time) Unix() int64
func (t Time) UnixNano() int64
func (t Time) Equal(u Time) bool
func (t Time) Before(u Time) bool
func (t Time) After(u Time) bool
func (t Time) Date() (year int, month Month, day int)
func (t Time) Clock() (hour, min, sec int)
func (t Time) Year() int
func (t Time) Month() Month
func (t Time) ISOWeek() (year, week int)
func (t Time) YearDay() int
func (t Time) Day() int
func (t Time) Weekday() Weekday
func (t Time) Hour() int
func (t Time) Minute() int
func (t Time) Second() int
func (t Time) Nanosecond() int
func (t Time) Add(d Duration) Time
func (t Time) AddDate(years int, months int, days int) Time
func (t Time) Sub(u Time) Duration
func (t Time) Round(d Duration) Time
func (t Time) Truncate(d Duration) Time
func (t Time) Format(layout string) string
func (t Time) String() string
func (t Time) GobEncode() ([]byte, error)
func (t *Time) GobDecode(data []byte) error
func (t Time) MarshalBinary() ([]byte, error)
func (t *Time) UnmarshalBinary(data []byte) error
func (t Time) MarshalJSON() ([]byte, error)
func (t *Time) UnmarshalJSON(data []byte) error
func (t Time) MarshalText() ([]byte, error)
func (t *Time) UnmarshalText(data []byte) error
代码示例如下:
func main() {
nowTime := time.Now()
fmt.Println("nowTime.Location", nowTime.Location())
zoneName, _ := nowTime.Zone()
fmt.Println("nowTime.Zone", zoneName)
fmt.Println("nowTime.IsZero", nowTime.IsZero())
fmt.Println("nowTime.Location", nowTime.Local())
fmt.Println("nowTime.UTC", nowTime.UTC())
fmt.Println("nowTime.In", nowTime.In(nowTime.Location()))
fmt.Println("nowTime.Unix", nowTime.Unix())
fmt.Println("nowTime.UnixNano", nowTime.UnixNano())
fmt.Println("nowTime.Equal", nowTime.Equal(nowTime))
fmt.Println("nowTime.Before", nowTime.Before(nowTime))
fmt.Println("nowTime.After", nowTime.After(nowTime))
fmt.Println(nowTime.Date())
fmt.Println(nowTime.Clock())
fmt.Println("nowTime.Year", nowTime.Year())
fmt.Println("nowTime.YearDay", nowTime.YearDay())
fmt.Println("nowTime.Month", nowTime.Month())
fmt.Println(nowTime.ISOWeek())
fmt.Println("nowTime.Day", nowTime.Day())
fmt.Println("nowTime.Weekday", nowTime.Weekday())
fmt.Println("nowTime.Hour", nowTime.Hour())
fmt.Println("nowTime.Minute", nowTime.Minute())
fmt.Println("nowTime.Second", nowTime.Second())
fmt.Println("nowTime.Nanosecond", nowTime.Nanosecond())
fmt.Println("nowTime.Add", nowTime.Add(time.Hour*3))
fmt.Println("nowTime.AddDate", nowTime.AddDate(2, 3, 4))
fmt.Println("nowTime.Sub", nowTime.Sub(nowTime))
fmt.Println("nowTime.String", nowTime.String())
fmt.Println("nowTime.Format", nowTime.Format("2006-01-02 15:04:05"))
fmt.Println("nowTime.Format", nowTime.Format("2006-01-02 15-04-05"))
fmt.Println("nowTime.Format", nowTime.Format("2006-01-02"))
}
输出结果:
nowTime.Location Local
nowTime.Zone CST
nowTime.IsZero false
nowTime.Location 2020-05-23 15:03:24.4848344 +0800 CST
nowTime.UTC 2020-05-23 07:03:24.4848344 +0000 UTC
nowTime.In 2020-05-23 15:03:24.4848344 +0800 CST
nowTime.Unix 1590217404
nowTime.UnixNano 1590217404484834400
nowTime.Equal true
nowTime.Before false
nowTime.After false
2020 May 23
15 3 24
nowTime.Year 2020
nowTime.YearDay 144
nowTime.Month May
2020 21
nowTime.Day 23
nowTime.Weekday Saturday
nowTime.Hour 15
nowTime.Minute 3
nowTime.Second 24
nowTime.Nanosecond 484834400
nowTime.Add 2020-05-23 18:03:24.4848344 +0800 CST m=+10800.007000401
nowTime.AddDate 2022-08-27 15:03:24.4848344 +0800 CST
nowTime.Sub 0s
nowTime.String 2020-05-23 15:03:24.4848344 +0800 CST m=+0.007000401
nowTime.Format 2020-05-23 15:03:24
nowTime.Format 2020-05-23 15-03-24
nowTime.Format 2020-05-23
type Duration int64
Duration
类型代表两个时间点之间经过的时间,以纳秒为单位。
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
常用的时间段。没有定义一天或超过一天的单元,以避免夏时制的时区切换的混乱。
要将 Duration
类型值表示为某时间单元的个数,用除法:
second := time.Second
fmt.Print(int64(second/time.Millisecond)) // prints 1000
要将整数个某时间单元表示为 Duration
类型值,用乘法:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
func ParseDuration(s string) (Duration, error)
ParseDuration
解析一个时间段字符串。一个时间段字符串是一个序列,每个片段包含可选的正负号、十进制数、可选的小数部分和单位后缀,如"300ms"、"-1.5h"、“2h45m”。合法的单位有"ns"、“us” /“µs”、“ms”、“s”、“m”、“h”。
func Since(t Time) Duration
Since
返回从 t
到现在经过的时间,等价于 time.Now().Sub(t)
。
func test() {
start := time.Now() // 获取当前时间
sum := 0
for i := 0; i < 100000000; i++ {
sum++
}
elapsed := time.Since(start) // 等价于 elapsed := time.Now().Sub(start)
fmt.Println("该函数执行完成耗时:", elapsed)
}
ParseDuration
解析一个时间段字符串。一个时间段字符串是一个序列,每个片段包含可选的正负号、十进制数、可选的小数部分和单位后缀,如"300ms"、"-1.5h"、“2h45m”。
合法的单位有"ns"、“us”、“µs”、“ms”、“s”、“m”、“h”。
func (d Duration) Hours() float64
func (d Duration) Minutes() float64
func (d Duration) Seconds() float64
func (d Duration) Nanoseconds() int64
func (d Duration) String() string
代码示例:
func main() {
tp, _ := time.ParseDuration("120s")
fmt.Println("tp.Hours", tp.Hours()) // tp.Hours 0.03333333333333333
fmt.Println("tp.Minutes", tp.Minutes()) // tp.Minutes 2
fmt.Println("tp.Seconds", tp.Seconds()) // tp.Seconds 120
fmt.Println("tp.Nanoseconds", tp.Nanoseconds()) // tp.Nanoseconds 120000000000
fmt.Println("tp.String", tp.String()) // tp.String 2m0s
}
func LoadLocation(name string) (*Location, error)
func FixedZone(name string, offset int) *Location
func (l *Location) String() string
代码示例:
func main() {
loc, _ := time.LoadLocation("")
// 服务器设定的时区,一般为CST
loc, _ = time.LoadLocation("Local")
fmt.Println("loc is ", loc) // loc is Local
// 美国洛杉矶PDT
loc, _ = time.LoadLocation("America/Los_Angeles")
fmt.Println("loc is ", loc) // loc is America/Los_Angeles
// 获取指定时区的时间点
local, _ := time.LoadLocation("America/Los_Angeles")
fmt.Println(time.Date(2018, 1, 1, 12, 0, 0, 0, local)) //2018-01-01 12:00:00 -0800 PST
}
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
源码包定义以上常量,在代码中可以通过 time.XXX
得到,代码如下:
func main() {
fmt.Println("time.Nanosecond", time.Nanosecond) // time.Nanosecond 1ns
fmt.Println("time.Microsecond", time.Microsecond) // time.Microsecond 1µs
fmt.Println("time.Millisecond", time.Millisecond) // time.Millisecond 1ms
fmt.Println("time.Second", time.Second) // time.Second 1s
fmt.Println("time.Minute", time.Minute) // time.Minute 1m0s
fmt.Println("time.Hour", time.Hour) // time.Hour 1h0m0s
}
代码如下:
func main() {
timeNow := time.Now()
fmt.Println("timeNow is ", timeNow)
// timeNow is 2020-05-23 22:29:53.0060736 +0800 CST m=+0.005000301
timeUnix := timeNow.Unix()
fmt.Println("timeUnix is ", timeUnix)
// timeUnix is 1590244193
timeCurrent := time.Unix(timeUnix, 0)
fmt.Println("timeCurrent is ", timeCurrent)
// timeCurrent is 2020-05-23 22:29:53 +0800 CST
}
注意: Go
中指定的特定时间格式为 2006-01-02 15:04:05 -0700 MST
, 为了记忆方便,按照美式时间格式 月日时分秒年 外加时区 排列起来依次是 01/02 03:04:05PM ‘06 -0700,刚开始使用时需要注意。
这一点与 Python
中的 %Y-%m-%d %H-%M-%S
有区别。
示例代码:
const (
//time format
FormatDay = "2006-01-02"
FormatSecond = "2006-01-02 15:04:05"
FormatMinute = "2006-01-02 15:04"
FormatOnlyHour = "15:04"
)
func main() {
timeFormatDay := time.Now().Format(FormatDay)
fmt.Printf("timeFormatDay is %#v, type is %T\n", timeFormatDay, timeFormatDay)
// timeFormatDay is "2020-05-23", type is string
timeFormatSecond := time.Now().Format(FormatSecond)
fmt.Println("timeFormatSecond is ", timeFormatSecond)
// timeFormatSecond is 2020-05-23 22:44:26
timeFormatMinute := time.Now().Format(FormatMinute)
fmt.Println("timeFormatMinute is ", timeFormatMinute)
// timeFormatMinute is 2020-05-23 22:44
timeFormatOnlyHour := time.Now().Format(FormatOnlyHour)
fmt.Println("timeFormatOnlyHour is ", timeFormatOnlyHour)
// timeFormatOnlyHour is 22:44
}
代码如下:
const (
//time format
FormatDay = "2006-01-02"
FormatSecond = "2006-01-02 15:04:05"
FormatMinute = "2006-01-02 15:04"
FormatOnlyHour = "15:04"
)
func main() {
timestamp, _ := time.Parse(FormatSecond, "2020-05-23 22:20:30")
fmt.Printf("timestamp is %v, type is %T\n", timestamp, timestamp)
// timestamp is 2020-05-23 22:20:30 +0000 UTC, type is time.Time
fmt.Println(timestamp.Unix()) //时间戳 1590272430
fmt.Println(time.Date(2020, 05, 23, 10, 11, 12, 13, time.Local).Unix())
}
示例代码:
const (
//time format
FormatDay = "2006-01-02"
FormatSecond = "2006-01-02 15:04:05"
FormatMinute = "2006-01-02 15:04"
FormatOnlyHour = "15:04"
)
func main() {
loc, _ := time.LoadLocation("Asia/Shanghai")
t, _ := time.ParseInLocation(FormatSecond, "2020-05-23 22:20:30", loc)
fmt.Printf("t is %v, type is %T\n", t, t)
// 标准时间格式 t is 2020-05-23 22:20:30 +0800 CST, type is time.Time
fmt.Println(t.Unix()) //时间戳 1590243630
}
dt := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)
fmt.Println(time.Now().After(dt)) // true
fmt.Println(time.Now().Before(dt)) // false
// 是否相等 判断两个时间点是否相等时推荐使用 Equal 函数
fmt.Println(dt.Equal(time.Now()))
// time.Local 用来表示当前服务器时区
// 自定义地区时间
secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
fmt.Println(time.Date(2018,1,2,0,0,0,0, beijing)) // 2018-01-02 00:00:00 +0800 Beijing Time
// 当前时间转为指定时区时间
fmt.Println(time.Now().In(beijing))
// 指定时间转换成指定时区对应的时间
dt, err := time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", time.Local)
// 当前时间在零时区年月日 时分秒 时区
year, mon, day := time.Now().UTC().Date() // 2018 April 24
hour, min, sec := time.Now().UTC().Clock() // 3 47 15
zone, _ := time.Now().UTC().Zone() // UTC
now := time.Now()
// 一年零一个月一天之后
fmt.Println(now.Date(1,1,1))
// 一段时间之后
fmt.Println(now.Add(time.Duration(10)*time.Minute))
// 计算两个时间点的相差天数
dt1 = time.Date(dt1.Year(), dt1.Month(), dt1.Day(), 0, 0, 0, 0, time.Local)
dt2 = time.Date(dt2.Year(), dt2.Month(), dt2.Day(), 0, 0, 0, 0, time.Local)
fmt.Println(int(math.Ceil(dt1.Sub(dt2).Hours() / 24)))
dt1 := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)
dt2 := time.Date(2018, 1, 9, 23, 59, 22, 100, time.Local)
// 不用关注时区,go会转换成时间戳进行计算
fmt.Println(dt1.Sub(dt2))
// func Sleep(d Duration) 休眠多少时间,休眠时处于阻塞状态,后续程序无法执行
time.Sleep(time.Duration(10) * time.Second)
// func After(d Duration) <-chan Time 非阻塞,可用于延迟
time.After(time.Duration(10) * time.Second)
// func Since(t Time) Duration 两个时间点的间隔
start := time.Now()
fmt.Println(time.Since(start)) // 等价于 Now().Sub(t), 可用来计算一段业务的消耗时间
func Until(t Time) Duration // 等价于 t.Sub(Now()),t与当前时间的间隔
// func (t Time) Add(d Duration) Time
fmt.Println(dt.Add(time.Duration(10) * time.Second)) // 加
func (t Time) Sub(u Time) Duration // 减
// func (t Time) AddDate(years int, months int, days int) Time
fmt.Println(dt.AddDate(1, 1, 1))
func (t Time) Before(u Time) bool
func (t Time) After(u Time) bool
func (t Time) Equal(u Time) bool 比较时间点时尽量使用Equal函数
参考:
https://segmentfault.com/a/1190000015040923?utm_source=tag-newest
https://blog.csdn.net/wschq/article/details/80114036
https://studygolang.com/static/pkgdoc/pkg/time.htm