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

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

除此之外 golang 也提供了以下类型,做一些特定的业务
- 时区(Location)
- Ticker
- Timer(定时器)

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

时间点(Time)

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

初始化

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

      // func Now() Timefmt.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) Timetime.Unix(1e9, 0)// func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Timetime.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:20fmt.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 zoneRFC850      = "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 zoneRFC3339     = "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() int64func (t Time) UnixNano() int64fmt.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() intfunc (t Time) Month() Monthfunc (t Time) Day() intfunc (t Time) Hour() intfunc (t Time) Minute() intfunc (t Time) Second() intfunc (t Time) Nanosecond() intfunc (t Time) YearDay() intfunc (t Time) Weekday() Weekdayfunc (t Time) ISOWeek() (year, week int)func (t Time) IsZero() boolfunc (t Time) Local() Timefunc (t Time) Location() *Locationfunc (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() float64func (d Duration) Minutes() float64func (d Duration) Seconds() float64func (d Duration) Nanoseconds() int64func (d Duration) Round(m Duration) Duration         // 四舍五入func (d Duration) Truncate(m Duration) Duration      // 向下取整

时区(Location)

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

    // 默认UTC    loc, err := time.LoadLocation("") // 服务器设定的时区,一般为CSTloc, err := time.LoadLocation("Local")// 美国洛杉矶PDTloc, 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) Timefmt.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) Timefmt.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 15zone, _ := time.Now().UTC().Zone()            // UTC

比较两个时间点

      dt := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)fmt.Println(time.Now().After(dt))     // truefmt.Println(time.Now().Before(dt))    // false// 是否相等 判断两个时间点是否相等时推荐使用 Equal 函数fmt.Println(dt.Equal(time.Now()))

设置执行时间

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

      select {case m := <- c:// do somethingcase <- 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)

参考文献

package time

golang积累-时间、时区、格式的使用

论golang Timer Reset方法使用的正确姿势

golang包time用法详解相关推荐

  1. 图像处理中媲美matlab的python包——scikit-image(skimage)包的用法详解

    前言: 基于python的图片处理包还是很多的,比如PIL,Pillow, opencv, scikit-image等.其中,PIL和Pillow只提供最基础的数字图像处理,功能有限:opencv本质 ...

  2. java jar包详解_Jar打包用法详解

    这篇文章主要介绍了Jar打包用法,详解分析了jar打包命令的各种常见用法及参数含义,非常具有实用价值,需要的朋友可以参考下 本文较为详细的分析了Jar打包的用法.分享给大家供大家参考.具体分析如下: ...

  3. python解包什么意思_python解包用法详解

    对于一堆资料,我们可以把它分给不同的人使用,这个分散的过程,我们可以看成是解包方法是实现.当然实际python解包的使用会相对复杂一点,我们会对常见的列表.函数等进行操作.下面我们就Python解包的 ...

  4. Oracle之DBMS_SQL包用法详解

    Oracle之DBMS_SQL包用法详解 原文  http://zhangzhongjie.iteye.com/blog/1948093 通常运用 DBMS_SQL 包一般分为 如下 几步: 1. o ...

  5. npm命令--安装依赖包--用法/详解

    原文网址:npm命令--安装依赖包--用法/详解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍npm如何安装依赖包. 用法 命令 作用 详述 npm install <pkg> //同 ...

  6. java string()函数_转载java String.split()函数的用法详解

    转载java String.split()函数的用法详解 如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!在java.lang包中有String.split()方法的原型是: p ...

  7. linux为什么用tar压缩,linux下tar压缩和解压命令用法详解

    linux下tar压缩和解压命令用法详解 2017-03-25 14:06 分享人:老牛 将/usr/local/test目录下所有文件仅打包,不压缩到 /usr/local/auto_bak/目下 ...

  8. csh for循环_shell中的for循环用法详解_linux shell

    这篇文章主要介绍了shell中的for循环用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 for 命令: for i i ...

  9. spring boot模板引擎thymleaf用法详解

    spring boot模板引擎thymleaf用法详解 Spring-boot支持FreeMarker.Thymeleaf.jsp.veocity 但是对freemarker和thymeleaf的支持 ...

最新文章

  1. 本周阅读清单:从NeurIPS 2020到EMNLP 2020
  2. 第二十六节(对象流,File类)
  3. linux开机引导过程总览
  4. 小米登录协议分析_小米温湿度传感器协议分析
  5. 中台到底是什么?传统企业怎样建设中台?
  6. java8与hibernate_如何在JPA和Hibernate中使用Java 8 LocalDateTime
  7. python 的内置方法zip()介绍
  8. java. base关键字_C#基础知识之base关键字介绍
  9. Python-nmap 使用文档
  10. 高等数学(第七版)同济大学 习题7-5 个人解答
  11. 微信小程序调出选择好友聊天窗口
  12. 因为计算机丢失d3dx10,Win7打开剑灵游戏提示丢失d3dx10_43.dll怎么解决
  13. c语言上届报告,51单片机摇摇棒制作资料,包含c代码PCB原理图与设计报告
  14. VMware安装流畅系统Chrome OS以及国产系统FedyOS(基于Chrome OS的二次开发)
  15. 诚邀参加“低噪声飞秒激光”( 上海交大)研讨会
  16. DB2下将16进制转为十进制
  17. 污水计算机仿真技术,活性污泥法污水处理计算机仿真软件的开发及应用
  18. 汽车4S店业务管理软件
  19. java正则包含特殊字符_java – 捕获由特殊字符嵌套/包含的正则表达式组
  20. 字符串处理:输入字符串s1和s2以及插入位置f,在字符串s1中的指定位置f处插入字符串s2。如输入BEIJING, 123, 3,则输出:BEI123JING。

热门文章

  1. 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV
  2. python怎么合成音乐_Python合成音乐
  3. vue项目JS播放音频音效和背景音乐
  4. Kotlin插件 kotlin-android-extensions
  5. bigsur cdr文件_macOS BigSur 11.0.1(20B29)-原版DMG黑苹果镜像
  6. 电路中的输入与输出电阻计算
  7. Vue进阶(幺零二):面试必备:2023 Vue经典面试题整理(含答案)
  8. C#access数据库查询操作(二)
  9. 内弹道仿真matlab全代码
  10. ubuntu 16.04 使用五笔拼音输入法