携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
这篇文章主要总结了下 time包的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者开发具有一定的帮助,需要的朋友们可以一起学习下。
前言
在我们开发中,经常会遇到时间戳和日期字符串互转、获取当前时间、时间之间的比较等与时间相关的各种需求,而且golang属于强类型语言,如果类型不对经常遇到问题,很是苦恼,如果我们平时掌握不牢固的话每次都得去查找怎么用,比较浪费时间,下面我来总结下golang中有关时间得一些基本用法。
time包
golang中的时间操作在time包中,时间操作的基础是基于一个Time的结构体,时间相关的操作都需要先转换成Time结构体,再通过Time结构体相关的函数转换成目标值。
时间可分为时间点与时间段,golang提供了以下两种基础类型
- 时间点(Time)
- 时间段(Duration)
时间点(Time)
time.Time类型表示时间。我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息,示例如下:
now := time.Now() //获取当前时间
fmt.Printf("current time:%v\n", now) //current time:2022-07-29 17:37:45.526079 +0800 CST m=+0.000118085
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)//2022-07-29 17:37:45
格式化
获取到时间点之后为了满足业务和设计,需要转化为我们需要的格式,也就是所谓的时间格式化。
格式化我们需要使用time.Format方法来实现。
fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 2022-07-29 18:05:50
fmt.Println(time.Now().Format(time.UnixDate)) // Fri Jul 29 18:05:50 CST 2022
时间戳
时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数,它也被称为Unix时间戳。
unc (t Time) Unix() int64 //时间戳
func (t Time) UnixNano() int64 //纳秒时间戳
fmt.Println(time.Now().Unix()) //获取当前时间时间戳
// 获取指定日期的时间戳
dt, _ := time.Parse("2016-01-02 15:04:05", "2022-07-29 12:24:51")
fmt.Println(dt.Unix())
fmt.Println(time.Date(2022, 7,29,15,30,10,0, time.Local).Unix())
时间段(Duration)
time.Duration是time包定义的一个类型,表示一段时间间隔,以纳秒为单位。定义如下:
const (
Nanosecond Duration = 1 //纳秒
Microsecond = 1000 * Nanosecond //微秒
Millisecond = 1000 * Microsecond //毫秒
Second = 1000 * Millisecond //秒
Minute = 60 * Second //分钟
Hour = 60 * Minute //小时
)
示例代码:
// func ParseDuration(s string)(time.Duration, error)
tp, _ := time.ParseDuration("2.5s")
fmt.Println(tp.Seconds(), tp.Nanoseconds(), tp.Truncate(1000), tp.Round(1000)) //2.5 2500000000 2.5s 2.5s
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 // 向下取整
时间运算
Add
有时候我们可能会遇到时间 + 时间间隔的需求,Go语言的时间对象有提供Add方法如下:
func (t Time) Add(d Duration) Time
示例:
now := time.Now()
fmt.Println(now.Add(time.Duration(10) * time.Second))
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
Before
比较两个时间点谁在前,返回bool型,如果t代表的时间点在u之前,返回真,否则返回假。
func (t Time) Before(u Time) bool
After
比较两个时间点谁在后,返回bool型,如果t代表的时间点在u之后,返回真,否则返回假。
func (t Time) After(u Time) bool
常用获取时间点方法
获取当前时间点
now := time.Now() //获取当前时间
year := now.Year() //年
month := now.Month() //月
day := now.Day() //日
hour := now.Hour() //小时
minute := now.Minute() //分钟
second := now.Second() //秒
week := now.Weekday() //周几
nowTimeStamp := now.Unix()//时间戳
nowTimeStr := now.Format("2006-01-02 15:04:05") //格式化时间
获取某天0点时间
t := time.Now()
//当天0点时间
nowTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
nowTimeStamp := nowTime.Unix()
//第二天0点
towTimeStr := nowTime.AddDate(0, 0, 1) //若要获取3天后的时间,则应将1改为3
towTimeStamp := towTimeStr.Unix()
//昨日0点
nowTime.AddDate(0, 0 ,-1) //若要获取3天前的时间,则应将-1改为-3
//某天的明天0点
nowTimeStr := "2022-02-28"
//使用Parse 默认获取为UTC时区 需要获取本地时区 所以使用ParseInLocation
t2, _ := time.ParseInLocation("2006-01-02", nowTimeStr, time.Local)
towTimeStamp := t2.AddDate(0, 0, 1).Unix()
towTimeStr := time.Unix(towTimeStamp, 0).Format("2006-01-02 15:04:05")
fmt.Println(towTimeStr) // 2022-03-01 00:00:00
//某天的前一天0点整
nowTimeStr := "2022-04-01"
//使用Parse 默认获取为UTC时区 需要获取本地时区 所以使用ParseInLocation
t2, _ := time.ParseInLocation("2006-01-02", nowTimeStr, time.Local)
towTimeStamp := t2.AddDate(0, 0, -1).Unix()
towTimeStr := time.Unix(towTimeStamp, 0).Format("2006-01-02 15:04:05")
fmt.Println(towTimeStr) // 2022-03-31 00:00:00
获取某周的开始和结束时间戳
// 获取某周的开始和结束时间,week为0本周,-1上周,1下周以此类推
func WeekIntervalTime(week int) (startTime, endTime string) {
now := time.Now()
offset := int(time.Monday - now.Weekday())
//周日做特殊判断 因为time.Monday = 0
if offset > 0 {
offset = -6
}
year, month, day := now.Date()
thisWeek := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
startTime = thisWeek.AddDate(0, 0, offset+7*week).Format("2006-01-02") + " 00:00:00"
endTime = thisWeek.AddDate(0, 0, offset+6+7*week).Format("2006-01-02") + " 23:59:59"
return startTime,endTime
}
获取某月的开始或结束时间戳
// 获取某月的开始和结束时间mon为0本月,-1上月,1下月以此类推
func MonthIntervalTime(mon int) (startTime, endTime string) {
year, month, _ := time.Now().Date()
thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
startTime = thisMonth.AddDate(0, mon, 0).Format("2006-01-02") + " 00:00:00"
endTime = thisMonth.AddDate(0, mon+1, -1).Format("2006-01-02") + " 23:59:59"
return startTime,endTime
}
获取本周、上周周一日期
/**
获取本周周一的日期
*/
func GetFirstDateOfWeek() (weekMonday string) {
now := time.Now()
offset := int(time.Monday - now.Weekday())
if offset > 0 {
offset = -6
}
weekStartDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
weekMonday = weekStartDate.Format("2006-01-02")
return
}
/**
获取上周的周一日期
*/
func GetLastWeekFirstDate() (weekMonday string) {
thisWeekMonday := GetFirstDateOfWeek()
TimeMonday, _ := time.Parse("2006-01-02", thisWeekMonday)
lastWeekMonday := TimeMonday.AddDate(0, 0, -7)
weekMonday = lastWeekMonday.Format("2006-01-02")
return
}