Go - 解析不是"标准"格式的日期/时间字符串

Nuc*_*eon 68 time go

如何解析Go中的非标准日期/时间字符串.在示例中,如果我想将字符串10/15/1983转换为time.Time?据time.Parse()推测,该功能允许您指定格式.

http://play.golang.org/p/v5DbowXt1x

package main

import "fmt"
import "time"

func main() {
    test, err := time.Parse("10/15/1983", "10/15/1983")
    if err != nil {
        panic(err)
    }

    fmt.Println(test)
}
Run Code Online (Sandbox Code Playgroud)

这导致恐慌.

panic: parsing time "10/15/1983" as "10/15/1983": cannot parse "" as "0/"

逻辑上这是有道理的,因为它应该知道哪一天是哪一天,哪一个月.

其他语言的功能类似于以下内容:

parse("mm/dd/yyyy", "10/15/1983")

我在Go文档中找不到这样的功能,是我正则表达式的唯一选择吗?

Dan*_*iel 154

time.Parse正在寻找一些关键值.

通过更改:

test, err := time.Parse("10/15/1983", "10/15/1983")
Run Code Online (Sandbox Code Playgroud)

test, err := time.Parse("01/02/2006", "10/15/1983")
Run Code Online (Sandbox Code Playgroud)

解析器会识别它.

这是操场上修改后的代码.

package main

import "fmt"
import "time"

func main() {
    test, err := time.Parse("01/02/2006", "10/15/1983")
    if err != nil {
        panic(err)
    }

    fmt.Println(test)
}
Run Code Online (Sandbox Code Playgroud)


您可以使用src/pkg/time/format.go文件中的常量列表来创建自己的解析格式.

const (
    stdLongMonth      = "January"
    stdMonth          = "Jan"
    stdNumMonth       = "1"
    stdZeroMonth      = "01"
    stdLongWeekDay    = "Monday"
    stdWeekDay        = "Mon"
    stdDay            = "2"
    stdUnderDay       = "_2"
    stdZeroDay        = "02"
    stdHour           = "15"
    stdHour12         = "3"
    stdZeroHour12     = "03"
    stdMinute         = "4"
    stdZeroMinute     = "04"
    stdSecond         = "5"
    stdZeroSecond     = "05"
    stdLongYear       = "2006"
    stdYear           = "06"
    stdPM             = "PM"
    stdpm             = "pm"
    stdTZ             = "MST"
    stdISO8601TZ      = "Z0700"  // prints Z for UTC
    stdISO8601ColonTZ = "Z07:00" // prints Z for UTC
    stdNumTZ          = "-0700"  // always numeric
    stdNumShortTZ     = "-07"    // always numeric
    stdNumColonTZ     = "-07:00" // always numeric
)
Run Code Online (Sandbox Code Playgroud)

所以,任何时候你的格式规定了一年,就应该以"06"或"2006"来完成,秒是由"05"或"5"的规定和时区是在"MST","Z0700"规定,"Z07:00 "," - 0700"," - 07"或"-07:00".如果您引用常量列表,则可以将您需要解析的任何标准格式放在一起.

例如,如果要以通用日志格式(Apache用于其日志文件的格式)解析日期/时间,则可以将以下字符串time.Parse()作为布局参数传递.

"02/Jan/2006:15:04:05 -0700"
Run Code Online (Sandbox Code Playgroud)

"02"表示月份字段,"Jan"表示月份字段,"2006"表示年份字段,"15"表示24小时格式的小时字段,"04"表示分钟字段, "05"表示秒字段," - 0700"表示时区字段.

该格式将解析当前的PST时间: 31/Dec/2012:15:32:25 -0800

所以这个time.Parse()电话看起来像这样:

test, err := time.Parse("02/Jan/2006:15:04:05 -0700", "31/Dec/2012:15:32:25 -0800")
Run Code Online (Sandbox Code Playgroud)

  • 哇,Go文档本可以提到你在日期格式中使用的数字实际上很重要. (69认同)
  • 在重新阅读文档后,我认为这一点可以在其中更加清晰.我结合现实世界的例子会让它更加清晰.在我的徒劳尝试中,我尝试了诸如`time.Parse("stdLongMonth/stdLongDay/stdLongYear","10/15/83")`= p. (7认同)
  • 你的代码有效,但为什么呢?如果我将它改为`time.Parse("01/02/2005","10/15/1983")`它失败了...... 2006年,2004年,1990年等相比,2006年的魔力是什么? (2认同)
  • 多么狡猾的做法啊!谢谢你的解释!+1 (2认同)

met*_*ule 6

如果您不记得指定布局中的数字("2006-01-02T15:04:05.000Z"),您可以使用我使用MS Excel约定的简单日期格式库github.com/metakeule/fmtdate,例如Y ,M,D,h并在内部将它们转换为数字格式:

package main

import (
    "github.com/metakeule/fmtdate"

    "fmt"
)

func main() {
    test, err := fmtdate.Parse("MM/DD/YYYY", "10/15/1983")
    if err != nil {
        panic(err)
    }

    fmt.Println(test)
}
Run Code Online (Sandbox Code Playgroud)

  • @DaveC嗯,我们德国人没有想到上午/下午,所以15到3是一个转换,你也必须记住顺序:日,月,小时/下午,分钟,秒,年,时区.今年的位置很奇怪.然而,我总是不得不查一查,而且我不是唯一一个......对于不熟悉go时间格式的人来说,excel格式显然是一种格式,不能与实际日期相混淆. (2认同)