Golang time包时间格式化、时间戳与间隔输出详解
在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时间管理技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













