time包中包括两类时间:时间点(某一时刻)和时长(某一段时间)的基本操作。

time

基本结构

Time

type Time struct {
    wall uint64
    ext  int64
    loc *Location
}
  • wall 秒
  • ext 纳秒
  • loc *Location
    • time.UTC utc时间
    • time.Local 本地时间
    • FixedZone(name string, offset int) *Location 设置时区名,以及与UTC0的时间偏差.返回Location

Duration

type Duration int64

Duration类型代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约290年。

时间常量

Duration的单位为 nanosecond,为了便于使用,time中定义了时间常量:

const (
    Nanosecond Duration = 1
    Microsecond = 1000 * Nanosecond
    Millisecond = 1000 * Microsecond
    Second = 1000 * Millisecond
    Minute = 60 * Second
    Hour = 60 * Minute
)

Ticker

type Ticker
type Ticker struct {
    C <-chan Time // 周期性传递时间信息的通道
    // 内含隐藏或非导出字段
}

Ticker保管一个通道,并每隔一段时间向其传递”tick”。

func NewTicker
func NewTicker(d Duration) *Ticker

NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。

func (*Ticker) Stop
func (t *Ticker) Stop()

Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。

总结

  • time.Duration(时长,耗时)
  • time.Time(时间点)
  • time.C(放时间点的管道)[ Time.C:=make(chan time.Time) ]

基本函数

time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。

func Now
func Now() Time

Now返回当前本地时间。

func (Time) Before
func (t Time) Before(u Time) bool

如果t代表的时间点在u之前,返回真;否则返回假。

func (Time) Add
func (t Time) Add(d Duration) Time

Add返回时间点t+d。

func (Time) Second
func (t Time) Second() int

返回t对应的那一分钟的第几秒,范围[0, 59]。

常规使用

sleep

golang的休眠可以使用time包中的sleep。

函数原型为:

func Sleep(d Duration)

下面实现休眠2秒功能。

package main

import (
    "fmt"
    "time"
)

func main() {

    fmt.Println("begin")
    time.Sleep(time.Duration(2)*time.Second)
    fmt.Println("end")
}

time使用变量的时候需要强制转换

time.Duration(cfg.CTimeOut) * time.Second

定时器

定时器只会传达一次到期事件,

type Timer struct {
    C <-chan Time
    r runtimeTimer
}

每天定时0点执行

import (
    "time"
    "fmt"
)

//定时结算Boottime表数据
func BoottimeTimingSettlement() {
    for {
        now := time.Now()
        // 计算下一个零点
        next := now.Add(time.Hour * 24)
        next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location())
        t := time.NewTimer(next.Sub(now))
        <-t.C
        Printf("定时结算Boottime表数据,结算完成: %v\n",time.Now())
        //以下为定时执行的操作
        BoottimeSettlement()
    }
}

断续器

周期性的传达到期事件的装置,定时器只会传达一次到期事件,断续器会持续工作直到停止。

type Ticker struct {
    C <-chan Time // The channel on which the ticks are delivered.
    r runtimeTimer
}

初始化

func NewTicker(d Duration) *Ticker

NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。

ticker := time.NewTicker(time.Millisecond * 500)
go func() {
    for t := range ticker.C {
        fmt.Println("Tick at", t)
    }
}()

time.Sleep(time.Millisecond * 1500)   //阻塞,则执行次数为sleep的休眠时间/ticker的时间
ticker.Stop()    
fmt.Println("Ticker stopped")

获取时间

各种现有时间的获取

func main() {
    fmt.Printf("时间戳(秒):%v;\n", time.Now().Unix())
    fmt.Printf("时间戳(纳秒):%v;\n",time.Now().UnixNano())
    fmt.Printf("时间戳(毫秒):%v;\n",time.Now().UnixNano() / 1e6)
    fmt.Printf("时间戳(纳秒转换为秒):%v;\n",time.Now().UnixNano() / 1e9)
}


时间戳(秒):1530027865;
时间戳(纳秒):1530027865231834600;
时间戳(毫秒):1530027865231;
时间戳(纳秒转换为秒):1530027865;

时间转化

处理时间单位自动转化问题

func ParseDuration(s string) (Duration, error)

传入字符串,返回响应的时间,其中传入的字符串中的有效时间单位如下:h,m,s,ms,us,ns,其他单位均无效,如果传入无效时间单位,则会返回0

获取前n天的时间

//获取两天前的时间
currentTime := time.Now()
oldTime := currentTime.AddDate(0, 0, -2)        //若要获取3天前的时间,则应将-2改为-3
//oldTime 的结果为go的时间time类型,2018-09-25 13:24:58.287714118 +0000 UTC

比较时间,使用before

time1 := "2015-03-20 08:50:29"
time2 := "2015-03-21 09:04:25"
//先把时间字符串格式化成相同的时间类型
t1, err := time.Parse("2006-01-02 15:04:05", time1)
t2, err := time.Parse("2006-01-02 15:04:05", time2)
if err == nil && t1.Before(t2) {
    //处理逻辑
    fmt.Println("true")
}

获取文件的各种时间

func main() {
    finfo, _ := os.Stat(filename)
    // Sys()返回的是interface{},所以需要类型断言,不同平台需要的类型不一样,linux上为*syscall.Stat_t
    stat_t := finfo.Sys().(*syscall.Stat_t)
    fmt.Println(stat_t)
    // atime,ctime,mtime分别是访问时间,创建时间和修改时间,具体参见man 2 stat
    fmt.Println(timespecToTime(stat_t.Atim))
    fmt.Println(timespecToTime(stat_t.Ctim))
    fmt.Println(timespecToTime(stat_t.Mtim))
}