现在的位置: 首页 > 编程语言 > 正文

Go中的Location、Ticker、time操作

2020年02月25日 编程语言 ⁄ 共 1978字 ⁄ 字号 评论关闭

  Go 中的时间最底层的数据结构为 Duration , 在 Duration 的基础上,我们定义了下面的概念:

  const (

  Nanosecond Duration = 1 // 纳秒,计算Duration的是使用ns

  Microsecond = 1000 * Nanosecond 微秒,计算Duration的是使用us

  Millisecond = 1000 * Microsecond 毫秒, 计算Duration的是使用ms

  Second = 1000 * Millisecond 秒,计算Duration的是使用s

  Minute = 60 * Second 分,计算Duration的是使用m

  Hour = 60 * Minute 时,计算Duration的是使用h

  )

  那么 Duration 可以如何操作呢?

  time.Duration

  seconds := 10

  time.Duration(seconds)*time.Second // 返回Duration结构

  time.ParseDuration ParseDutation 主要用于解析字符串,使用字符串的可以避免使用 time.Duration 不方便表示的时间段。

  hours, _ := time.ParseDuration("10h") // 生成10个小时的duration

  complex, _ := time.ParseDuration("1h10m10s") // 生成1小时10分钟10秒的duration

  micro, _ := time.ParseDuration("1µs") // 生成1微妙的duration

  time.Sub

  如何计算两个时间的时间差,返回 Duration 结构?注意:

  start := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)

  end := time.Date(2000, 1, 1, 12, 0, 0, 0, time.UTC)

  difference := end.Sub(start)

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

  time.Since

  time.Since 等价于 time.Now().Sub(t) ,用于计算当前时间和之前某个时间的时间差。

  time.Until

  time.Until 等价于 t.Sub(time.Now()) ,用于计算之后的某个时间和当前时间的时间差。

  那么 Duration 到底是什么数据结构呢? Duration 只是 int64 的一种昵称,在此之上也实现多种方法,如 .Hours() , .Minutes() , .Seconds() 等。

  type Duration int64

  Location

  一般情况不需要设置 Location ,如果要设置 location ,能够在哪些地方使用呢? 首先是在 time.Date 构造 time.Time 的过程中,最后一个参数设置当前时间所在时区。

  Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location)

  那么 time.Location 如何初始化呢?使用 time.LoadLocation 来加载。

  location, err := time.LoadLocation("America/Los_Angeles")

  timeInUTC := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC) // time.UTC是*Location结构

  带时区的时间转化,

  t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) // 当前时间为UTC时间

  fmt.Printf("Go launched at %s\n", t.Local()) // t.Local转化本地时间, 2009-11-11 07:00:00 +0800 CST。

  东八区怎么表示呢?

  // 方法一

  l,_ := time.LoadLocation("Asia/Shanghai")

  // 方法二,可能用的不多,定义一个名字,然后自行计算时区+-12 * 3600

  var cstZone = time.FixedZone("CST", 8*3600) // 东八

  fmt.Println(time.Now().In(cstZone).Format("01-02-2006 15:04:05"))

  为什么是乘3600呢?从秒开始计算,下面两行得到北京时区。

  secondsEastOfUTC := int((8 * time.Hour).Seconds())

  beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)

  Ticker

  type Ticker struct {

  C <-chan Time // channel 每隔固定的时间会发送消息   }   每隔固定的时间会发送信号,这个固定时间怎么获取呢?通过NewTicker接收Duration对象获取,下面代码演示了每个1秒打印,打印10秒的功能。   ticker := time.NewTicker(time.Second)   defer ticker.Stop() // 【重要】关闭ticker   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)   }   }   Time

  Time 是操纵时间的核心对象。

  time.Parse,time.ParseInLocation

  time.Parse(layout, string) // 获取指定字符串代表的时间

  time.ParseInLocation(layout, value string, loc *Location) // 带上时区的时间

  今天开发中遇到一个问题,计算两个时间相差多少秒?

  todayEnd, _ := time.Parse(timeLayout, fmt.Sprintf("%s %s", time.Now().Format("2006-01-02"), "23:59:59"))

  todayStart := time.Now()

  validSeds := todayEnd.Sub(todayStart).Minutes()

  fmt.Println("validSeds: ", int(validSeds))

  上面的代码计算时间一直不正确,就是因为 time.Parse 获取出来的时间是相对0时区的,而 time.Now 使用的是本地时区,需要将其中 Parse 出的代码修为下面形式:

  l, _ := time.LoadLocation("Asia/Shanghai")

  todayEnd, _ := time.ParseInLocation(timeLayout, fmt.Sprintf("%s %s", time.Now().Format("2006-01-02"), "23:59:59"), l)

  time.Unix, time.UnixNano

  计算当前的时间戳

  time.Unix() // 秒级 time.UnixNano() // 毫秒级

  time.Add

  增加一个 Duration 。

  time.AddDate

  play

  start := time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)

  oneDayLater := start.AddDate(0, 0, 1) // 增加一天

  oneMonthLater := start.AddDate(0, 1, 0) // 增加一月

  oneYearLater := start.AddDate(1, 0, 0) // 增加一年

  不过 AddDate 都可以使用 Add + Duraion 组合解决。

  t.After,t.Before

  比较两个时间的先后

  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

  isYear2000AfterYear3000 := year2000.After(year3000) // False

  isYear3000BeforeYear2000 := year3000.Before(year2000) // false

  isYear2000BeforeYear3000 := year2000.Before(year3000) // true

  t.Date, t.Clock

  func (t Time) Clock() (hour, min, sec int) // 返回t的时分秒

  func (t Time) Date() (year int, month Month, day int) // 返回t的年月日

  t.Format 时间格式化显示。

  t.In 通过复制的方式,改变当前时间的时区。

  func (t Time) In(loc *Location) Time

  t.IsZero

  声明 time.Time 未赋值,改值为 January 1, year 1, 00:00:00 UTC.

  t.Local, t.UTC

  分别使用本地时区生成时间, 0时区生成时间。

  t.Zone()

  返回当前时区的名称和偏移0时区多少秒。

  t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.Local)

  name, offset := t.Zone()

  fmt.Println(name, offset) // CST 28800(8*3600)

  Timer

  Timer 是个什么东西?最基本还是个channel。

  type Timer struct {

  C <-chan Time // 时间到了,发送信号,做好接收准备   }   怎么初始化 Timer 呢?

  func NewTimer(d Duration) *Timer

  时间到了,要执行什么函数呢?

  func AfterFunc(d Duration, f func()) *Timer

  中途如果想着 stop 定时器,怎么办?

  func (t *Timer) Stop() bool

  为了确保关闭?

  if !t.Stop() {

  <-t.C   }   Month、Weekday   两个封装的方式相同,使用昵称的方式挂载更多的方法,是变量能够存在更多的可能性。   // Month   type Month int   const (   January Month = 1 + iota   February   March   April   May   June   July   August   September   October   November   December   )   func (m Month) String() string{}   // Weekday   type Weekday int   const (   Sunday Weekday = iota   Monday   Tuesday   Wednesday   Thursday   Friday   Saturday   )   func (d Weekday) String() string   以上内容就是有关Go中的time操作的相关介绍,如果要了解更多go语言以及time操作知识,请关注学步园。

抱歉!评论已关闭.