Golang时间戳转换完整教程
掌握Go语言time包处理Unix时间戳的所有技巧,包含获取、转换、格式化和时区处理的详细代码示例。
获取当前时间戳
使用time包获取当前Unix时间戳
Go
package main
import (
"fmt"
"time"
)
func main() {
// 获取当前时间戳(秒级)
timestamp := time.Now().Unix()
fmt.Println(timestamp) // 1735660800
// 获取当前时间戳(毫秒级)
timestampMs := time.Now().UnixMilli()
fmt.Println(timestampMs) // 1735660800000
// 获取当前时间戳(微秒级)
timestampUs := time.Now().UnixMicro()
fmt.Println(timestampUs) // 1735660800000000
// 获取当前时间戳(纳秒级)
timestampNs := time.Now().UnixNano()
fmt.Println(timestampNs) // 1735660800000000000
}时间戳转日期
将Unix时间戳转换为Time对象或格式化字符串
Go
package main
import (
"fmt"
"time"
)
func main() {
// 时间戳转Time对象
timestamp := int64(1735660800)
t := time.Unix(timestamp, 0) // 第二参数是纳秒
// 格式化输出
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2025-01-01 00:00:00
fmt.Println(t.Format("2006/01/02")) // 2025/01/01
fmt.Println(t.Format("15:04:05")) // 00:00:00
fmt.Println(t.Format("2006年01月02日 15时04分05秒")) // 2025年01月01日 00时00分00秒
// 毫秒时间戳转换
timestampMs := int64(1735660800000)
tMs := time.UnixMilli(timestampMs)
fmt.Println(tMs.Format("2006-01-02 15:04:05.000"))
// 获取各个时间字段
fmt.Printf("年: %d\n", t.Year())
fmt.Printf("月: %d\n", t.Month())
fmt.Printf("日: %d\n", t.Day())
fmt.Printf("时: %d\n", t.Hour())
fmt.Printf("分: %d\n", t.Minute())
fmt.Printf("秒: %d\n", t.Second())
}日期转时间戳
将日期字符串或Time对象转换为Unix时间戳
Go
package main
import (
"fmt"
"time"
)
func main() {
// 创建指定日期的Time对象
t := time.Date(2025, 1, 1, 0, 0, 0, 0, time.Local)
timestamp := t.Unix()
fmt.Println(timestamp) // 1735660800
// 解析日期字符串
layout := "2006-01-02 15:04:05"
t2, err := time.Parse(layout, "2025-01-01 00:00:00")
if err != nil {
panic(err)
}
fmt.Println(t2.Unix())
// 解析带时区的日期字符串
t3, err := time.Parse(time.RFC3339, "2025-01-01T00:00:00+08:00")
if err != nil {
panic(err)
}
fmt.Println(t3.Unix())
// 使用ParseInLocation解析本地时间
loc, _ := time.LoadLocation("Asia/Shanghai")
t4, err := time.ParseInLocation("2006-01-02 15:04:05", "2025-01-01 00:00:00", loc)
if err != nil {
panic(err)
}
fmt.Println(t4.Unix())
}日期格式化
将日期格式化为各种显示格式(注意Go的特殊格式化方式)
Go
package main
import (
"fmt"
"time"
)
func main() {
t := time.Unix(1735660800, 0)
// Go使用参考时间: 2006-01-02 15:04:05
// 2006 = 年, 01 = 月, 02 = 日
// 15 = 时(24小时制), 04 = 分, 05 = 秒
// 常用格式
fmt.Println(t.Format("2006-01-02")) // 2025-01-01
fmt.Println(t.Format("2006/01/02 15:04:05")) // 2025/01/01 00:00:00
fmt.Println(t.Format("2006-01-02T15:04:05Z07:00")) // ISO 8601
fmt.Println(t.Format("Jan 02, 2006")) // Jan 01, 2025
fmt.Println(t.Format("Monday, January 02, 2006")) // Wednesday, January 01, 2025
// 时间戳格式化(毫秒)
fmt.Println(t.Format("2006-01-02 15:04:05.000"))
// 预定义格式
fmt.Println(t.Format(time.RFC3339)) // 2025-01-01T00:00:00Z
fmt.Println(t.Format(time.RFC1123)) // Wed, 01 Jan 2025 00:00:00 UTC
fmt.Println(t.Format(time.Kitchen)) // 12:00AM
// 中文格式
fmt.Println(t.Format("2006年01月02日 15时04分05秒"))
}时区处理
处理不同时区的时间戳转换
Go
package main
import (
"fmt"
"time"
)
func main() {
// 获取本地时区
loc := time.Local
fmt.Println("本地时区:", loc)
// 加载指定时区
shanghai, _ := time.LoadLocation("Asia/Shanghai")
newYork, _ := time.LoadLocation("America/New_York")
utc := time.UTC
// 当前时间在不同时区
now := time.Now()
fmt.Println("本地:", now.Format("2006-01-02 15:04:05"))
fmt.Println("UTC:", now.In(utc).Format("2006-01-02 15:04:05"))
fmt.Println("上海:", now.In(shanghai).Format("2006-01-02 15:04:05"))
fmt.Println("纽约:", now.In(newYork).Format("2006-01-02 15:04:05"))
// 时间戳转指定时区
timestamp := int64(1735660800)
t := time.Unix(timestamp, 0)
fmt.Println("上海时间:", t.In(shanghai).Format("2006-01-02 15:04:05"))
fmt.Println("纽约时间:", t.In(newYork).Format("2006-01-02 15:04:05"))
// 创建指定时区的时间
t2 := time.Date(2025, 1, 1, 0, 0, 0, 0, shanghai)
fmt.Println(t2.Unix()) // 上海时区的时间戳
}常用时间操作
时间计算、比较等常用操作
Go
package main
import (
"fmt"
"time"
)
func main() {
// 时间加减
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
nextWeek := now.AddDate(0, 0, 7) // 加7天
nextMonth := now.AddDate(0, 1, 0) // 加1个月
nextYear := now.AddDate(1, 0, 0) // 加1年
// 时间差计算
start := time.Now()
// ... 执行一些操作
elapsed := time.Since(start)
fmt.Printf("耗时: %v\n", elapsed)
fmt.Printf("耗时: %d 毫秒\n", elapsed.Milliseconds())
// 两个时间的差
t1 := time.Date(2025, 1, 1, 0, 0, 0, 0, time.Local)
t2 := time.Date(2025, 1, 15, 12, 0, 0, 0, time.Local)
diff := t2.Sub(t1)
fmt.Printf("相差: %v\n", diff) // 相差: 348h0m0s
fmt.Printf("相差: %.1f 小时\n", diff.Hours())
fmt.Printf("相差: %d 天\n", int(diff.Hours())/24)
// 时间比较
fmt.Println(t1.Before(t2)) // true
fmt.Println(t1.After(t2)) // false
fmt.Println(t1.Equal(t2)) // false
// 定时器
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for i := 0; i < 3; i++ {
<-ticker.C
fmt.Println("Tick at", time.Now().Format("15:04:05"))
}
}最佳实践
- •格式化时间使用"2006-01-02 15:04:05"这个固定模板
- •存储时间时使用Unix时间戳,避免时区问题
- •使用time.Since()和time.Until()计算时间差更简洁
- •Go 1.17+推荐使用UnixMilli()和UnixMicro()方法
常见问题
Go的格式化时间为什么用2006-01-02 15:04:05?
Go使用这个特定的时间作为参考时间,每个数字代表一个时间单位:2006是年、01是月、02是日、15是时(24小时制)、04是分、05是秒。这样做比使用YYYY-MM-DD更不容易出错。
time.Now()返回的是什么时区?
time.Now()返回的是本地时区的时间。可以使用In()方法转换时区,如time.Now().In(time.UTC)转换为UTC时间。
如何解析不同格式的日期字符串?
使用time.Parse()解析不带时区的字符串(返回UTC时间),使用time.ParseInLocation()解析带时区的字符串。需要根据日期格式编写对应的layout。
time.Unix()和time.UnixMilli()的区别?
time.Unix(sec, nsec)接受秒和纳秒两个参数,time.UnixMilli(ms)接受毫秒。Go 1.17+增加了UnixMilli()和UnixMicro()方便毫秒和微秒时间戳的转换。