golang time包之实用攻略

1,385 阅读6分钟

引言

  • 写文章的初衷是因为学习到了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
    2020101611: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())
	}