Go语言基础之time包
time包
time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。
时间类型
time.Time
类型表示时间。我们可以通过time.Now()
函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 | 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.Printf( "%d-%02d-%02d %02d:%02d:%02d\n" , year, month, day, hour, minute, second) } |
时间戳
时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp)。
基于时间对象获取时间戳的示例代码如下:
1 2 3 4 5 6 7 | func timestampDemo() { now := time.Now() //获取当前时间 timestamp1 := now.Unix() //获取当前时间戳 timestamp2 := now.UnixNano() //回去当前纳秒时间戳 fmt.Printf( "current timestamp1:%v\n" , timestamp1) fmt.Printf( "current timestamp2:%v\n" , timestamp2) } |
使用time.Unix()
函数可以将时间戳转为时间格式。
1 2 3 4 5 6 7 8 9 10 11 | func timestampDemo2(timestamp int64) { timeObj := time.Unix(timestamp, 0) //将时间戳转为时间格式 //Unix第二个参数是纳秒的偏移量 fmt.Println(timeObj) year := timeObj.Year() //年 month := timeObj.Month() //月 day := timeObj.Day() //日 hour := timeObj.Hour() //小时 minute := timeObj.Minute() //分钟 second := timeObj.Second() //秒 fmt.Printf( "%d-%02d-%02d %02d:%02d:%02d\n" , year, month, day, hour, minute, second) } |
时间间隔
time.Duration
是time
包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。time.Duration
表示一段时间间隔,可表示的最长时间段大约290年。
time包中定义的时间间隔类型的常量如下:
1 2 3 4 5 6 7 8 | const ( Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond Millisecond = 1000 * Microsecond Second = 1000 * Millisecond Minute = 60 * Second Hour = 60 * Minute ) |
例如:time.Duration
表示1纳秒,time.Second
表示1秒。
时间操作
Add
我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法如下:
func (t Time) Add(d Duration) Time
举个例子,求一个小时之后的时间:
1 2 3 4 5 | 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之前,返回真;否则返回假。
t < u 返回 true
After
func (t Time) After(u Time) bool
如果t代表的时间点在u之后,返回真;否则返回假。
t > u 返回true
Since
func Since(t Time) Duration
time.SInce(time) 算出传入时间与现在的差值
定时器
使用time.Tick(时间间隔)
来设置定时器,定时器的本质上是一个通道(channel)。
1 2 3 4 5 6 | func tickDemo() { ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器 for i := range ticker { fmt.Println(i) //每秒都会执行的任务 } } |
时间格式化
时间类型有一个自带的方法Format
进行格式化,需要注意的是Go语言中格式化时间模板不是常见的Y-m-d H:M:S
而是使用Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)。也许这就是技术人员的浪漫吧。
补充:如果想格式化为12小时方式,需指定PM
。
1 2 3 4 5 6 7 8 9 10 11 | func formatDemo() { now := time.Now() // 格式化的模板为Go的出生时间2006年1月2号15点04分 Mon Jan // 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" )) fmt.Println(now.Format( "2006/01/02 15:04" )) fmt.Println(now.Format( "15:04 2006/01/02" )) fmt.Println(now.Format( "2006/01/02" )) } |
解析字符串格式的时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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" , "2019/08/04 14:15:20" , loc) if err != nil { fmt.Println(err) return } fmt.Println(timeObj) fmt.Println(timeObj.Sub(now)) |
时间的计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // 获取今天0点0时0分的时间戳 currentTime := time.Now() startTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location()) fmt.Println(startTime) fmt.Println(startTime.Format( "2006/01/02 15:04:05" )) // 获取今天23:59:59秒的时间戳 currentTime := time.Now() endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location()) fmt.Println(endTime) fmt.Println(endTime.Format( "2006/01/02 15:04:05" )) // 获取1分钟之前的时间 m, _ := time.ParseDuration( "-1m" ) result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format( "2006/01/02 15:04:05" )) // 获取1小时之前的时间 m, _ := time.ParseDuration( "-1h" ) result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format( "2006/01/02 15:04:05" )) // 获取1分钟之后的时间 m, _ := time.ParseDuration( "1m" ) result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format( "2006/01/02 15:04:05" )) // 获取1小时之后的时间 m, _ := time.ParseDuration( "1h" ) result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format( "2006/01/02 15:04:05" )) // 计算两个时间戳 afterTime, _ := time.ParseDuration( "1h" ) result := currentTime.Add(afterTime) beforeTime, _ := time.ParseDuration( "-1h" ) result2 := currentTime.Add(beforeTime) m := result.Sub(result2) fmt.Printf( "%v 分钟 \n" , m.Minutes()) h := result.Sub(result2) fmt.Printf( "%v小时 \n" , h.Hours()) d := result.Sub(result2) fmt.Printf( "%v 天\n" , d.Hours()/24) // 判断一个时间是否在一个时间之后 stringTime, _ := time.Parse( "2006-01-02 15:04:05" , "2019-12-12 12:00:00" ) beforeOrAfter := stringTime.After(time.Now()) if true == beforeOrAfter { fmt.Println( "2019-12-12 12:00:00在当前时间之后!" ) } else { fmt.Println( "2019-12-12 12:00:00在当前时间之前!" ) } // 判断一个时间相比另外一个时间过去了多久 startTime := time.Now() time.Sleep(time.Second * 5) fmt.Println( "离现在过去了:" , time.Since(startTime))<br><br> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 定时任务 func startTimer(f func ()) { go func () { for { f() now := time.Now() // 计算下一个零点 next := now.Add(time.Hour * 24) next = time.Date(next.Year(), next.Month(), next.Day(), 0,0,0,0,next.Location()) t := time.NewTimer(next.Sub(now)) <-t.C } }() } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)