英文:
How to parse CCYY-MM-DDThh:mm:ss[.sss...] date format
问题
众所周知,Go语言中的日期解析有其特殊之处。
然而,我现在遇到了需要将CCYY-MM-DDThh:mm:ss[.sss...]
格式的日期时间字符串解析为有效日期的问题。
这个CCYY
格式在天文学中似乎是无处不在的,实际上,CC代表的是当前世纪,所以尽管我们处于2022年,但世纪是21世纪,意味着以CCYY
格式表示的日期应该是2122年。
当我们无法指定编码布局时,如何解析这种格式的日期字符串呢?
我应该只是按照那种格式解析,并减去一个“世纪”,例如,将2106
解析为2006
的日期时间...?
有人在以前遇到过这个小众问题吗?
(就我个人而言,如果不是因为这是我出生的确切时间,我永远不可能记住2006年1月2日下午3:04:05,UTC-0700
!我真是幸运。)
英文:
As we all know, date parsing in Go has it's quirks*.
However, I have now come up against needing to parse a datetime string in CCYY-MM-DDThh:mm:ss[.sss...]
to a valid date in Go.
This CCYY
format is a format that seems to be ubiquitous in astronomy, essentially the CC is the current century, so although we're in 2022, the century is the 21st century, meaning the date in CCYY
format would be 2122.
How do I parse a date string in this format, when we can't specify a coded layout?
Should I just parse in that format, and subtract one "century" e.g., 2106
becomes 2006
in the parsed datetime...?
Has anyone come up against this niche problem before?
*(I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700
if it wasn't the exact time of my birth! I got lucky)
答案1
得分: 2
time
包不支持解析世纪。你需要自己处理。
另外要注意,简单的减法是不够的,例如21世纪发生在2001年1月1日至2100年12月31日之间(年份可能以20
或21
开头)。如果年份以00
结尾,你不需要减去100年。
我会编写一个辅助函数来解析这样的日期:
func parse(s string) (t time.Time, err error) {
t, err = time.Parse("2006-01-02T15:04:05[.000]", s)
if err == nil && t.Year()%100 != 0 {
t = t.AddDate(-100, 0, 0)
}
return
}
进行测试:
fmt.Println(parse("2101-12-31T12:13:14[.123]"))
fmt.Println(parse("2122-10-29T12:13:14[.123]"))
fmt.Println(parse("2100-12-31T12:13:14[.123]"))
fmt.Println(parse("2201-12-31T12:13:14[.123]"))
输出结果(在 Go Playground 上尝试):
2001-12-31 12:13:14.123 +0000 UTC <nil>
2022-10-29 12:13:14.123 +0000 UTC <nil>
2100-12-31 12:13:14.123 +0000 UTC <nil>
2101-12-31 12:13:14.123 +0000 UTC <nil>
至于记住布局的时间:
在美国,日期的常见顺序是 January 2, 15:04:05, 2006(时区:-0700),在这个表示中,各部分按递增的数字顺序排列:January 是第1个月,15点是下午3点,年份2006是第6个。所以顺序是 1、2、3、4、5、6、7。
英文:
The time
package does not support parsing centuries. You have to handle it yourself.
Also note that a simple subtraction is not enough, as e.g. the 21st century takes place between January 1, 2001 and December 31, 2100 (the year may start with 20
or 21
). If the year ends with 00
, you do not have to subtract 100 years.
I would write a helper function to parse such dates:
func parse(s string) (t time.Time, err error) {
t, err = time.Parse("2006-01-02T15:04:05[.000]", s)
if err == nil && t.Year()%100 != 0 {
t = t.AddDate(-100, 0, 0)
}
return
}
Testing it:
fmt.Println(parse("2101-12-31T12:13:14[.123]"))
fmt.Println(parse("2122-10-29T12:13:14[.123]"))
fmt.Println(parse("2100-12-31T12:13:14[.123]"))
fmt.Println(parse("2201-12-31T12:13:14[.123]"))
Which outputs (try it on the Go Playground):
2001-12-31 12:13:14.123 +0000 UTC <nil>
2022-10-29 12:13:14.123 +0000 UTC <nil>
2100-12-31 12:13:14.123 +0000 UTC <nil>
2101-12-31 12:13:14.123 +0000 UTC <nil>
As for remembering the layout's time:
January 2, 15:04:05, 2006 (zone: -0700) is a common order in the US, and in this representation parts are in increasing numerical order: January is month 1, 15 hour is 3PM, year 2006 is 6. So the ordinals are 1, 2, 3, 4, 5, 6, 7.
答案2
得分: 0
我个人永远不会能够记住2006年1月2日下午3点04分05秒(UTC-0700),如果不是因为那是我出生的确切时间!我很幸运。
Go时间包的布局是基于Unix(和类Unix)的日期命令格式。例如,在Linux上,
$ date
Fri Apr 15 08:20:43 AM EDT 2022
$
现在,从左到右计数,
月份 = 1
日 = 2
小时 = 3(或15 = 12 + 3)
分钟 = 4
秒 = 5
年 = 6
注意:Rob Pike是《Unix编程环境》的作者之一。
英文:
> I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700 if it wasn't the exact time of my birth! I got lucky.
The reason for the Go time package layout is that it is derived from the Unix (and Unix-like) date command format. For example, on Linux,
$ date
Fri Apr 15 08:20:43 AM EDT 2022
$
Now, count from left to right,
Month = 1
Day = 2
Hour = 3 (or 15 = 12 + 3)
Minute = 4
Second = 5
Year = 6
Note: Rob Pike is an author of The Unix Programming Environment
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论