5分钟撸一个时间转换器,Go语言教你如何开挂

简介: 5分钟撸一个时间转换器,Go语言教你如何开挂

Go 语言中内置的 time 包提供了时间的显示、转换、计算等功能,使用 time 包可以方便地进行时间相关操作。时间,对程序员来说是一个复杂且重要的概念。在代码中如何正确地表示和操作时间,直接影响到程序的行为和结果。Go 语言作为一门优秀的编程语言,它在时间表示和转换方面有着非常强大和人性化的功能。

本文主要内容包括

  1. Go 语言时间转换基础
  2. 时间的显示和格式化
  3. 时间的计算和转换
  4. 时间字符串解析
  5. 实际时间转换示例
  6. 时间处理进阶用法
  7. time 包的其他用法
  8. Go语言时间转换完整示例


1

 

一、Go 语言时间转换基础

Go 语言中内置的 time 包提供了时间的显示、转换、计算等功能,使用 time 包可以方便地进行时间相关操作。

1.1

 

1. Time 类型

time.Time 类型表示时间点信息,它包含时、分、秒、纳秒、时区等信息。使用 time.Now()可以获取当前时间

now := time.Now() // 获取当前时间

也可以使用 time.Unix()将 Unix 时间戳转换为 Time

t := time.Unix(1660924000, 0) // 将秒级Unix时间戳转换为时间

1.2

 

2. 时间组成

time.Time 提供了获取时间各个组成部分的方法

hour := t.Hour() // 小时
minute := t.Minute() // 分钟  
second := t.Second() // 秒
nanosecond := t.Nanosecond() // 纳秒
year := t.Year() // 年
month := t.Month() // 月
day := t.Day() // 日
weekday := t.Weekday() // 星期几
zone, offset := t.Zone() // 时区信息

这些方法可以获得时间的时分秒、年月日等信息。

1.3

 

3. 时间比较

可以使用 time.Time 的 Before()、After()、Equal()方法比较两个时间大小

t1 := time.Now()
t2 := t1.Add(time.Hour)
fmt.Println(t1.Before(t2)) // true
fmt.Println(t1.After(t2)) // false
fmt.Println(t1.Equal(t2)) // false

time.Time 还可以直接比较大小:if t1.Before(t2) {...}

2

 

二、时间的显示和格式化

获得 time.Time 后,可以以不同的格式显示时间。

2.1

 

1. 默认格式

Print 或 Println 直接输出 time.Time,默认以 RFC3339 格式显示

now := time.Now()
fmt.Println(now) // 2023-02-20T21:00:00+08:00

2.2

 

2. 自定义格式化

使用 time.Time 的 Format 方法可以自定义格式化时间显示

const format = "2006-01-02 15:04:05"
fmt.Println(now.Format(format)) // 2023-02-20 21:00:05

Format 的参数定义了转换的格式和内容

2006    年份,用4位数表示
01      月份,用2位数表示
02      日期,用2位数表示  
15      小时,24小时制,用2位数表示
04      分钟,用2位数表示
05      秒,用2位数表示

通过组合不同的格式值,可以灵活地格式化时间显示。

2.3

 

3. 标准格式

time 包定义了几种标准的格式化布局常量

  • time.ANSIC = "Mon Jan _2 15:04:05 2006"
  • time.UnixDate = "Mon Jan _2 15:04:05 MST 2006"
  • time.RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
  • time.RFC822 = "02 Jan 06 15:04 MST"
  • time.RFC822Z = "02 Jan 06 15:04 -0700"
  • time.RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
  • time.RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
  • time.RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700"
  • time.RFC3339 = "2006-01-02T15:04:05Z07:00"
  • time.RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
  • time.Kitchen = "3:04PM"
  • time.Stamp = "Jan _2 15:04:05"
  • time.StampMilli = "Jan _2 15:04:05.000"
  • time.StampMicro = "Jan _2 15:04:05.000000"
  • time.StampNano = "Jan _2 15:04:05.000000000"

使用这些格式只需要将常量作为参数传入 Format 方法

fmt.Println(now.Format(time.RFC822)) // 02 Feb 23 21:00 +0800

3

 

三、时间的计算和转换

可以对时间进行计算,获得新的时间,或者转换为其他时间单位。

3.1

 

1. Add 和 Sub

使用 Add 可以增加时间

t := t.Add(time.Hour * 24) // 增加24小时
t = t.Add(time.Minute * 30) // 增加30分钟

Sub 可以获取两个时间的差值 Duration

t1 := ...
t2 := ... 
diff := t2.Sub(t1) // 获取间隔时间段

3.2

 

2. UTC 和 Local

UTC()方法可以获取 UTC 时间,Local()方法可以转换为当前位置的时间

now := time.Now() // 当前本地时间 
utc := now.UTC() // 转换为UTC时间
local := utc.Local() // 重新转换为本地时间

3.3

 

3. 时间戳转换

Unix()和 UnixNano()可以获取时间的 Unix 时间戳(秒和纳秒)

now := time.Now()
seconds := now.Unix() // 秒级时间戳
nanoseconds := now.UnixNano() // 纳秒时间戳

3.4

 

4. 睡眠

Sleep 可以使程序睡眠指定时间

time.Sleep(time.Second * 5) // 睡眠5秒

3.5

 

5. Ticker

Ticker 可以设置定时器,定期发送时间

ticker := time.NewTicker(time.Second * 5)
for now := range ticker.C {
    fmt.Println(now) // 每5秒打印一次时间
}

4

 

四、时间字符串解析

可以将字符串解析为时间。

4.1

 

1. Parse 和 ParseInLocation

Parse 解析一个格式化的时间字符串,返回时间

t, err := time.Parse("2006-01-02 15:04:05", "2023-02-20 21:00:00")

ParseInLocation 同时指定时区信息

loc, err := time.LoadLocation("Asia/Shanghai")
t, err := time.ParseInLocation("2006-01-02 15:04:05", "2023-02-20 21:00:00", loc)

4.2

 

2. 标准格式

使用 RFC3339、RFC822 等标准格式的时间字符串可以直接解析


t, err := time.Parse(time.RFC3339, "2023-02-20T21:00:00+08:00")

4.3

 

3. 错误处理

因为解析可能出错,应该处理解析错误

const layout = "2006-01-02 15:04:05"
t, err := time.Parse(layout, "2023-02-20 21:00:00")
if err != nil {
    fmt.Println(err)
    return 
}
// 使用解析的时间t

5

 

五、实际时间转换示例

结合上面的知识点,这里提供一些常见的时间转换示例。

5.1

 

1. Unix 时间戳转换

将 Unix 时间戳秒转换为时间

import "time"
seconds := 1660924000
t := time.Unix(seconds, 0) 
// 使用Unix()从秒时间戳获取时间
fmt.Println(t) // 2023-02-20 21:00:00 +0800 CST

5.2

 

2. ANSI C 时间格式转换

解析 ANSI C 格式的时间字符串

const ansiCLayout = "Mon Jan _2 15:04:05 2006"  
str := "Mon Feb 20 21:00:00 2023"
t, err := time.Parse(ansiCLayout, str)
fmt.Println(t) // 2023-02-20 21:00:00 +0800 CST

5.3

 

3. 格式化显示时间

格式化显示时间

now := time.Now() 
const layout = "2006-01-02 15:04:05"
fmt.Println(now.Format(layout)) // 2023-02-20 21:00:05

5.4

 

4. 获取时间字段

获取时间的时分秒等字段

hour := now.Hour()
minute := now.Minute()
second := now.Second()
year := now.Year()
month := now.Month()
day := now.Day()

5.5

 

5. 计算时间差

计算两个时间的差值

t1, err := time.Parse("2006-01-02 15:04:05", "2023-02-01 00:00:00")
t2, err := time.Parse("2006-01-02 15:04:05", "2023-02-28 00:00:00")
diff := t2.Sub(t1) // 27h0m0s

6

 

六、时间处理进阶用法

这里介绍一些时间处理的进阶用法。

6.1

 

1. 时区处理

Go 语言中时区处理主要涉及

  • LoadLocation 函数加载时区信息
  • 时区参数在 ParseInLocation 解析时指定
  • time.Time 的 Location 方法获取时区

示例:

loc, err := time.LoadLocation("Asia/Shanghai")
t, err := time.ParseInLocation("2006-01-02 15:04:05", "2023-02-20 21:00:00", loc) 
zone, offset := t.Zone() // 获取时区信息
fmt.Println(t.Location()) // Asia/Shanghai

6.2

 

2. 定时器

time.Ticker 定期触发时间:

ticker := time.NewTicker(time.Second * 5) 
for t := range ticker.C {
   fmt.Println(t) // 每5秒打印一次时间
}

6.3

 

3. 时间戳转换

time.Unix 和 UnixNano 转换为时间戳

now := time.Now()
secs := now.Unix() // 秒时间戳
nanos := now.UnixNano() // 纳秒时间戳

6.4

 

4. 时间格式化处理

Format 格式化时间显示

t := time.Now()
fmt.Println(t.Format("2006-01-02 15:04:05")) // 自定义格式
fmt.Println(t.Format(time.RFC3339)) // 使用RFC3339标准格式

6.5

 

5. 链式时间计算

时间支持链式操作,可以连续增加时间

t := time.Now()
t = t.Add(time.Hour * 24).Add(time.Minute * 30) // 增加1天和30分钟

7

 

七、time 包的其他用法

time 包中还有一些其他用法

  1. AfterFunc 和 NewTimer 可以在未来时间做一次性触发

  2. Date 和 ParseDuration 可以处理日期和时间段

  3. LoadLocation 可以预加载时区信息

  4. Sleep 可以使 Goroutine 睡眠指定时间

  5. Since 和 Until 可以计算时间段序列

详细用法可以查阅 time 包的文档和示例代码。

8

 

八、Go语言时间转换完整示例

Go 语言中时间转换和格式化的完整示例

package main
import (
    "fmt"
    "time"
)
func main() {
    // 1. 将时间戳秒转换为时间
    seconds := int64(1660924000)
    t := time.Unix(seconds, 0)
    fmt.Println(t)
    // 2. 解析布局格式的时间字符串
    layout := "2006-01-02 15:04:05" 
    t, err := time.Parse(layout, "2023-08-20 11:00:00")
    if err != nil {
        fmt.Println(err)
        return
    }
    // 3. 格式化输出时间
    fmt.Println(t.Format("2006/01/02 15:04")) 
    // 4. 计算时间差值
    t1, _ := time.Parse(layout, "2023-08-01 11:00:00")
    t2, _ := time.Parse(layout, "2023-08-31 11:00:00")
    diff := t2.Sub(t1)
    fmt.Println(diff)
    // 5. 增加时间
    t = t.Add(time.Hour * 24)
    fmt.Println(t)
    // 6. 定时器
    ticker := time.NewTicker(time.Second * 2)
    go func() {
        for t := range ticker.C {
            fmt.Println("Tick:", t) 
        }
    }()
    // 7. 睡眠
    time.Sleep(time.Second * 5)
    ticker.Stop()
    fmt.Println("Done")
}
    1. 将 Unix 时间戳秒转换为时间
    2. 解析布局格式的时间字符串
    3. 使用 Format 格式化输出时间
    4. 计算两个时间的差值
    5. 增加时间的小时
    6. 使用 Ticker 设置定时器定期触发
    7. 调用 Sleep 使程序睡眠一段时间

    这个示例演示了 Go 语言中处理时间的一些常见用法。我们可以通过组合这些用法来实现具体的时间转换、显示、计算等功能。

    9

     

    九、总结

    在 Go 语言中正确处理时间非常重要,time 提供了完善的时间操作和转换功能。

    主要是理解 time.Time 表示时间点,可以通过方法获取时间详情;显示和格式化时间需要定义布局;可以对时间进行计算和转换等。

    注意解析时间时区信息,使用 tic.Ticker 定时触发等高级用法。

    通过熟练应用 time 包,可以便利地进行各种时间相关处理。


    目录
    相关文章
    |
    4月前
    |
    存储 安全 Java
    【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
    结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
    276 1
    |
    12月前
    |
    编译器 Go
    揭秘 Go 语言中空结构体的强大用法
    Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
    |
    12月前
    |
    运维 监控 算法
    监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
    在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
    |
    6月前
    |
    Cloud Native 安全 Java
    Go:为云原生而生的高效语言
    Go:为云原生而生的高效语言
    381 1
    |
    6月前
    |
    Cloud Native Go API
    Go:为云原生而生的高效语言
    Go:为云原生而生的高效语言
    464 0
    |
    6月前
    |
    Cloud Native Java Go
    Go:为云原生而生的高效语言
    Go:为云原生而生的高效语言
    313 0
    |
    6月前
    |
    Cloud Native Java 中间件
    Go:为云原生而生的高效语言
    Go:为云原生而生的高效语言
    337 0
    |
    6月前
    |
    Cloud Native Java Go
    Go:为云原生而生的高效语言
    Go:为云原生而生的高效语言
    374 0
    |
    6月前
    |
    数据采集 Go API
    Go语言实战案例:多协程并发下载网页内容
    本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
    |
    6月前
    |
    数据采集 JSON Go
    Go语言实战案例:实现HTTP客户端请求并解析响应
    本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。