1. ホーム
  2. time

標準形式ではない日付/時刻文字列のパース

2023-10-05 19:41:29

質問

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 のドキュメントにそのような関数が見当たらないのですが、唯一の選択肢は regex ですか?

どのように解決するのですか?

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" で指定する必要があるのです。 00"、"-0700"、"-07"、"-07:00"のいずれかです。 定数リストを参照すれば、解析に必要な標準的な書式をまとめることができそうです。

の日付/時刻を解析したい場合は、次のようにします。 一般的なログ形式 で、Apache がログファイルに使っている書式で、 日付と時刻を解析したい場合は、次の文字列を time.Parse() に渡すことです。 レイアウト の引数に指定します。

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