Go - Time

一、Time

1-1 time.Format() - 时间格式化

package main

import (
	"fmt"
	"time"
)

func main() {
	now_time := time.Now()
	fmt.Println(now_time) //2020-03-09 14:48:06.238256 +0800 CST m=+0.000109584
	//相当于Ymd
	fmt.Println(now_time.Format("20060102")) // 20200309
	//相当于Y-m-d
	fmt.Println(now_time.Format("2006-01-02")) // 2020-03-09
	//相当于Y-m-d H:i:s
	fmt.Println(now_time.Format("2006-01-02 15:04:05")) // 2020-03-09 14:48:06
	//相当于Y-m-d 00:00:00
	fmt.Println(now_time.Format("2006-01-02 00:00:00")) // 2020-03-09 00:00:00
}

1-1-1 内置 format 常量格式

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"
)
package main

import (
	"fmt"
	"time"
)

func main() {
	now_time := time.Now()
	fmt.Println(now_time) 
  //2020-03-09 14:48:06.238256 +0800 CST m=+0.000109584
	fmt.Println(now_time.Format(time.RFC3339)) 
  // 2020-03-24T15:09:54+08:00
}

1-2 time.sub() - 获取时间差

package main

import (
	"fmt"
	"time"
)

func expensiveCall() {}

func main() {
	t0 := time.Now()
	expensiveCall()
	t1 := time.Now()
	fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
}
//  t1.Sub(t0) == t1-t0
  • Func Since(t Time) Duration == time.Now().Sub(t)
  • Func Untill(t Time) Duration == t.Sub(time.Now())

1-3 time.Parse() - String 转 Time

func Parse(layout, value string) (Time, error)
package main

import (
	"fmt"
	"time"
)

func main() {
	resFormat := "2006-01-02 15:04:05"
	nowTime := time.Now().Format(resFormat)
	res, err := time.Parse(resFormat, nowTime)
	fmt.Println(res, "---------", err)
	//	2020-03-25 14:20:47 +0000 UTC --------- 
}

1-4 Add Time

1-4-1 func (Time) Add - 更细粒度的时间相加返回

func (t Time) Add(d Duration) Time

Add returns the time t+d.

注意:返回 time.Time 类型

package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
	fmt.Printf("start = %v\n", start)
	
	afterTenSeconds := start.Add(time.Second * 10)
	fmt.Printf("start.Add(time.Second * 10) = %v\n", afterTenSeconds)
	
	afterTenMinutes := start.Add(time.Minute * 10)
	fmt.Printf("start.Add(time.Minute * 10) = %v\n", afterTenMinutes)
	
	afterTenHours := start.Add(time.Hour * 10)
	fmt.Printf("start.Add(time.Hour * 10) = %v\n", afterTenHours)
	
	afterTenDays := start.Add(time.Hour * 24 * 10)
	fmt.Printf("start.Add(time.Hour * 24 * 10) = %v\n", afterTenDays)
	

}
/*
start = 2009-01-01 12:00:00 +0000 UTC
start.Add(time.Second * 10) = 2009-01-01 12:00:10 +0000 UTC
start.Add(time.Minute * 10) = 2009-01-01 12:10:00 +0000 UTC
start.Add(time.Hour * 10) = 2009-01-01 22:00:00 +0000 UTC
start.Add(time.Hour * 24 * 10) = 2009-01-11 12:00:00 +0000 UTC
*/

1-4-2 func (Time) AddDate - 返回简单的时间相加

func (t Time) AddDate(years int, months int, days int) Time
package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
	oneDayLater := start.AddDate(0, 0, 1)
	fmt.Printf("oneDayLater: start.AddDate(0, 0, 1) = %v\n", oneDayLater)
	
	oneMonthLater := start.AddDate(0, 1, 0)
	fmt.Printf("oneMonthLater: start.AddDate(0, 1, 0) = %v\n", oneMonthLater)
	
	oneYearLater := start.AddDate(1, 0, 0)
	fmt.Printf("oneYearLater: start.AddDate(1, 0, 0) = %v\n", oneYearLater)
}

/*
oneDayLater: start.AddDate(0, 0, 1) = 2009-01-02 00:00:00 +0000 UTC
oneMonthLater: start.AddDate(0, 1, 0) = 2009-02-01 00:00:00 +0000 UTC
oneYearLater: start.AddDate(1, 0, 0) = 2010-01-01 00:00:00 +0000 UTC
*/

1-5 func(Time) After - 判断时间 a 是否在 b 之后

func (t Time) After(u Time) bool
package main

import (
	"fmt"
	"time"
)

func main() {
	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)

	isYear3000AfterYear2000 := year3000.After(year2000) // True
  	fmt.Printf("year3000.After(year2000) = %v\n", isYear3000AfterYear2000)

	isYear2000AfterYear3000 := year2000.After(year3000) // False
	fmt.Printf("year2000.After(year3000) = %v\n", isYear2000AfterYear3000)
}

1-6 func (Time) Before - 判断时间 a 是否在 b之前

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

import (
	"fmt"
	"time"
)

func main() {
	year2000 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
	year3000 := time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)

	isYear2000BeforeYear3000 := year2000.Before(year3000) // True
	isYear3000BeforeYear2000 := year3000.Before(year2000) // False

	fmt.Printf("year2000.Before(year3000) = %v\n", isYear2000BeforeYear3000)
	fmt.Printf("year3000.Before(year2000) = %v\n", isYear3000BeforeYear2000)

}

1-7 获取 Time 内单属性

  • func (t Time) Clock() (hour, min, sec int)
  • func (t Time) Date() (year int, month Month, day int)
  • func (t Time) Year() int
  • func (t Time) Month() Month
  • func (t Time) Day() int
  • func (t Time) Hour() int
  • func (t Time) Minute() int
  • func (t Time) Second() int
  • func (t Time) Nanosecond() int
  • func (t Time) Local() Time
  • func (t Time) Location() *Location
  • func (t Time) Weekday() Weekday
package main

import (
	"fmt"
	"time"
)

func main() {
	d := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
	year, month, day := d.Date()
	hour, min, sec := d.Clock()
	
	dyear := d.Year()
	dday := d.Day()
	dhour := d.Hour()
	dlocal := d.Local()
	dlocation := d.Location()
  dweekday := d.Weekday()
	
	fmt.Printf("year = %v\n", year)
	fmt.Printf("month = %v\n", month)
	fmt.Printf("day = %v\n", day)
	
	fmt.Printf("hour = %v\n", hour)
	fmt.Printf("min = %v\n", min)
	fmt.Printf("sec = %v\n", sec)
	
	fmt.Printf("dyear = %v\n", dyear)
	fmt.Printf("dday = %v\n", dday)
	fmt.Printf("dhour = %v\n", dhour)
	fmt.Printf("dlocal = %v\n", dlocal)
	fmt.Printf("dlocation = %v\n", dlocation)
  fmt.Printf("dweekday = %v\n", dweekday)
}

1-8 func (Time) Unix - 获取时间戳

Unix 返回 t 作为 Unix 时间,从1970年1月1日UTC开始经过的秒数。这个结果并不依赖于与t相关的位置。类unix操作系统通常将时间记录为32位的秒数,但是由于这里的方法返回64位的值,所以它在数十亿年的时间内都是有效的。

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println(now.Unix()) // 1585120235
	fmt.Println(now.UnixNano()) // 1585120235502442000
}

1-9 func (t Time) Format - 两个时间是否相等

t 和 u 是否在同一时刻相等。即使在不同的位置,也是相等的。

例如,6:00 +0200 和 4:00 UTC 是相等的。

package main

import (
	"fmt"
	"time"
)

func main() {
	secondsEastOfUTC := int((8 * time.Hour).Seconds())
	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)

	// Unlike the equal operator, Equal is aware that d1 and d2 are the
	// same instant but in different time zones.
	d1 := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
	d2 := time.Date(2000, 2, 1, 20, 30, 0, 0, beijing)

	datesEqualUsingEqualOperator := d1 == d2 // false
	datesEqualUsingFunction := d1.Equal(d2) // true

	fmt.Printf("datesEqualUsingEqualOperator = %v\n", datesEqualUsingEqualOperator)
	fmt.Printf("datesEqualUsingFunction = %v\n", datesEqualUsingFunction)

}

1-10 func (Time) ISOWeek - 判断时间是否为0值

func (t Time) ISOWeek() (year, week int)

ISOWeek 返回发生 t 的 ISO 8601年和周数。一周从1到53。
n 年1月1日至1月3日可能属于 n-1 年的第52周或第53周,12月29日至12月31日可能属于n+1年的第1周。

即,返回年份和属于该年的第几周。

package main

import (
	"fmt"
	"time"
)

func main() {
	d:= time.Now()
	fmt.Println(d.ISOWeek()) // 2020 13
}

1-11 func (Time) String - Time 转 String

func (t Time) String() string
package main

import (
	"fmt"
	"time"
)

func main() {
	timeWithNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 15, time.UTC)
	withNanoseconds := timeWithNanoseconds.String()

	timeWithoutNanoseconds := time.Date(2000, 2, 1, 12, 13, 14, 0, time.UTC)
	withoutNanoseconds := timeWithoutNanoseconds.String()

	fmt.Printf("withNanoseconds = %v\n", string(withNanoseconds))
	fmt.Printf("withoutNanoseconds = %v\n", string(withoutNanoseconds))

}

1-12 其他不常用函数

1-12-1 func (Time) Round

func (t Time) Round(d Duration) Time

Round返回将t四舍五入到d的最近倍数的结果(因为时间为零)。中间值的舍入行为是向上舍入。如果d <= 0,则圆形返回t,去掉任何单调的时钟读数,但其他方面不变。

Round以时间作为自零时起的绝对持续时间;它不以时间的呈现形式进行操作。因此,根据时间的位置,Round(小时)可能返回一个非零分钟的时间。

1-12-2 func (Time) Truncate

func (t Time) Truncate(d Duration) Time

Truncate返回将t舍入为d的倍数的结果(因为时间为0)。如果d <= 0, Truncate返回t,去掉任何单调的时钟读数,但其他方面不变。

Truncate将时间作为从0开始的绝对持续时间;它不以时间的呈现形式进行操作。因此,根据时间的位置,Truncate(Hour)可能返回一个非零分钟的时间。

二、Location 时区

Location 提供了两种实例,Local、UTC

var Local *Location = &localLoc // 使用本地系统时间
var UTC *Location = &utcLoc // 使用 UTC 时间
package main

import (
	"fmt"
	"time"
)

func main() {
	// China doesn't have daylight saving. It uses a fixed 8 hour offset from UTC.
	secondsEastOfUTC := int((8 * time.Hour).Seconds())
	beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)

	// If the system has a timezone database present, it's possible to load a location
	// from that, e.g.:
	//    newYork, err := time.LoadLocation("America/New_York")

	// Creating a time requires a location. Common locations are time.Local and time.UTC.
	timeInUTC := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
	sameTimeInBeijing := time.Date(2009, 1, 1, 20, 0, 0, 0, beijing)

	// Although the UTC clock time is 1200 and the Beijing clock time is 2000, Beijing is
	// 8 hours ahead so the two dates actually represent the same instant.
	timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)
	fmt.Println(timesAreEqual)

}

2-1 Func FixedZone - 自定义名和偏移量修改时区

func FixedZone(name string, offset int) *Location

FixedZone returns a Location that always uses the given zone name and offset (seconds east of UTC).

注意:偏移量的单位为 s

package main

import (
	"fmt"
	"time"
)

func main() {
	loc := time.FixedZone("UTC-8", -8*60*60)
	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, loc)
	fmt.Println("The time is:", t.Format(time.RFC822))
}
// The time is: 10 Nov 09 23:00 UTC-8

2-2 Func LoadLocation - 获取指定时区名的时间

func LoadLocation(name string) (*Location, error)

LoadLocation 根据指定时区名,查询 IANA Time Zone database,返回对应时间。

  • 如果 name == “” or “UTC”,则默认返回 UTC 时区时间。
  • 如果 name == “local”,返回当前系统时间

Time Zone database 路径:$GOROOT/lib/time/zoneinfo.zip

package main

import (
	"fmt"
	"time"
)

func main() {
	location, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		panic(err)
	}

	timeInUTC := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
	fmt.Println(timeInUTC)
	fmt.Println(timeInUTC.In(location))
	
}
// 转换使用的时区
/*
2018-08-30 12:00:00 +0000 UTC
2018-08-30 20:00:00 +0800 CST
*/

三、Duration

持续时间.定义了以下持续时间类型.多用于时间的加减 需要传入Duration做为参数的时候

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

3-1 time.ParseDuration - 字符串转 Duration

func ParseDuration(s string) (Duration, error)
package main

import (
	"fmt"
	"time"
)

func main() {
	hours, _ := time.ParseDuration("10h")
	complex, _ := time.ParseDuration("1h10m10s")
	micro, _ := time.ParseDuration("1µs")
	// The package also accepts the incorrect but common prefix u for micro.
	micro2, _ := time.ParseDuration("1us")

	fmt.Println(hours)
	fmt.Println(complex)
	fmt.Printf("There are %.0f seconds in %v.\n", complex.Seconds(), complex)
	fmt.Printf("There are %d nanoseconds in %v.\n", micro.Nanoseconds(), micro)
	fmt.Printf("There are %6.2e seconds in %v.\n", micro2.Seconds(), micro)
}

3-1-1 单位换算

package main

import (
	"fmt"
	"time"
)

func main() {
	pd, _ := time.ParseDuration("4h30m")
	fmt.Println(pd)
	fmt.Println(pd.Hours())
	fmt.Println(pd.Minutes())
	fmt.Println(pd.Seconds())
	fmt.Println(pd.Milliseconds())
	fmt.Println(pd.Microseconds())
	fmt.Println(pd.Nanoseconds())
}

/*
4h30m0s
4.5
270
16200
16200000
16200000000
16200000000000
*/

3-2 func(Duration)String - time 转 string

package main

import (
	"fmt"
	"time"
	"reflect"
)

func main() {
	t1 := time.Date(2016, time.August, 15, 0, 0, 0, 0, time.UTC)
	t2 := time.Date(2017, time.February, 16, 0, 0, 0, 0, time.UTC)
	str_t := t2.Sub(t1).String()
	fmt.Println(reflect.TypeOf(t2.Sub(t1)))
	fmt.Println(str_t)
}
/*
time.Duration
4440h0m0s
*/

四、Ticker & Timer - 定时器

4-1 Ticker - 循环执行

指定时间段将数据放入 channel,即刻开始计时,固定时间触发。

type Ticker struct {
    C <-chan Time 
  	// The channel on which the ticks are delivered.
    // contains filtered or unexported fields
}
  • *func NewTicker(d Duration) Ticker
  • *func (t Ticker) Stop()
package main

import (
	"fmt"
	"time"
)

func main() {
	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)
		}
	}
}
/*
Current time:  2020-03-26 09:47:27.147979 +0800 CST m=+1.000889801
Current time:  2020-03-26 09:47:28.147958 +0800 CST m=+2.000868911
Current time:  2020-03-26 09:47:29.147934 +0800 CST m=+3.000845823
Current time:  2020-03-26 09:47:30.147973 +0800 CST m=+4.000884768
Current time:  2020-03-26 09:47:31.147917 +0800 CST m=+5.000829367
Current time:  2020-03-26 09:47:32.147923 +0800 CST m=+6.000835699
Current time:  2020-03-26 09:47:33.147955 +0800 CST m=+7.000867899
Current time:  2020-03-26 09:47:34.147997 +0800 CST m=+8.000910410
Current time:  2020-03-26 09:47:35.147934 +0800 CST m=+9.000848587
Current time:  2020-03-26 09:47:36.147921 +0800 CST m=+10.000835152
Done!
*/

4-2 Timer - 定时执行

Timer 代表一个信号事件,如果 Timer 超时,当前时间将发送给 channel ,除非 Timer 被 AfterFunc 创建。一个 Timer 必须通过 NewTimer 或者 AfterFunc 被创建。

type Timer struct {
    C <-chan Time
    // contains filtered or unexported fields
}

4-2-1 AfterFunc - 滞后执行函数

func AfterFunc(d Duration, f func()) *Timer
  • 等待 Duration 使用内部的 Goroutine 调用 Func
  • 返回 Timer,能被用来取消 Stop 方法的调用。
package main

import (
    "fmt"
    "time"
)

func main() {
    done := make(chan struct{}) // 用来等待协程结束
		
  	// 3s 后执行
    go time.AfterFunc(time.Second*3, func() {
        fmt.Println("Print after 3 seconds")
        done <- struct{}{} // 通知主协程结束
    })

    fmt.Println("Print in main")

    <-done
    close(done)
}

4-2-2 NewTimer - 滞后发送自身 C 字段

func NewTimer(d Duration) *Timer
  • 在最新的 Duration 后,将当前时间放入 Channel
  • 返回 Timer
package main

import (
	"fmt"
	"time"
)

func main() {
	done := make(chan struct{}) // 用来等待协程结束

	timer := time.NewTimer(time.Second * 3)

	go func() {
		fmt.Printf("Now is %s\n", <-timer.C)
		done <- struct{}{}
	}()

	fmt.Println("Print in main")

	<-done
	close(done)
}
/*
Print in main
Now is 2020-03-26 15:15:25.1683 +0800 CST m=+3.004355427
*/

4-2-3 Reset - 重置状态等待执行

func (t *Timer) Reset(d Duration) bool
  • 在 Duration 之后重置 Timer 定时执行
  • True - Timer 启动成功;False - Timer 超时或停止
package main

import (
	"fmt"
	"time"
)

func main() {

	timer1 := time.NewTimer(2 * time.Second)
	fmt.Printf("Timer 1 fired at %s\n", <-timer1.C)
	timer1.Reset(3*time.Second)
	fmt.Printf("Timer 1 fired at %s\n", <-timer1.C)
}
/*
Timer 1 fired at 2020-03-26 15:25:32.814457 +0800 CST m=+2.000371001
Timer 1 fired at 2020-03-26 15:25:35.817389 +0800 CST m=+5.003280755
*/

4-2-4 Stop

func (t *Timer) Stop() bool
  • It returns true if the call stops the timer, false if the timer has already expired or been stopped.
  • Stop 不会关闭 Channel,为了保护读操作的正常进行

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Printf("Now at %s\n", time.Now())
	timer1 := time.NewTimer(2 * time.Second)
	fmt.Printf("Timer 1 fired at %s\n", <-timer1.C)
	timer2 := time.NewTimer(time.Second)
	go func() {
		fmt.Printf("Timer 2 fired at %s\n", <-timer2.C)
	}()
	stop2 := timer2.Stop()
	if stop2 {
		fmt.Println("Timer 2 stopped")
	}

	time.Sleep(2 * time.Second)
}
/*
Now at 2020-03-26 15:29:00.633902 +0800 CST m=+0.000117930
Timer 1 fired at 2020-03-26 15:29:02.634157 +0800 CST m=+2.000358265
Timer 2 stopped
*/

参考学习

golang - time doc

Go by Example: Timers

你可能感兴趣的:(Go)