如何解析Go中的时间,而不以秒和毫秒为间隔?
我必须解析以下格式的时间:如何解析Go中的时间,而不以秒和毫秒为间隔?,go,Go,我必须解析以下格式的时间: 20060102150405000 例如,“20170116111621978”代表2017年1月16日11:16:21.978。在我看来,Go time软件包需要在日期格式(05.000)中嵌入一个句点(因此需要输入)。除了重写源字符串以包含一个句点来用time.parse解析这些字符串之外,我想不出任何方法。有人有什么建议吗?不幸的是,软件包要求布局中的分数秒部分(毫秒)有一个句点前缀,因此您有两个选择: 修改输入以插入句点,这样您就可以使用布局2006010
20060102150405000
例如,“20170116111621978”代表2017年1月16日11:16:21.978。在我看来,Go time软件包需要在日期格式(05.000)中嵌入一个句点(因此需要输入)。除了重写源字符串以包含一个句点来用time.parse解析这些字符串之外,我想不出任何方法。有人有什么建议吗?不幸的是,软件包要求布局中的分数秒部分(毫秒)有一个句点前缀,因此您有两个选择:
- 修改输入以插入句点,这样您就可以使用布局
20060102150405.000
- 或者切掉最后3位数字,使用布局解析前缀
20060102150405
,解析毫秒(例如使用),并将其添加到时间使用中
似乎无法用标准的Go-parse格式实现这一点
解析日期而不出错的一个技巧是将最后三毫秒的精确数字time.parse(“20060102150405”+t[len(t)-3:],t)
添加到格式中(最长为秒),但这只能确保解析不会返回错误。它将失去小数部分
此代码段()说明了作者的建议:
package main
import (
"fmt"
"time"
"strconv"
)
const t = "20170116111621978"
func main() {
dateStr := t[:len(t)-3]
millisStr := t[len(t)-3:]
parsed, err := time.Parse("20060102150405", dateStr)
if err != nil {
panic(err)
}
millis, _ := strconv.Atoi(millisStr)
parsed = parsed.Add(time.Duration(millis)*time.Millisecond)
// prints true
fmt.Println(parsed.UnixNano() == time.Date(2017, 1, 16, 11, 16, 21, 978000000, time.UTC).UnixNano())
}
Icza的答案似乎比Steven Penny的答案更有效:
$ go test -bench=. ./parsedate_test.go -benchtime=10s
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
BenchmarkParseMillisSscanf-4 5538606 2159 ns/op 144 B/op 16 allocs/op
BenchmarkParseMillisAddTime-4 74758664 157.4 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 26.086s
这似乎可以做到:
package main
import (
"fmt"
"time"
)
func main() {
var (
year, day, hour, min, sec, mil int
mon time.Month
)
fmt.Sscanf(
"20060102150405000", "%4v%2v%2v%2v%2v%2v%3v",
&year, &mon, &day, &hour, &min, &sec, &mil,
)
t := time.Date(year, mon, day, hour, min, sec, mil * 1e6, time.UTC)
fmt.Println(t) // 2006-01-02 15:04:05 +0000 UTC
}
参考下表:我不得不说,我很难从给出的三个(目前)答案中选择一个明确的答案。这三个问题,作为一个整体,实际上是对这个问题的一个好的、全面的回答。我向贡献者表示歉意,我只能选择一个。此解决方案的另一个缺点是它也“接受”无效输入,例如,如果年份为负。time.Parse()
函数将为该输入报告一个错误。@StevenPenny Negative year只是一个例子time.Parse()
有更多的验证规则。这个问题的范围是解析一个时间,所以它在范围之内。@icza,它在我回答的范围之外。我不想把它扩大到现在的程度。