Go语言基础time包使用示例详解

1,131 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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
}