【Go语言学习系列16】标准库探索(三):时间与日期

Go语言标准库:时间与日期处理

📚 原创系列: “Go语言学习系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Go技术文章。

📑 Go语言学习系列导航

本文是【Go语言学习系列】的第16篇,当前位于第二阶段(基础巩固篇)

🚀 第二阶段:基础巩固篇
  1. 13-包管理深入理解
  2. 14-标准库探索(一):io与文件操作
  3. 15-标准库探索(二):字符串处理
  4. 16-标准库探索(三):时间与日期 👈 当前位置
  5. 17-标准库探索(四):JSON处理
  6. 18-标准库探索(五):HTTP客户端
  7. 19-标准库探索(六):HTTP服务器
  8. 20-单元测试基础
  9. 21-基准测试与性能剖析入门
  10. 22-反射机制基础
  11. 23-Go中的面向对象编程
  12. 24-函数式编程在Go中的应用
  13. 25-context包详解
  14. 26-依赖注入与控制反转
  15. 27-第二阶段项目实战:RESTful API服务

📚 查看完整Go语言学习系列导航

📖 文章导读

在本文中,您将了解:

  • Go语言time包的核心概念与设计理念
  • 时间的表示、格式化与解析方法
  • 日期计算、时区处理与时间比较
  • 定时器和计时器的使用技巧
  • 高效处理时间相关操作的最佳实践

几乎所有应用程序都需要处理时间:记录日志、计算时间差、实现定时任务、处理用户输入的日期等。本文将带您全面了解如何在Go中高效处理时间相关操作。


标准库探索(三):时间与日期

1. 时间的表示

在Go中,时间通过time.Time类型表示,这是一个包含日期和时间信息的结构体。

1.1 获取当前时间

import (
    "fmt"
    "time"
)

func main() {
   
   
    // 获取当前本地时间
    now := time.Now()
    fmt.Println("当前时间:", now)
    
    // 获取UTC时间(协调世界时)
    utcNow := time.Now().UTC()
    fmt.Println("UTC时间:", utcNow)
}

输出示例:

当前时间: 2023-05-20 15:30:45.123456789 +0800 CST
UTC时间: 2023-05-20 07:30:45.123456789 +0000 UTC

1.2 创建特定时间

// 使用time.Date创建特定时间
birthDay := time.Date(1990, time.May, 15, 12, 30, 0, 0, time.Local)
fmt.Println("生日:", birthDay)

// 参数依次为:年、月、日、时、分、秒、纳秒、时区
deadline := time.Date(2023, time.December, 31, 23, 59, 59, 0, time.UTC)
fmt.Println("截止日期:", deadline)

1.3 时间组成部分的获取

now := time.Now()

// 获取日期部分
year := now.Year()       // 年份,如2023
month := now.Month()     // 月份,如time.May
day := now.Day()         // 日,如20
weekday := now.Weekday() // 星期几,如time.Saturday

// 获取时间部分
hour := now.Hour()       // 小时,如15
minute := now.Minute()   // 分钟,如30
second := now.Second()   // 秒,如45
nano := now.Nanosecond() // 纳秒,如123456789

fmt.Printf("日期: %d年%d月%d日 %s\n", year, month, day, weekday)
fmt.Printf("时间: %02d:%02d:%02d.%09d\n", hour, minute, second, nano)

1.4 Unix时间戳

Unix时间戳表示从1970年1月1日UTC零点至今的秒数或纳秒数:

now := time.Now()

// 获取Unix时间戳(秒)
unixTime := now.Unix()
fmt.Println("Unix时间戳(秒):", unixTime)

// 获取Unix时间戳(毫秒)
unixMilli := now.UnixMilli()
fmt.Println("Unix时间戳(毫秒):", unixMilli)

// 获取Unix时间戳(纳秒)
unixNano := now.UnixNano()
fmt.Println("Unix时间戳(纳秒):", unixNano)

// 从Unix时间戳创建time.Time
timestamp := int64(1621500000)
timeFromUnix := time.Unix(timestamp, 0)
fmt.Println("从时间戳创建时间:", timeFromUnix)

2. 时间的格式化与解析

Go语言的时间格式化与其他语言有很大不同。Go使用一个特定的参考时间(2006-01-02 15:04:05)作为格式化模板,而不是像许多语言使用的YYYY-MM-DD这样的格式字符串。

2.1 时间格式化

now := time.Now()

// 基本格式化
fmt.Println(now.Format("2006-01-02 15:04:05"))       // 2023-05-20 15:30:45
fmt.Println(now.Format("2006/01/02 15:04"))          // 2023/05/20 15:30
fmt.Println(now.Format("15:04:05"))                  // 15:30:45
fmt.Println(now.Format("2006年01月02日"))              // 2023年05月20日

// 包含星期和时区
fmt.Println(now.Format("2006-01-02 15:04:05 Monday MST")) // 2023-05-20 15:30:45 Saturday CST

// 使用预定义的常量
fmt.Println(now.Format(time.RFC3339))     // 2023-05-20T15:30:45+08:00
fmt.Println(now.Format(time.RFC822))      // 20 May 23 15:30 CST
fmt.Println(now.Format(time.Kitchen))     // 3:30PM

参考时间说明:

  • 2006: 四位数年份
  • 01: 两位数月份(01-12)
  • 02: 两位数日期(01-31)
  • 15: 两位数小时(24小时制,00-23)
  • 04: 两位数分钟(00-59)
  • 05: 两位数秒(00-59)
  • Monday: 星期几的英文表示
  • MST: 时区的缩写

这些数字并不是随机选择的,它们按照美国的日期表示方式排列:月/日/年 时:分:秒,即01/02/2006 15:04:05。这个日期是2006年1月2日下午3点4分5秒,记忆方法是01/02 03:04:05PM '06

2.2 时间解析

// 基本时间解析
timeStr := "2023-05-20 15:30:45"
t, err := time.Parse("2006-01-02 15:04:05", timeStr)
if err != nil {
   
   
    fmt.Println("解析错误:", err)
} else {
   
   
    fmt.Println("解析结果:", t)
}

// 带时区的解析
timeWithZone := "2023-05-20T15:30:45+08:00"
t, err = time.Parse(time.RFC3339, timeWithZone)
if err != nil {
   
   
    fmt.Println("解析错误:", err)
} else {
   
   
    fmt.Println("解析结果:", t)
}

// 在当前位置的时区解析(默认解析为UTC)
localTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2023-05-20 15:30:45", time.Local)
if err != nil {
   
   
    fmt.Println("解析错误:", err)
} else {
   
   
    fmt.Println("本地解析结果:", localTime)
}

需要注意的是,time.Parse默认将解析后的时间视为UTC时间。如果你想将字符串解析为本地时间,应该使用time.ParseInLocation

2.3 常见格式化与解析错误

  1. 错误的格式化占位符
// 错误:使用YYYY-MM-DD这样的格式
wrongFormat := now.Format("YYYY-MM-DD") // 这将输出"YYYY-MM-DD"而不是预期的年月日

// 正确:使用2006-01-02
correctFormat := now.Format("2006-01-02") // 输出如"2023-05-20"
  1. 解析时未考虑时区
// 解析没有明确时区信息的时间字符串
t, _ := time.Parse("2006-01-02 15:04:05", "2023-05-20 15:30:45")
fmt.Println(t) // 默认为UTC时间

// 如果要解析为本地时间,应使用ParseInLocation
t, _ = time.ParseInLocation("2006-01-02 15:04:05", "2023-05-20 15:30:45", time.Local)
fmt.Println(t) // 使用本地时区

3. 时间操作和计算

3.1

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值