Разбор строк даты/времени, которые не являются "стандартными" форматами

Как обрабатывать нестандартные строки даты/времени в 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, является ли единственным выбором для регулярного выражения?

Ответ 1

Есть несколько ключевых значений, которые ищет time.Parse.

Изменяя:

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

к

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

анализатор распознает его.

Здесь измененный код на игровой площадке.

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 ". Если вы ссылаетесь на список констант, вы можете собрать любой стандартный формат, который вам нужен для синтаксического анализа.

Например, если вы хотите проанализировать дату/время в общем формате журнала, формат, который Apache использует для своих файлов журналов, вы сделали бы это, передав следующую строку в time.Parse() в качестве аргумента layout.

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

"02" обозначает поле месяца месяца, "Ян" обозначает поле названия месяца, "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")

Ответ 2

Если вы не можете вспомнить номера в заданном макете ( "2006-01-02T15: 04: 05.000Z" ), вы можете использовать мою простую библиотеку форматирования даты 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)
}