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

时间:2012-12-31 22:32:20

标签: 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)
}

这导致恐慌。

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

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

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

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

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

4 个答案:

答案 0 :(得分:149)

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

通过更改:

test, err := time.Parse("10/15/1983", "10/15/1983")

test, err := time.Parse("01/02/2006", "10/15/1983")

解析器会识别它。

这是modified code on the playground

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)
}


您可以利用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
)

因此,只要您的格式指定年份,就应该使用“06”或“2006”,秒由“05”或“5”指定,时区指定为“MST”,“Z0700”,“ Z07:00“,” - 0700“,” - 07“或”-07:00“。如果您引用常量列表,您可能会将您需要解析的任何标准格式放在一起。

例如,如果要解析Common Log Format中日期/时间(Apache用于其日志文件的格式),可以将以下字符串传递给time.Parse()作为< i> layout 参数。

"02/Jan/2006:15:04:05 -0700"

“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")

答案 1 :(得分:6)

如果您无法记住指定布局中的数字(&#34; 2006-01-02T15:04:05.000Z&#34;),您可以使用我的简单日期格式库github.com/metakeule/fmtdate它使用MS Excel约定,如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)
}

答案 2 :(得分:2)

如果您正在寻找C样式格式功能:在查看了一些选项之后,我选择了https://github.com/cactus/gostrftime,因为它通常遵循strfmt(3)表示法。

引用示例:

import (
    "fmt"
    "time"
    "github.com/cactus/gostrftime"
)

func main() {
    now := time.Now()
    fmt.Println(gostrftime.Format("%Y-%m-%d", now))
}

如果C和Go都必须使用日期格式,并且不碰触C实现,则别无选择,只能适应Go端。上面的软件包满足了这一需求。

答案 3 :(得分:0)

如果你不想费心记住神奇的数字,你可以这样做:

package main

import (
   "fmt"
   "time"
)

func main() {
   var (
      y, d int
      m time.Month
   )
   fmt.Sscanf("10/15/1983", "%v/%v/%v", &m, &d, &y)
   t := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
   fmt.Println(t) // 1983-10-15 00:00:00 +0000 UTC
}

https://golang.org/pkg/fmt#Sscanf