引言
- 写文章的初衷是因为学习到了cron时,想要自己写个必须要对time有不错的理解
- 记录一下自己的学习过程,方便以后查询资料
- time包的使用
- time包的源码分析
- github地址
1、time介绍
时间可分为时间点与时间段,golang 也不例外,提供了以下两种基础类型
- 时间点(Time)
- 时间段(Duration)
此外还有一些特殊的类型
- 时区(Location)
- Ticker
- Timer(定时器)
2、时间点
2.1 初始化time
// func Now() Time 返回当前本地时间
fmt.Println(time.Now())
// func (t Time) In(loc *Location) Time 返回特定时区时间
fmt.Println(time.Now().In(time.UTC))
// 返回自定义时间 + 时区
// func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
fmt.Println(time.Date(2018, 9, 12, 12, 30, 10, 0, time.Local))
// func Parse(layout, value string) (Time, error) 字符串转换为时间类型
fmt.Println(time.Parse("2006-01-02 15:04:05", "2018-04-23 12/24/51"))
// 字符串转换为时间格式并设置时区
// func ParseInLocation(layout, value string, loc *Location) (Time, error) (layout已带时区时可直接用Parse)
fmt.Println(time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", time.Local))
// Unix返回与给定Unix时间相对应的本地时间
// func Unix(func Unix(sec int64, nsec int64) Time
fmt.Println(time.Unix(1, 2))
2.2 转换为字符串
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
// func
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
fmt.Println(time.Now().Format("2006/01/02 15:04:05"))
fmt.Println(time.Now().Format("2006年01月02日 15:04:05"))
fmt.Println(time.Now().Format(time.RFC3339))
// func (t Time) AppendFormat(b []byte, layout string) []byte
fmt.Println(string(time.Now().AppendFormat([]byte("时间: "), "2006-01-02 15:04:05")))
2020-10-16 11:05:09
2020/10/16 11:05:09
2020年10月16日 11:05:09
2020-10-16T11:05:09+08:00
时间: 2020-10-16 11:05:09
golang 特定的时间格式 2006-01-02 15:04:05
2.3 转换为时间戳
//func (t Time) Unix() int64
fmt.Println(time.Now().Unix())
//func (t Time) UnixNano() int64
fmt.Println(time.Now().UnixNano())
2.4 时间函数
获取时间的年月日时分秒等
func (t Time) Date() (year int, month Month, day int) //返回年月日 2020 October 16
func (t Time) Clock() (hour, min, sec int) //返回时分秒 11 7 0
func (t Time) Year() int //返回年份 2020
func (t Time) Month() Month //返回月份英文 October
func (t Time) Day() int //返回天数 16
func (t Time) Hour() int //返回小时 11
func (t Time) Minute() int //返回分钟 7
func (t Time) Second() int //返回秒 5
func (t Time) Nanosecond() int //返回纳秒 991813400
func (t Time) YearDay() int //返回指定年的日期非闰年[1,365]闰年[1,366] 290
func (t Time) Weekday() Weekday //返回周英文 Friday
func (t Time) ISOWeek() (year, week int) //返回 ISO 8601 year 第多少周 2020 42
时间点判断
// func (t Time) Equal(u Time) bool
fmt.Println(time.Now().Equal(time.Now()))
// func (t Time) Before(u Time) bool
fmt.Println(time.Now().Before(time.Now()))
// func (t Time) After(u Time) bool
fmt.Println(time.Now().After(time.Now()))
时间加减
// func (t Time) AddDate(years int, months int, days int) Time
fmt.Println(time.Now().AddDate(0, 0, 1))
// func (t Time) Add(d Duration) Time 当前时间加传入时间段
fmt.Println(time.Now().Add(time.Duration(1) * time.Hour))
// func Until(t Time) Duration 传入时间减本地时间
fmt.Println(time.Until(time.Date(2018, 9, 12, 12, 30, 10, 0, time.Local)))
// func Since(t Time) Duration 本地时间减传入时间
fmt.Println(time.Since(time.Date(2018, 9, 12, 12, 30, 10, 0, time.Local)))
// func (t Time) Sub(u Time) Duration 当前时间减传入时间
fmt.Println(time.Now().Sub(time.Date(2018, 9, 12, 12, 30, 10, 0, time.Local)))
时区相关函数
//func (t Time) Zone() (name string, offset int) 算在时间t生效的时区,返回缩写
fmt.Println(time.Now().Zone())
//func (t Time) Location() *Location 获取当前时间设置的时区
fmt.Println(time.Now().Location())
//func (t Time) In(loc *Location) Time 设置时区返回时间
fmt.Println(time.Now().In(time.UTC))
fmt.Println(time.Now().In(time.UTC).Zone())
// func (t Time) Local() Time
fmt.Println(time.Now().Local())
// func (t Time) UTC() Time
fmt.Println(time.Now().UTC())
// func LoadLocation(name string) (*Location, error) 加载时区
location, _ := time.LoadLocation("America/Los_Angeles")
fmt.Println(time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC).In(location))
// func FixedZone(name string, offset int) *Location 设置时区及其偏移量
loc := time.FixedZone("UTC-8", -8*60*60)
fmt.Println(time.Date(2018, 9, 12, 12, 30, 10, 0, loc))
fmt.Println(time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", loc))
其他函数
//func (t Time) IsZero() bool
fmt.Println(time.Now().IsZero())//是否零时间瞬间
// func Sleep(d Duration) 休眠多少时间,休眠时处于阻塞状态,后续程序无法执行
time.Sleep(time.Duration(1) * time.Second)
// func (t Time) GobEncode() ([]byte, error)
encode, _ := time.Now().GobEncode()
fmt.Println(encode)
// func (t *Time) GobDecode(data []byte) error
var ignored time.Time
fmt.Println(ignored.GobDecode(encode))
fmt.Println(string(encode))
//marshal binary序列化,将时间t序列化后存入[]byte数组中
//func (t Time) MarshalBinary() ([]byte, error)
//marshal json序列化,将时间t序列化后存入[]byte数组中
//func (t Time) MarshalJSON() ([]byte, error)
//marshal text序列化,将时间t序列化后存入[]byte数组中
//func (t Time) MarshalText() ([]byte, error)
//将data数据反序列化到时间t中
//func (t *Time) UnmarshalBinary(data []byte) error
//将data数据反序列化到时间t中
//func (t *Time) UnmarshalJSON(data []byte) (err error)
//将data数据反序列化到时间t中
//func (t *Time) UnmarshalText(data []byte) (err error)
tbyte, err := time.Now().MarshalJSON()
fmt.Println("'t.MarshalJSON': ", tbyte, err)
// 时间数据反序列化
var tun time.Time
err = tun.UnmarshalJSON(tbyte)
fmt.Println("'t_un.UnmarshalJSON': ", tun, err)
3、时间段(Duartion)
// func ParseDuration(s string) (Duration, error)
tp, _ := time.ParseDuration("10508888788.9ns")
// time.Duration(10) * time.Second
fmt.Println(tp.Truncate(1000), tp.Seconds(), tp.Nanoseconds())
func (d Duration) Hours() float64
func (d Duration) Minutes() float64
func (d Duration) Seconds() float64
func (d Duration) Milliseconds() float64 //毫秒
func (d Duration) Microseconds() float64 //微秒
func (d Duration) Nanoseconds() int64 //纳秒
func (d Duration) Round(m Duration) Duration // 四舍五入
func (d Duration) Truncate(m Duration) Duration // 向下取整
4、定时器(心跳)Ticker
在特定的时间间隔持续触发
- 案例
ticker := time.NewTicker(time.Second)
defer ticker.Stop() //
done := make(chan bool)
go func() {
time.Sleep(10 * time.Second)
done <- true
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-ticker.C:
fmt.Println("Current time: ", t)
}
}
- 相关方法
1、time.NewTicker() 创建一个定时器
2、time.Tick() 获取定时器的时间通道
2、ticker.Stop() 停止
5、计时器 Timer
给定多少时间后触发
- 函数
func NewTimer(d Duration) *Timer 初始化
func AfterFunc(d Duration, f func()) *Timer 初始化并且传入匿名函数
func (*Timer) Reset
func (*Timer) Stop
- NewTimer案例
fmt.Println("秒:", time.Now().Second())
timer := time.NewTimer(time.Second * 5)
time.AfterFunc(time.Second, func() {
//该匿名函数的作用就是在1秒后打印结果,并通知main()函数可以结束主goroutine
fmt.Println("one second after,秒:", time.Now().Second())
timer.Reset(time.Second * 2)
})
//多路复用通道
select {
case <-timer.C: //计时器到时了,即2秒已到
fmt.Println(timer.Stop())
fmt.Println("time is over,stop!!秒:", time.Now().Second())
case <-time.After(time.Second * 2): //打点器触发了,说明已隔500毫秒
fmt.Println(timer.Stop())
fmt.Println("已超时;秒:", time.Now().Second())
}