golang package time的用法具体详解

在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍 golang 中有关时间的一些基本用法,我们从 time 的几种 type 来开始介绍。

时间可分为时间点与时间段, golang 也不例外,提供了以下两种基础类型

  1. 时间点(Time)
  2. 时间段(Duration)

除此之外 golang 也提供了以下类型,做一些特定的业务

  1. 时区(Location)
  2. Ticker
  3. Timer(定时器)

我们将按以上顺序来介绍 time 包的使用。

时间点(Time)

我们使用的所有与时间相关的业务都是基于点而延伸的,两点组成一个时间段,大多数应用也都是围绕这些点与面去做逻辑处理。

初始化

go 针对不同的参数类型提供了以下初始化的方式

// func Now() Time
  fmt.Println(time.Now())

  // func Parse(layout, value string) (Time, error)
  time.Parse("2016-01-02 15:04:05", "2018-04-23 12:24:51")

  // func ParseInLocation(layout, value string, loc *Location) (Time, error) (layout已带时区时可直接用Parse)
  time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", time.Local)

  // func Unix(sec int64, nsec int64) Time
  time.Unix(1e9, 0)

  // func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
  time.Date(2018, 1, 2, 15, 30, 10, 0, time.Local)

  // func (t Time) In(loc *Location) Time 当前时间对应指定时区的时间
  loc, _ := time.LoadLocation("America/Los_Angeles")
  fmt.Println(time.Now().In(loc))

  // func (t Time) Local() Time

获取到时间点之后为了满足业务和设计,需要转换成我们需要的格式,也就是所谓的时间格式化。

格式化

to string

格式化为字符串我们需要使用 time.Format 方法来转换成我们想要的格式

fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 2018-04-24 10:11:20
  fmt.Println(time.Now().Format(time.UnixDate))   // Tue Apr 24 09:59:02 CST 2018

Format 函数中可以指定你想使用的格式,同时 time 包中也给了一些我们常用的格式

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

注意: galang 中指定的 特定时间格式 为 "2006-01-02 15:04:05 -0700 MST" , 为了记忆方便,按照美式时间格式 月日时分秒年 外加时区 排列起来依次 是 01/02 03:04:05PM ‘06 -0700 ,刚开始使用时需要注意。

to time stamp

func (t Time) Unix() int64
  func (t Time) UnixNano() int64

  fmt.Println(time.Now().Unix())

  // 获取指定日期的时间戳
  dt, _ := time.Parse("2016-01-02 15:04:05", "2018-04-23 12:24:51")
  fmt.Println(dt.Unix())

  fmt.Println(time.Date(2018, 1,2,15,30,10,0, time.Local).Unix())

其他

time 包还提供了一些常用的方法,基本覆盖了大多数业务,从方法名就能知道代表的含义就不一一说明了。

func (t Time) Date() (year int, month Month, day int)
  func (t Time) Clock() (hour, min, sec 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) YearDay() int
  func (t Time) Weekday() Weekday
  func (t Time) ISOWeek() (year, week int)
  func (t Time) IsZero() bool
  func (t Time) Local() Time
  func (t Time) Location() *Location
  func (t Time) Zone() (name string, offset int)
  func (t Time) Unix() int64

时间段(Duartion)

介绍完了时间点,我们再来介绍时间段,即 Duartion 类型, 我们业务也是很常用的类型。

// func ParseDuration(s string) (Duration, error)
  tp, _ := time.ParseDuration("1.5s")
  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) Nanoseconds() int64
  func (d Duration) Round(m Duration) Duration   // 四舍五入
  func (d Duration) Truncate(m Duration) Duration  // 向下取整

时区(Location)

我们在来介绍一下时区的相关的函数

// 默认UTC
 loc, err := time.LoadLocation("")
 // 服务器设定的时区,一般为CST
 loc, err := time.LoadLocation("Local")
 // 美国洛杉矶PDT
 loc, err := time.LoadLocation("America/Los_Angeles")

 // 获取指定时区的时间点
 local, _ := time.LoadLocation("America/Los_Angeles")
 fmt.Println(time.Date(2018,1,1,12,0,0,0, local))

可以在 $GOROOT/lib/time/zoneinfo.zip 文件下看到所有时区。

时间运算

好了,基础的类型我们介绍完,现在开始时间运算相关的函数,也是日常业务中我们大量应用的。

// func Sleep(d Duration) 休眠多少时间,休眠时处于阻塞状态,后续程序无法执行
  time.Sleep(time.Duration(10) * time.Second)

  // func After(d Duration) <-chan Time 非阻塞,可用于延迟
  time.After(time.Duration(10) * time.Second)

  // func Since(t Time) Duration 两个时间点的间隔
  start := time.Now()
  fmt.Println(time.Since(start)) // 等价于 Now().Sub(t), 可用来计算一段业务的消耗时间

  func Until(t Time) Duration  // 等价于 t.Sub(Now()),t与当前时间的间隔

  // func (t Time) Add(d Duration) Time
  fmt.Println(dt.Add(time.Duration(10) * time.Second)) // 加

  func (t Time) Sub(u Time) Duration     // 减 

  // func (t Time) AddDate(years int, months int, days int) Time
  fmt.Println(dt.AddDate(1, 1, 1))

  // func (t Time) Before(u Time) bool
  // func (t Time) After(u Time) bool
  // func (t Time) Equal(u Time) bool   比较时间点时尽量使用Equal函数

我们大概就介绍完了多数涉及时间点与时间段的函数,接下面我们通过一些使用场景来做一些演示。

使用场景

日期时间差

dt1 := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)
  dt2 := time.Date(2018, 1, 9, 23, 59, 22, 100, time.Local)
  // 不用关注时区,go会转换成时间戳进行计算
  fmt.Println(dt1.Sub(dt2))

基于当前时间的前后运算

now := time.Now()

  // 一年零一个月一天之后
  fmt.Println(now.Date(1,1,1))
  // 一段时间之后
  fmt.Println(now.Add(time.Duration(10)*time.Minute))

  // 计算两个时间点的相差天数
  dt1 = time.Date(dt1.Year(), dt1.Month(), dt1.Day(), 0, 0, 0, 0, time.Local)
  dt2 = time.Date(dt2.Year(), dt2.Month(), dt2.Day(), 0, 0, 0, 0, time.Local)
  fmt.Println(int(math.Ceil(dt1.Sub(dt2).Hours() / 24)))

时区转换

// time.Local 用来表示当前服务器时区
  // 自定义地区时间
  secondsEastOfUTC := int((8 * time.Hour).Seconds())
  beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
  fmt.Println(time.Date(2018,1,2,0,0,0,0, beijing)) // 2018-01-02 00:00:00 +0800 Beijing Time 

  // 当前时间转为指定时区时间
  fmt.Println(time.Now().In(beijing))

  // 指定时间转换成指定时区对应的时间
  dt, err := time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", time.Local)

  // 当前时间在零时区年月日 时分秒 时区
  year, mon, day := time.Now().UTC().Date()  // 2018 April 24
  hour, min, sec := time.Now().UTC().Clock() // 3 47 15
  zone, _ := time.Now().UTC().Zone()   // UTC

比较两个时间点

dt := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)
  fmt.Println(time.Now().After(dt))  // true
  fmt.Println(time.Now().Before(dt)) // false

  // 是否相等 判断两个时间点是否相等时推荐使用 Equal 函数
  fmt.Println(dt.Equal(time.Now()))

设置执行时间

通过 time.After 函数与 select 结合使用可用于处理程序超时设定

select {
  case m := <- c:
   // do something
  case <- time.After(time.Duration(1)*time.Second):
   fmt.Println("time out")
  }

Ticker类型

Ticker 类型包含一个 channel ,有时我们会遇到每隔一段时间执行的业务(比如设置心跳时间等),就可以用它来处理,这是一个 重复的过程

// 无法取消
  tick := time.Tick(1 * time.Minute)
  for _ = range tick {
   // do something
  }

  // 可通过调用ticker.Stop取消
  ticker := time.NewTicker(1 * time.Minute)
  for _ = range tick {
   // do something
  }

Timer类型

Timer 类型用来代表一个单独的事件,当设置的时间过期后,发送当前的时间到 channel , 我们可以通过以下两种方式来创建

func AfterFunc(d Duration, f func()) *Timer // 指定一段时间后指定的函数
  func NewTimer(d Duration) *Timer

以上两函数都可以使用 Reset , 这个有个需要注意的地方是使用 Reset 时需要确保 t.C 通道被释放时才能调用,以防止发生资源竞争的问题,可通过以下方式解决

if !t.Stop() {
   <-t.C
  }
  t.Reset(d)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • golang time包下定时器的实现方法
(0)

相关推荐

  • golang time包下定时器的实现方法

    golang time包 和python一样,golang时间处理还是比较方便的,以下介绍了golang 时间日期,相关包 "time"的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍. 时间戳 当前时间戳 fmt.Println(time.Now().Unix()) # 1389058332 str格式化时间 当前格式化时间 fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 这

  • golang package time的用法具体详解

    在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍 golang 中有关时间的一些基本用法,我们从 time 的几种 type 来开始介绍. 时间可分为时间点与时间段, golang 也不例外,提供了以下两种基础类型 时间点(Time) 时间段(Duration) 除此之外 golang 也提供了以下类型,做一些特定的业务 时区(Location) Ticker Timer(定时器) 我们将按以上顺序来介绍 time 包的使用. 时间点(Time) 我们使用的所有与时间相关的业务都是

  • golang中的三个点 '...'的用法示例详解

    '-' 其实是go的一种语法糖. 它的第一个用法主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数. 第二个用法是slice可以被打散进行传递. 下面直接上例子: func test1(args ...string) { //可以接受任意个string参数 for _, v:= range args{ fmt.Println(v) } } func main(){ var strss= []string{ "qwr", "234", "yui

  • Golang验证器之validator是使用详解

    目录 前言 什么是validator 安装 使用方法 校验规则 跨字段验证 错误处理 小结 前言 对于HTTP请求,我们要在脑子里有一个根深蒂固的概念,那就是任何客户端传过来的数据都是不可信任的.那么开发接口的时候需要对客户端传提交的参数进行参数校验,如果提交的参数只有一个两个,这样我们可以简单写个if判断,那么要是有很多的参数校验,那么满屏都是参数校验的if判断,效率不仅低还不美观,接下来我们介绍一个参数校验器validator. 什么是validator Validator 是一个 Gola

  • Java设计模式之策略模式原理与用法实例详解

    本文实例讲述了Java设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.其中JDK里面的TreeSet类和TreeMap类就用到了策略模式.这两个类是带排序的集合类,其中排序的规则就相当于策略模式里定义的一系列算法,而集合类就相当于是策略模式里的环境类,供用户使用,用只知道TreeSet和TreeMap是带排序的,至于怎么排序的,是由排序的算法决定的. 策略模式

  • Java设计模式之装饰模式原理与用法实例详解

    本文实例讲述了Java设计模式之装饰模式原理与用法.分享给大家供大家参考,具体如下: 装饰模式能在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.JDK中IO的设计就用到了装饰模式,通过过滤流对节点流进行包装来实现功能的扩展. 装饰模式的角色的组成: ① 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加工功能的对象.(InputStream.OutputStream) ② 具体构件(Concrete Co

  • python golang中grpc 使用示例代码详解

    python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件hello.proto // [python quickstart](https://grpc.io/docs/quickstart/python.html#run-a-grpc-application) // python -m grpc_tools.protoc --python_out=. -

  • 基于gin的golang web开发:路由示例详解

    Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的命令安装Gin go get -u github.com/gin-gonic/gin 在代码里添加依赖 import "github.com/gin-gonic/gin" 快速启动一个Gin服务器的代码如下 package main import "github.com/gin-

  • golang类型转换组件Cast的使用详解

    开源地址 https://github.com/spf13/cast Cast是什么? Cast是一个库,以一致和简单的方式在不同的go类型之间转换. Cast提供了简单的函数,可以轻松地将数字转换为字符串,将接口转换为bool类型等等.当一个明显的转换是可能的时,Cast会智能地执行这一操作.它不会试图猜测你的意思,例如,你只能将一个字符串转换为int的字符串表示形式,例如"8".Cast是为Hugo开发的,Hugo是一个使用YAML.TOML或JSON作为元数据的网站引擎. 为什么

  • Golang 标准库 tips之waitgroup详解

    WaitGroup 用于线程同步,很多场景下为了提高并发需要开多个协程执行,但是又需要等待多个协程的结果都返回的情况下才进行后续逻辑处理,这种情况下可以通过 WaitGroup 提供的方法阻塞主线程的执行,直到所有的 goroutine 执行完成. 本文目录结构: WaitGroup 不能被值拷贝 Add 需要在 Wait 之前调用 使用 channel 实现 WaitGroup 的功能 Add 和 Done 数量问题 WaitGroup 和 channel 控制并发数 WaitGroup 和

  • Go语言基础go接口用法示例详解

    目录 概述 语法 定义接口 实现接口 空接口 接口的组合 总结 概述 Go 语言中的接口就是方法签名的集合,接口只有声明,没有实现,不包含变量. 语法 定义接口 type [接口名] interface { 方法名1(参数列表) 返回值列表 方法名2(参数列表) 返回值列表 ... } 例子 type Isay interface{ sayHi() } 实现接口 例子 //定义接口的实现类 type Chinese struct{} //实现接口 func (_ *Chinese) sayHi(

随机推荐