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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析DNS,个人版 1个月
简介: 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 包,可以便利地进行各种时间相关处理。


    目录
    相关文章
    |
    9天前
    |
    JSON 中间件 Go
    go语言后端开发学习(四) —— 在go项目中使用Zap日志库
    本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
    go语言后端开发学习(四) —— 在go项目中使用Zap日志库
    |
    2天前
    |
    安全 Java Go
    探索Go语言在高并发环境中的优势
    在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
    |
    6天前
    |
    运维 Kubernetes Go
    "解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
    【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
    27 1
    |
    6天前
    |
    SQL 关系型数据库 MySQL
    Go语言中使用 sqlx 来操作 MySQL
    Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
    15 1
    |
    12天前
    |
    XML JSON Go
    微服务架构下的配置管理:Go 语言与 yaml 的完美结合
    微服务架构下的配置管理:Go 语言与 yaml 的完美结合
    |
    12天前
    |
    程序员 Go
    Go 语言:面向对象还是非面向对象?揭开编程语言的本质
    Go 语言:面向对象还是非面向对象?揭开编程语言的本质
    |
    6天前
    |
    算法 NoSQL 中间件
    go语言后端开发学习(六) ——基于雪花算法生成用户ID
    本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
    go语言后端开发学习(六) ——基于雪花算法生成用户ID
    |
    7天前
    |
    JSON 缓存 监控
    go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
    Viper 是一个强大的 Go 语言配置管理库,适用于各类应用,包括 Twelve-Factor Apps。相比仅支持 `.ini` 格式的 `go-ini`,Viper 支持更多配置格式如 JSON、TOML、YAML
    go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
    |
    12天前
    |
    存储 编译器 Go
    Go语言中的逃逸分析
    Go语言中的逃逸分析
    |
    8天前
    |
    安全 Go API
    go语言中的Atomic操作与sema锁
    在并发编程中,确保数据一致性和程序正确性是关键挑战。Go语言通过协程和通道提供强大支持,但在需精细控制资源访问时,Atomic操作和sema锁变得至关重要。Atomic操作确保多协程环境下对共享资源的访问是不可分割的,如`sync/atomic`包中的`AddInt32`等函数,底层利用硬件锁机制实现。sema锁(信号量锁)控制并发协程数量,其核心是一个uint32值,当大于零时通过CAS操作实现锁的获取与释放;当为零时,sema锁管理协程休眠队列。这两种机制共同保障了Go语言并发环境下的数据完整性和程序稳定性。

    相关实验场景

    更多