Go基础:Go语言能用到的常用时间处理

文章目录

一、时间的基本获取

Go 语言中的日期与时间处理主要通过标准库 time 包实现,它提供了丰富的时间获取、计算、格式化、解析等功能,适用于定时任务、日志记录、时间差计算等场景。

1.1 获取当前时间

使用 time.Now() 可以获取当前本地时间,返回 time.Time 类型。示例代码:

go 复制代码
package main
import (
	"fmt"
	"time"
)
func main() {
	now := time.Now()
	fmt.Println("当前时间:", now)
}

输出:

复制代码
当前时间: 2025-09-09 15:07:56.123456 +0800 CST m=+0.000123456

详细版本:

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	// 获取当前时间
	now := time.Now()
	fmt.Println("当前时间:", now)
	
	// 获取时间的各个部分
	fmt.Println("年:", now.Year())
	fmt.Println("月:", now.Month())
	fmt.Println("日:", now.Day())
	fmt.Println("时:", now.Hour())
	fmt.Println("分:", now.Minute())
	fmt.Println("秒:", now.Second())
	fmt.Println("纳秒:", now.Nanosecond())
	fmt.Println("星期:", now.Weekday())
	
	// 时间戳(自1970-01-01 00:00:00 UTC以来的秒数)
	fmt.Println("时间戳(秒):", now.Unix())
	fmt.Println("时间戳(纳秒):", now.UnixNano())
	
	// 从时间戳创建时间
	timestamp := now.Unix()
	t := time.Unix(timestamp, 0)
	fmt.Println("从时间戳恢复的时间:", t)
}

执行结果如下:

go 复制代码
当前时间: 2025-09-25 19:26:41.588584 +0800 CST m=+0.000068543
年: 2025
月: September
日: 25
时: 19
分: 26
秒: 41
纳秒: 588584000
星期: Thursday
时间戳(秒): 1758799601
时间戳(纳秒): 1758799601588584000
从时间戳恢复的时间: 2025-09-25 19:26:41 +0800 CST

1.2 时间的格式化与解析

Go 语言使用特定的参考时间Mon Jan 2 15:04:05 MST 2006作为格式化模板。

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	
	// 格式化时间
	fmt.Println("标准格式:", now.Format(time.RFC3339))
	fmt.Println("自定义格式1:", now.Format("2006-01-02 15:04:05"))
	fmt.Println("自定义格式2:", now.Format("2006年01月02日 15时04分05秒"))
	fmt.Println("简短格式:", now.Format("06/01/02 15:04"))
	
	// 解析字符串为时间
	timeStr := "2023-10-05 14:30:00"
	t, err := time.Parse("2006-01-02 15:04:05", timeStr)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("解析后的时间:", t)
	}
	
	// 带时区的解析
	timeStr2 := "2023-10-05T14:30:00+08:00"
	t2, err := time.Parse(time.RFC3339, timeStr2)
	if err != nil {
		fmt.Println("解析错误:", err)
	} else {
		fmt.Println("带时区的时间:", t2)
	}
}

执行结果如下:

go 复制代码
标准格式: 2025-09-25T19:28:00+08:00
自定义格式1: 2025-09-25 19:28:00
自定义格式2: 2025年09月25日 19时28分00秒
简短格式: 25/09/25 19:28
解析后的时间: 2023-10-05 14:30:00 +0000 UTC
带时区的时间: 2023-10-05 14:30:00 +0800 CST

二、时区处理

2.1 加载时区

使用 time.LoadLocation() 加载指定时区。示例代码:

go 复制代码
func main() {
	loc, err := time.LoadLocation("America/New_York")
	if err != nil {
		fmt.Println("加载时区失败:", err)
		return
	}
	now := time.Now()
	fmt.Println("本地时间:", now)
	fmt.Println("纽约时间:", now.In(loc))
}

2.2 固定时区时间

使用 time.FixedZone() 创建固定偏移量的时区。示例代码:

go 复制代码
func main() {
	loc := time.FixedZone("UTC+8", 8*3600)
	now := time.Now()
	fmt.Println("UTC+8 时间:", now.In(loc))
}

2.3 详细版本代码

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println("本地时间:", now)
	fmt.Println("UTC时间:", now.UTC())
	
	// 加载特定时区
	loc, err := time.LoadLocation("America/New_York")
	if err != nil {
		fmt.Println("加载时区错误:", err)
		return
	}
	
	// 转换到纽约时间
	nyTime := now.In(loc)
	fmt.Println("纽约时间:", nyTime.Format("2006-01-02 15:04:05"))
	
	// 转换到东京时间
	loc, err = time.LoadLocation("Asia/Tokyo")
	if err != nil {
		fmt.Println("加载时区错误:", err)
		return
	}
	tokyoTime := now.In(loc)
	fmt.Println("东京时间:", tokyoTime.Format("2006-01-02 15:04:05"))
	
	// 使用固定偏移创建时区(如UTC+8)
	beijingLoc := time.FixedZone("CST", 8*3600)
	beijingTime := now.In(beijingLoc)
	fmt.Println("北京时间:", beijingTime.Format("2006-01-02 15:04:05"))
}

执行结果如下:

go 复制代码
本地时间: 2025-09-25 19:29:15.049073 +0800 CST m=+0.000072959
UTC时间: 2025-09-25 11:29:15.049073 +0000 UTC
纽约时间: 2025-09-25 07:29:15
东京时间: 2025-09-25 20:29:15
北京时间: 2025-09-25 19:29:15

三、时间计算与比较

3.1 时间加减

使用 Add()AddDate() 方法进行时间加减。示例代码:

go 复制代码
func main() {
	now := time.Now()
	fmt.Println("当前时间:", now)
	// 加 1 小时
	later := now.Add(time.Hour)
	fmt.Println("加 1 小时:", later)
	// 加 1 天
	tomorrow := now.AddDate(0, 0, 1)
	fmt.Println("加 1 天:", tomorrow)
}

3.2 时间差计算

使用 Sub() 方法计算两个时间之间的差值,返回 time.Duration 类型。示例代码:

go 复制代码
func main() {
	start := time.Now()
	time.Sleep(2 * time.Second)
	end := time.Now()
	duration := end.Sub(start)
	fmt.Println("时间差:", duration)
	fmt.Println("秒数:", duration.Seconds())
}

综合案例:

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	fmt.Println("当前时间:", now.Format("2006-01-02 15:04:05"))
	
	// 时间加法
	tomorrow := now.Add(24 * time.Hour)
	fmt.Println("明天此时:", tomorrow.Format("2006-01-02 15:04:05"))
	
	nextWeek := now.AddDate(0, 0, 7)
	fmt.Println("下周此时:", nextWeek.Format("2006-01-02 15:04:05"))
	
	// 时间减法
	lastHour := now.Add(-1 * time.Hour)
	fmt.Println("一小时前:", lastHour.Format("2006-01-02 15:04:05"))
	
	// 计算时间差
	diff := now.Sub(lastHour)
	fmt.Println("时间差:", diff.Hours(), "小时")
	
	// 时间比较
	if now.After(tomorrow) {
		fmt.Println("now 在 tomorrow 之后")
	} else {
		fmt.Println("now 在 tomorrow 之前")
	}
	
	if now.Before(lastHour) {
		fmt.Println("now 在 lastHour 之前")
	} else {
		fmt.Println("now 在 lastHour 之后")
	}
	
	// 检查两个时间是否相同
	if now.Equal(now) {
		fmt.Println("时间相同")
	}
	
	// 计算两个日期之间的天数差
	date1 := time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)
	date2 := time.Date(2023, time.December, 31, 0, 0, 0, 0, time.UTC)
	days := int(date2.Sub(date1).Hours() / 24)
	fmt.Println("2023年天数:", days)
}

执行结果如下:

go 复制代码
当前时间: 2025-09-25 19:31:17
明天此时: 2025-09-26 19:31:17
下周此时: 2025-10-02 19:31:17
一小时前: 2025-09-25 18:31:17
时间差: 1 小时
now 在 tomorrow 之前
now 在 lastHour 之后
时间相同
2023年天数: 364

四、定时器与 Ticker

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	// 定时器: 延迟执行一次
	timer := time.NewTimer(2 * time.Second)
	fmt.Println("等待2秒...")
	<-timer.C
	fmt.Println("2秒后执行")
	
	// 立即触发定时器
	timer2 := time.NewTimer(5 * time.Second)
	go func() {
		<-timer2.C
		fmt.Println("timer2 触发")
	}()
	stop2 := timer2.Stop()
	if stop2 {
		fmt.Println("timer2 已停止")
	}
	
	// Ticker: 周期性执行
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()
	
	done := make(chan bool)
	go func() {
		time.Sleep(5 * time.Second)
		done <- true
	}()
	
	fmt.Println("开始每秒输出(持续5秒):")
	for {
		select {
		case <-done:
			fmt.Println("完成")
			return
		case t := <-ticker.C:
			fmt.Println("当前时间:", t.Format("15:04:05"))
		}
	}
}

执行结果如下:

go 复制代码
等待2秒...
2秒后执行
timer2 已停止
开始每秒输出(持续5秒):
当前时间: 19:36:23
当前时间: 19:36:24
当前时间: 19:36:25
当前时间: 19:36:26
当前时间: 19:36:27
完成

五、实用时间工具函数

go 复制代码
package main

import (
	"fmt"
	"time"
)

// 格式化时间为友好显示(如: 3分钟前, 2小时前, 3天前)
func TimeAgo(t time.Time) string {
	now := time.Now()
	diff := now.Sub(t)
	
	switch {
	case diff < time.Minute:
		return fmt.Sprintf("%d秒前", int(diff.Seconds()))
	case diff < time.Hour:
		return fmt.Sprintf("%d分钟前", int(diff.Minutes()))
	case diff < 24*time.Hour:
		return fmt.Sprintf("%d小时前", int(diff.Hours()))
	case diff < 7*24*time.Hour:
		return fmt.Sprintf("%d天前", int(diff.Hours()/24))
	default:
		return t.Format("2006-01-02")
	}
}

// 获取指定日期所在周的周一
func GetMondayOfWeek(t time.Time) time.Time {
	weekday := t.Weekday()
	offset := (int(weekday) - 1 + 7) % 7
	return t.AddDate(0, 0, -offset)
}

// 获取当月第一天
func GetFirstDayOfMonth(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location())
}

// 获取当月最后一天
func GetLastDayOfMonth(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location())
}

func main() {
	// 测试TimeAgo函数
	now := time.Now()
	fmt.Println("刚刚:", TimeAgo(now))
	fmt.Println("30秒前:", TimeAgo(now.Add(-30*time.Second)))
	fmt.Println("2小时前:", TimeAgo(now.Add(-2*time.Hour)))
	fmt.Println("3天前:", TimeAgo(now.Add(-3*24*time.Hour)))
	
	// 测试周一周函数
	monday := GetMondayOfWeek(now)
	fmt.Println("本周一:", monday.Format("2006-01-02"))
	
	// 测试月份第一天和最后一天
	firstDay := GetFirstDayOfMonth(now)
	lastDay := GetLastDayOfMonth(now)
	fmt.Println("本月第一天:", firstDay.Format("2006-01-02"))
	fmt.Println("本月最后一天:", lastDay.Format("2006-01-02"))
}

执行结果如下:

go 复制代码
刚刚: 0秒前
30秒前: 30秒前
2小时前: 2小时前
3天前: 3天前
本周一: 2025-09-22
本月第一天: 2025-09-01
本月最后一天: 2025-09-30

总结:Go 语言的 time 包功能强大,支持时间的获取、计算、格式化、解析、时区处理等操作。

相关推荐
苏三说技术5 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
长栎6 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端
用户559822481226 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode6 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战6 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha6 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn6 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端
用户762352425916 小时前
ShardingJDBC
后端
行者全栈架构师6 小时前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端