【Golang】日期与时间


阅读目录

一、Time

二、常用时间总结

三、定时器

一、Time

//时间类型
func testTime(){
	now := time.Now()
	fmt.Println(now)
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
}

//时间戳
func testTimestamp(){
	now := time.Now()
	timestamp1 := now.Unix()        //时间戳
	timestamp2 := now.UnixNano()    //纳秒时间戳
	fmt.Printf("current timestamp1:%v\n", timestamp1)
	fmt.Printf("current timestamp2:%v\n", timestamp2)
}

//时间转换
func testTimeTransform(){
	timestamp := time.Now().Unix()  //时间戳
	//时间戳转时间类型
	unix := time.Unix(timestamp, 0)
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", unix.Year(), unix.Month(), unix.Day(), unix.Hour(), unix.Minute(), unix.Second())
}

//时间操作
func testTimeOperate(){
	//add
	now := time.Now()
	newTime := now.Add(time.Hour)
	fmt.Println(newTime)

	//sub
	newTimeDuration := newTime.Sub(now)
	//返回一个时间区
	fmt.Println(newTimeDuration)
}

//时间格式化
func testTimeFormatAndParse(){
	now := time.Now()
	// 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"))

	//默认UTC时间
	//t, _ := time.Parse("2006-01-02 15:04:05", "2020-05-07 09:14:00")
	t, _ := time.ParseInLocation("2006-01-02 15:04:05", "2020-05-07 10:30:52", time.Local)

	fmt.Println(t)
	fmt.Println(time.Now().Sub(t).Hours())
}

//时区
func testTimezone(){
	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", "2020/05/07 10:31:20", loc)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(timeObj)
	fmt.Println(timeObj.Sub(now))
}

//对于 json,使用的是 time.RFC3339Nano 这种格式。通常程序中不使用这种格式。解决办法是定义自己的类型。
type oftenTime time.Time

func(o oftenTime) MarshalJSON() ([]byte, error) {
	t := time.Time(o)
	//判断类型
	if y := t.Year(); y < 0 || y >= 10000 {
		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
	}
	//JSON,双引号不能少
	return []byte(t.Format(`"2006-01-02 15:04:05"`)), nil
}

func testTimeJson(){
	o := oftenTime(time.Now())
	bytes, e := json.Marshal(o)
	fmt.Println(string(bytes), e)
}

//获取当前时间整点的 Time 实例
func testRoundAndTruncate(){
	fmt.Println(time.Now().Truncate(1 * time.Hour))
	fmt.Println(time.Now().Round(1 * time.Hour))

	t, _ := time.ParseInLocation("2006-01-02 15:04:05", "2020-05-08 10:30:52", time.Local)
	// 整点(向下取整)
	fmt.Println(t.Truncate(1 * time.Hour))
	// 整点(最接近)
	fmt.Println(t.Round(1 * time.Hour))

	// 整分(向下取整)
	fmt.Println(t.Truncate(1 * time.Minute))
	// 整分(最接近)
	fmt.Println(t.Round(1 * time.Minute))

	t2, _ := time.ParseInLocation("2006-01-02 15:04:05", t.Format("2006-01-02 15:00:00"), time.Local)
	fmt.Println(t2)
}

二、常用时间总结

//获取每月第一天
func GetFirstDateOfMonth(t time.Time) time.Time {
	t = t.AddDate(0, 0, -t.Day() + 1)
	return GetZeroTime(t)
}

func GetLastDateOfMonth(t time.Time) time.Time {
	return GetFirstDateOfMonth(t).AddDate(0, 1, -1)
}

//获取某一天的0点时间
func GetZeroTime(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
//获取是周几
func GetWeekDay(t time.Time) int {
	year, month, day  := t.Year(), int(t.Month()), t.Day()
	var weekday = [7]int{7, 1, 2, 3, 4, 5, 6}
	var y, m , c int
	if month >= 3 {
		m = month
		y = year % 100
		c = year / 100
	} else {
		m = month + 12
		y = (year - 1) % 100
		c = (year - 1) / 100
	}
	week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
	if week < 0 {
		week = 7 - (-week)%7
	} else {
		week = week % 7
	}
	return weekday[week]
}

//获取本周周日的日期
func GetLastDateOfWeek(t time.Time, fmtStr string) (dayStr string) {
	dayObj := GetZeroTime(t)
	if t.Weekday() == time.Sunday{
		dayStr = dayObj.Format(fmtStr)
	}else{
		dayStr = dayObj.AddDate(0, 0, 7-int(t.Weekday())).Format(fmtStr)
	}
	return
}

//获取本周周一的日期
func GetFirstDateOfWeek(t time.Time, fmtStr string) (dayStr string) {
	dayObj := GetZeroTime(t)
	if t.Weekday() == time.Monday {
		//修改hour、min、sec = 0后格式化
		dayStr = dayObj.Format(fmtStr)
	}else{
		offset := int(time.Monday - t.Weekday())
		if offset > 0 {
			offset = -6
		}
		dayStr = dayObj.AddDate(0, 0, offset).Format(fmtStr)
	}
	return
}

//获取上周周一日期
func GetLastWeekFirstDate(t time.Time, fmtStr string) (day string, err error) {
	monday := GetFirstDateOfWeek(t, fmtStr)
	dayObj, err := time.Parse(fmtStr, monday)
	if err != nil{
		return
	}
	day = dayObj.AddDate(0, 0, -7).Format(fmtStr)
	return
}
//获取上周最后一天
func GetLastWeekLastDate(t time.Time, fmtStr string) (day string, err error) {
	sunday := GetFirstDateOfWeek(t, fmtStr)
	dayObj, err := time.Parse(fmtStr, sunday)
	if err != nil{
		return
	}
	day = dayObj.AddDate(0, 0, -1).Format(fmtStr)
	return
}

三、定时器

1.Timer

//通过 time.After 模拟超时
func testTimerAfter(){
	c := make(chan int)

	go func() {
		//time.Sleep(1 * time.Second)
		time.Sleep(3 * time.Second)
		<-c
	}()

	select {
	case c <- 1:
		fmt.Println("channel...")
	case <-time.After(2 * time.Second):   //阻塞两秒钟
		close(c)
		fmt.Println("timeout...")
	}
}

//time.Stop 停止定时器 或 time.Reset 重置定时器
func testTimerReset(){
	start := time.Now()
	timer := time.AfterFunc(2*time.Second, func() {
		fmt.Println("after func callback, elaspe:", time.Now().Sub(start))
	})
	//time.Sleep(1 * time.Second)
	time.Sleep(3*time.Second)
	// Reset 在 Timer 还未触发时返回 true;触发了或 Stop 了,返回 false
	// Reset 会先调用 stopTimer 再调用 startTimer,类似于废弃之前的定时器,重新启动一个定时器。返回值和 Stop 一样。
	if timer.Reset(3 * time.Second) {
		fmt.Println("timer has not trigger!")
	} else {
		fmt.Println("timer had expired or stop!")
	}
	time.Sleep(10 * time.Second)
}

2.Tick

func testTickDemo() {
        //定义一个1秒间隔的定时器
	ticker := time.Tick(time.Second) 
	for i := range ticker {
		fmt.Println(i)
	}
}

3.定时器的实际应用

  • github.com/jasonlvhit/gocron
  • github.com/robfig/cron
posted @ 2020-09-20 09:57  初遇ぃ  阅读(305)  评论(0编辑  收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中 //一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中