GoLong的学习之路(十四)语法之标准库 time(时间包)的使用

2023-10-28 15:15

本文主要是介绍GoLong的学习之路(十四)语法之标准库 time(时间包)的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • time包
    • 跨时区
    • 时间戳
    • 时间间隔
    • 时间操作
      • add
      • Sub
      • Equal
      • Before
      • After
    • 定时器
    • 时间格式化
    • 解析字符串格式的时间

time包

时间和日期是我们编程中经常会用到的,本文主要介绍了 Go 语言内置的 time 包的基本用法。

  • time 包提供了一些关于时间显示和测量用的函数。
  • time 包中日历的计算采用的是公历,不考虑润秒。

Go 语言中使用time.Time类型表示时间。我们可以通过time.Now函数获取当前的时间对象,然后从时间对象中可以获取到年、月、日、时、分、秒等信息。

// timeDemo 时间对象的年月日时分秒
func timeDemo() {now := time.Now() // 获取当前时间fmt.Printf("current time:%v\n", now)year := now.Year()     // 年month := now.Month()   // 月day := now.Day()       // 日hour := now.Hour()     // 小时minute := now.Minute() // 分钟second := now.Second() // 秒fmt.Println(year, month, day, hour, minute, second)
}

跨时区

Go 语言中使用 location 来映射具体的时区。时区(Time Zone)是根据世界各国家与地区不同的经度而划分的时间定义,全球共分为24个时区。

中国差不多跨5个时区(壮哉我中国,地大物博),为了时区的一致,在国内通常使用的是北京的时区。

下面的示例代码中使用beijing来表示东八区8小时的偏移量,其中time.FixedZone和time.LoadLocation这两个函数则是用来获取location信息。

// timezoneDemo 时区示例
func timezoneDemo() {// 中国没有夏令时,使用一个固定的8小时的UTC时差。// 对于很多其他国家需要考虑夏令时。secondsEastOfUTC := int((8 * time.Hour).Seconds())// FixedZone 返回始终使用给定区域名称和偏移量(UTC 以东秒)的 Location。beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)// 如果当前系统有时区数据库,则可以加载一个位置得到对应的时区// 例如,加载纽约所在的时区newYork, err := time.LoadLocation("America/New_York") // UTC-05:00if err != nil {fmt.Println("load America/New_York location failed", err)return}fmt.Println()// 加载上海所在的时区//shanghai, err := time.LoadLocation("Asia/Shanghai") // UTC+08:00// 加载东京所在的时区//tokyo, err := time.LoadLocation("Asia/Tokyo") // UTC+09:00// 创建时间对象需要指定位置。常用的位置是 time.Local(当地时间) 和 time.UTC(UTC时间)。//timeInLocal := time.Date(2023, 10, 27, 20, 0, 0, 0, time.Local)  // 系统本地时间timeInUTC := time.Date(2023, 10, 27, 12, 0, 0, 0, time.UTC)sameTimeInBeijing := time.Date(2023, 10, 27, 20, 0, 0,  beijing)sameTimeInNewYork := time.Date(2009, 1, 1, 7, 0, 0, 0, newYork)// 北京时间(东八区)比UTC早8小时,所以上面两个时间看似差了8小时,但表示的是同一个时间timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)fmt.Println(timesAreEqual)// 纽约(西五区)比UTC晚5小时,所以上面两个时间看似差了5小时,但表示的是同一个时间timesAreEqual = timeInUTC.Equal(sameTimeInNewYork)fmt.Println(timesAreEqual)
}

注意
由于time.loadLocation 依赖系统的时区数据库,在不确定程序的运行环境的情况下建议先定义时区偏移量,然后使用time.FixedZone 的方式指定时区。

(这个我遇到过,你们敢信,在这个时代,我曾经遇到过一个xp系统的电脑。人还不会配置时间,系统时间就有问题。所以一定不能依赖系统的时区数据库)

时间戳

Unix Time是自1970年1月1日 00:00:00 UTC 至当前时间经过的总秒数。

// timestampDemo 时间戳
func timestampDemo() {now := time.Now()        // 获取当前时间timestamp := now.Unix()  // 秒级时间戳milli := now.UnixMilli() // 毫秒时间戳 Go1.17+micro := now.UnixMicro() // 微秒时间戳 Go1.17+nano := now.UnixNano()   // 纳秒时间戳fmt.Println(timestamp, milli, micro, nano)
}

time 包还提供了一系列将 int64 类型的时间戳转换为时间对象的方法。

这里注意还是得转换一下时区

secondsEastOfUTC := int((8 * time.Hour).Seconds())beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)// 北京时间 2022-02-22 22:22:22.000000022 +0800 CSTt := time.Date(2022, 02, 22, 22, 22, 22, 22, beijing)
var (sec  = t.Unix()msec = t.UnixMilli()usec = t.UnixMicro())// 将秒级时间戳转为时间对象(第二个参数为不足1秒的纳秒数)timeObj := time.Unix(sec, 22)fmt.Println(timeObj)           // 2022-02-22 22:22:22.000000022 +0800 CSTtimeObj = time.UnixMilli(msec) // 毫秒级时间戳转为时间对象fmt.Println(timeObj)           // 2022-02-22 22:22:22 +0800 CSTtimeObj = time.UnixMicro(usec) // 微秒级时间戳转为时间对象fmt.Println(timeObj)           // 2022-02-22 22:22:22 +0800 CST

时间间隔

time.Duration是time包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。

time.Duration表示一段时间间隔,可表示的最长时间段大约290年。

time.Duration表示1纳秒,time.Second表示1秒。

const (Nanosecond  Duration = 1Microsecond          = 1000 * NanosecondMillisecond          = 1000 * MicrosecondSecond               = 1000 * MillisecondMinute               = 60 * SecondHour                 = 60 * Minute
)

源码

在这里插入图片描述

时间操作

add

func (t Time) Add(d Duration) Time
func main() {now := time.Now()later := now.Add(time.Hour) // 当前时间加1小时后的时间fmt.Println(later)
}

Sub

func (t Time) Sub(u Time) Duration

返回一个时间段t-u。

如果结果超出了Duration可以表示的最大值最小值,将返回最大值最小值

要获取时间点t-d(d为Duration),可以使用t.Add(-d)。

Equal

func (t Time) Equal(u Time) bool

判断两个时间是否相同,会考虑时区的影响,因此不同时区标准的时间也可以正确比较。

这个方法和用t==u不同,这种方法还会比较地点和时区信息。

Before

func (t Time) Before(u Time) bool

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

After

func (t Time) After(u Time) bool

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

定时器

使用time.Tick(时间间隔)来设置定时器,定时器的本质上是一个通道(channel)

func tickDemo() {ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器for i := range ticker {fmt.Println(i)//每秒都会执行的任务}
}

时间格式化

time.Format函数能够将一个时间对象格式化输出为指定布局的文本表示形式,需要注意的是 Go 语言中时间格式化的布局不是常见的Y-m-d H:M:S,而是使用2023-10-27 15:04:05.000

  • 如果想格式化为12小时格式,需在格式化布局中添加PM。
  • 小数部分想保留指定位数就写0,如果想省略末尾可能的0就写 9。
// formatDemo 时间格式化
func formatDemo() {now := time.Now()// 格式化的模板为 2006-01-02 15:04:05// 24小时制fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))// 12小时制fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))// 小数点后写0,因为有3个0所以格式化输出的结果也保留3位小数fmt.Println(now.Format("2006/01/02 15:04:05.000")) // 2022/02/27 00:10:42.960// 小数点后写9,会省略末尾可能出现的0fmt.Println(now.Format("2006/01/02 15:04:05.999")) // 2022/02/27 00:10:42.96// 只格式化时分秒部分fmt.Println(now.Format("15:04:05"))// 只格式化日期部分fmt.Println(now.Format("2006.01.02"))
}

在这里插入图片描述

解析字符串格式的时间

对于从文本的时间表示中解析出时间对象,time包中提供了time.Parse和time.ParseInLocation两个函数。

其中time.Parse在解析时不需要额外指定时区信息。

// parseDemo 指定时区解析时间
func parseDemo() {// 在没有时区指示符的情况下,time.Parse 返回UTC时间timeObj, err := time.Parse("2006/01/02 15:04:05", "2022/10/05 11:25:20")if err != nil {fmt.Println(err)return}fmt.Println(timeObj) // 2022-10-05 11:25:20 +0000 UTC// 在有时区指示符的情况下,time.Parse 返回对应时区的时间表示// RFC3339     = "2006-01-02T15:04:05Z07:00"timeObj, err = time.Parse(time.RFC3339, "2023-10-05T11:25:20+08:00")if err != nil {fmt.Println(err)return}fmt.Println(timeObj) // 2022-10-05 11:25:20 +0800 CST
}

在这里插入图片描述

time.ParseInLocation函数需要在解析时额外指定时区信息。

func parseDemo() {now := time.Now()fmt.Println(now)// 加载时区loc, err := time.LoadLocation("Asia/Shanghai")if err != nil {fmt.Println(err)return}// 按照指定时区和指定格式解析字符串时间timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2022/10/05 11:25:20", loc)if err != nil {fmt.Println(err)return}fmt.Println(timeObj)fmt.Println(timeObj.Sub(now))
}

在这里插入图片描述

这篇关于GoLong的学习之路(十四)语法之标准库 time(时间包)的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294086

相关文章

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window