Golang time包时间格式化、时间戳与间隔输出详解

Ruby
Ruby
发布时间:2026-10-13 | 4人浏览过
原创

在Go开发中,准确处理时间至关重要。本文将演示如何使用time包获取当前时间的年月日时分秒,如何转换为秒、毫秒、微秒和纳秒的时间戳,以及如何对duration类型进行格式化输出,并解析其底层源码逻辑。

获取当前时间的组成单元

使用time.Now()获取当前时间后,可以通过直接调用的接口分别获取年、月、日、时、分、秒和纳秒。其中,微秒和毫秒通常需要基于纳秒进行换算。

以下代码展示了如何提取各个时间分量:

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

// 直接获取各时间分量
year := now.Year()
month := now.Month()
day := now.Day()
hour := now.Hour()
minute := now.Minute()
second := now.Second()
nanosecond := now.Nanosecond()

// 基于纳秒计算微秒和毫秒
microsecond := nanosecond / 1e3
millisecond := nanosecond / 1e6

// 格式化输出当前时间,注意参考时间为 2006-01-02 15:04:05
fmt.Println(now.Format("2006-01-02 15:04:05.000000000"))
fmt.Println(year, month, day, hour, minute, second, nanosecond, microsecond, millisecond)

转换Unix时间戳(秒/毫秒/纳秒)

从Unix纪元(1970年1月1日)到现在的时长,可以通过不同的后缀接口获取不同精度的时间戳。这些接口直接返回整数类型的秒数或纳秒数计数。

常用方法如下:

  • Unix():返回秒级时间戳(通常10位数字)。
  • UnixMilli():返回毫秒级时间戳(通常13位数字)。
  • UnixMicro():返回微秒级时间戳(通常16位数字)。
  • UnixNano():返回纳秒级时间戳(通常19位数字)。
sec := now.Unix()      // sec
ms := now.UnixMilli()  // ms
us := now.UnixMicro()  // us
ns := now.UnixNano()   // ns

fmt.Printf("sec:%v\n ms:%v\n us:%v\n ns:%v\n", sec, ms, us, ns)

时间间隔(Duration)格式化输出

time.Duration表示两个时间点之间的持续时间,内部以纳秒为单位存储的整数值。在打印或展示时,常需要根据场景选择不同的精度格式。

第1步:直接使用 %v 输出完整描述

如果不进行单位转换,直接使用%v打印,Go会自动将内部纳秒值转换为人类可读的字符串形式(如 "1h1m1.001001001s"),精度最高且不易出错。

duration := 1*time.Hour + 1*time.Minute + 1*time.Second +
	1*time.Millisecond + 1*time.Microsecond + 1*time.Nanosecond

fmt.Printf("duration:%v\n", duration)
// 输出: 1h1m1.001001001s

// %.3v 仅截取前三个字符,不推荐用于完整展示
fmt.Printf("duration:%.3v\n", duration)
// 输出: 1h1

第2步:转换为特定单位(秒/毫秒)并格式化

在性能统计或日志记录中,常需统一单位为秒或毫秒。Seconds()返回float64,支持小数;Milliseconds()返回int64。

秒的输出:可使用%f控制小数位数,例如%0.3f精确到毫秒级别。

fmt.Printf("duration:%vsec\n", duration.Seconds())
// 输出: 3661.001001001sec (默认精度)

fmt.Printf("duration:%0.3fsec\n", duration.Seconds())
// 输出: 3661.001sec

毫秒的输出:由于Milliseconds()返回整数,直接用%d或%v即可。若转为float64,小数部分恒为0,无实际意义。

fmt.Printf("duration:%vms\n", duration.Milliseconds())
// 输出: 3661001ms

fmt.Printf("duration:%.3dms\n", duration.Milliseconds())
// 输出: 3661001ms

12小时制与其他格式示例

Go的时间格式化引用固定时间:2006-01-02 15:04:05 Mon Jan。若要实现12小时制,必须显式指定PM占位符,否则无法区分上午或下午。

func formatDemo() {
    now := time.Now()
    
    // 24小时制
    fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
    
    // 12小时制,注意 PM 的使用
    fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
    
    // 其他常见格式
    fmt.Println(now.Format("2006/01/02 15:04"))
}

底层源码逻辑简述

Seconds()等方法的实现并非简单除法,而是先分离整数部分(秒/分/时)和小数部分(剩余纳秒),再组合为浮点数。这种设计避免了浮点误差导致的舍入问题,确保打印结果与纯整数转换一致。

关键源码逻辑如下:

// Seconds returns the duration as a floating point number of seconds.
func (d Duration) Seconds() float64 {
	sec := d / Second
	nsec := d % Second
	return float64(sec) + float64(nsec)/1e9
}

总结

处理Go中的时间问题时,应优先使用内置的Unix系列接口获取高精度时间戳。对于时长展示,若需保留完整精度,直接使用%v打印Duration对象是最稳妥的方式;若需统一单位,推荐转换为秒并使用%f控制小数精度。以上就是关于Go语言time包时间处理与格式化的详细内容,更多关于Go时间管理技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表