Golang解析带毫秒的非标准时间戳格式
Golang解析带毫秒的非标准时间戳格式 我有以下时间戳需要解析:
2022.05.14-00.37.13:544
我尝试使用以下代码片段,但无法解析毫秒部分:
package main
import (
"fmt"
"time"
)
func main() {
s := "2022.05.14-00.37.13:544"
t, err := time.Parse("2006.01.02-15.04.05:000", s)
fmt.Println(t)
fmt.Println(err)
}
它失败并显示:
parsing time "2022.05.14-00.37.13:544" as "2006.01.02-15.04.05:000": cannot parse "544" as ":000"
我尝试了不同的方法,但都没有成功。 只有在移除毫秒部分时才能正常工作。 为了也能解析毫秒,正确的“参考字符串”应该是什么? 感谢所有提示。
这是包含上述代码片段的 Go Playground:
Go Playground - The Go Programming Language

更多关于Golang解析带毫秒的非标准时间戳格式的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang解析带毫秒的非标准时间戳格式的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果我阅读了这个议题,我认为我上述的用例目前无法通过Go的时间解析器实现:
时间:小数秒中不支持十进制逗号
由 dmitri.m 提出:
重现问题的步骤是什么?
如果可能,请包含一个指向 play.golang.org 上程序的链接。
Go 的 time 包期望小数秒中的十进制标记始终是一个点。
尝试解析使用十进制逗号的时间字符串会导致错误:
http://play.golang.org/p/d8qQasN0z1
在许多地区,十进制逗号是标准用法,但目前如果时间字符串中小数部分由逗号分隔,则无法解析秒的小数部分。
https://en.wikipedia.org/wiki/Decimal_mark#Countries_using_Arabic_numerals_with_decimal_comma
期望的输出是什么?
如果提供的布局也使用十进制逗号,时间字符串应该能够被解析且不报错。
实际看到的是什么?
将时间 "2013-08-19 22:56:01,234" 解析为 "2006-01-02 15:04:05,000" 时出错:
无法将 "234" 解析为 ",000"
你使用的是哪个编译器(5g, 6g, 8g, gccgo)?
6g
你使用的是哪个操作系统?
OS X 10.8.4
你使用的是哪个版本?(运行 'go version')
go version devel +5037426bea2f Mon Aug 19 23:09:24 2013 +0400 darwin/amd64
请在下面提供任何额外的信息。
请注意,(*time.Time).Format() 目前可以很好地输出十进制逗号,因为它不将其视为特殊字符。但是,为了在 Parse() 中支持十进制逗号而进行直接的修改——通过将它们添加到 stdFracSecond{0,9} 类中——会破坏这一点,因为 formatNano() 中硬编码了 '.'。
对于解析带毫秒的非标准时间戳格式 2022.05.14-00.37.13:544,需要使用正确的布局字符串。毫秒部分(:544)对应参考时间中的 .000 部分,但需要注意分隔符匹配。
以下是正确的解析方式:
package main
import (
"fmt"
"time"
)
func main() {
s := "2022.05.14-00.37.13:544"
// 正确的布局字符串
layout := "2006.01.02-15.04.05.000"
// 先将冒号替换为点号,以匹配布局
s = s[:len(s)-4] + "." + s[len(s)-3:]
t, err := time.Parse(layout, s)
fmt.Println("解析结果:", t)
fmt.Println("错误信息:", err)
fmt.Println("格式化输出:", t.Format("2006-01-02 15:04:05.000"))
}
如果不想修改原始字符串,可以使用更灵活的正则表达式方法:
package main
import (
"fmt"
"regexp"
"strconv"
"time"
)
func main() {
s := "2022.05.14-00.37.13:544"
// 使用正则表达式提取各个部分
re := regexp.MustCompile(`(\d{4})\.(\d{2})\.(\d{2})-(\d{2})\.(\d{2})\.(\d{2}):(\d{3})`)
matches := re.FindStringSubmatch(s)
if matches != nil {
year, _ := strconv.Atoi(matches[1])
month, _ := strconv.Atoi(matches[2])
day, _ := strconv.Atoi(matches[3])
hour, _ := strconv.Atoi(matches[4])
minute, _ := strconv.Atoi(matches[5])
second, _ := strconv.Atoi(matches[6])
millisecond, _ := strconv.Atoi(matches[7])
t := time.Date(year, time.Month(month), day, hour, minute, second, millisecond*1e6, time.UTC)
fmt.Println("解析结果:", t)
fmt.Println("格式化输出:", t.Format("2006-01-02 15:04:05.000"))
}
}
或者使用字符串分割的简单方法:
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func main() {
s := "2022.05.14-00.37.13:544"
// 分割日期和时间部分
parts := strings.Split(s, "-")
if len(parts) != 2 {
fmt.Println("格式错误")
return
}
// 解析日期部分
dateParts := strings.Split(parts[0], ".")
if len(dateParts) != 3 {
fmt.Println("日期格式错误")
return
}
year, _ := strconv.Atoi(dateParts[0])
month, _ := strconv.Atoi(dateParts[1])
day, _ := strconv.Atoi(dateParts[2])
// 解析时间部分(包含毫秒)
timeParts := strings.Split(parts[1], ":")
if len(timeParts) != 2 {
fmt.Println("时间格式错误")
return
}
// 解析时分秒
hmsParts := strings.Split(timeParts[0], ".")
if len(hmsParts) != 3 {
fmt.Println("时分秒格式错误")
return
}
hour, _ := strconv.Atoi(hmsParts[0])
minute, _ := strconv.Atoi(hmsParts[1])
second, _ := strconv.Atoi(hmsParts[2])
// 解析毫秒
millisecond, _ := strconv.Atoi(timeParts[1])
// 创建时间对象
t := time.Date(year, time.Month(month), day, hour, minute, second, millisecond*1e6, time.UTC)
fmt.Println("解析结果:", t)
fmt.Println("格式化输出:", t.Format("2006-01-02 15:04:05.000"))
}
关键点在于Go的time.Parse函数要求布局字符串中的分隔符必须完全匹配。原始时间戳中的毫秒部分使用冒号分隔(:544),而标准布局使用点号(.000),因此需要先进行字符串替换或使用其他解析方法。

