LoginSignup
43
24

More than 3 years have passed since last update.

Golang time.Parse の使い方

Posted at

この記事は 私のホームページ とのマルチポストです

この記事では、Golang で文字列を Time 構造体に変換する time.Parse の使い方を解説しつつ
使用例のコード片を提示します。

基本的な使い方

第1引数に、時刻のフォーマット定義を指定し、第2引数にパースしたい文字列を指定します。

フォーマットは、必ず 2006年1月2日午後3時4分5秒(山岳部標準時) である必要があります。
なんでこの時間? と、一瞬思いますが、月日時分秒年の順番で表記した時、左から 1,2,3,4,5,6,7 と増えていきます。

山岳部標準時は -7 です。

時刻を24時間表記でパースさせたい場合は、15 を指定します。

package main

import (
    "fmt"
    "time"
)

func main() {
    // パースする対象である時間がどのように参照されているかのフォーマット定義です
    layout := "Jan 2, 2006 at 3:04pm (MST)"

    // パースする対象の文字列です
    value := "Feb 3, 2013 at 7:54pm (PST)"
    t, _ := time.Parse(layout, value)

    fmt.Println(t)
    // 2013-02-03 19:54:00 +0000 PST
}

一部の定義を省略する

フォーマット定義およびパースしたい文字列から一部の値を外した場合、デフォルトとして 0 が、 0 が設定できない場合 1 が設定されます。
タイムゾーンの場合は UTC が設定されます。

下記の例では、時刻やタイムゾーンを省略したため、時・分・秒に 0 が、タイムゾーンに UTC がセットされます。
年を省略した場合は 0 が、月・日を省略した場合は、 1 がセットされます。

package main

import (
  "fmt"
  "time"
)

func main() {
  layout := "2006-01-02"

  value := "2019-07-23"
  t, e := time.Parse(layout, value)

  if e != nil {
    fmt.Println(e)
  }

  fmt.Println(t)
  // 2019-07-23 00:00:00 +0000 UTC
}

つまり、何もかも省略した場合は、0000-01-01 00:00:00 +0000 UTC になります。

package main

import (
  "fmt"
  "time"
)

func main() {
  layout := ""

  value := ""
  t, e := time.Parse(layout, value)

  if e != nil {
    fmt.Println(e)
  }

  fmt.Println(t)
  // 0000-01-01 00:00:00 +0000 UTC
}

format と layout のフォーマットが違うとエラーになります。

例えば、下記の例を見てみましょう。

フォーマット定義ではタイムゾーン指定を削りましたが、パースしたい文字列ではタイムゾーンが指定されています。なので、エラーになります。。
この場合、パースすると必ず 0001-01-01 00:00:00 +0000 UTC になります。

package main

import (
  "fmt"
  "time"
)

func main() {
  layout := "Jan 2, 2006 at 3:04pm"
  value := "Feb 3, 2013 at 7:54pm (PST)"
  t, _ := time.Parse(layout, value)

  if e != nil {
    fmt.Println(e)
    // parsing time "Oct 3, 1986 at 8:07am (PST)": extra text:  (PST)
  }

  fmt.Println(t)
  // 0001-01-01 00:00:00 +0000 UTC
}

フォーマットに日本語を使う

フォーマットに使用する日時さえあってれば可能です。

package main

import (
  "fmt"
  "time"
)

func main() {
  layout := "2006年01月02日 15時04分05秒 (MST)"

  value := "2019年07月23日 20時10分11秒 (JST)"
  t, e := time.Parse(layout, value)

  if e != nil {
    fmt.Println(e)
  }

  fmt.Println(t)
  // 2019-07-23 20:10:11 +0000 JST
}

組み込みフォーマット

timeパッケージの定数 に定義されています。

const (
        ANSIC       = "Mon Jan _2 15:04:05 2006"
        UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
        RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
        RFC822      = "02 Jan 06 15:04 MST"
        RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
        RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
        RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
        RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
        RFC3339     = "2006-01-02T15:04:05Z07:00"
        RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
        Kitchen     = "3:04PM"
        // Handy time stamps.
        Stamp      = "Jan _2 15:04:05"
        StampMilli = "Jan _2 15:04:05.000"
        StampMicro = "Jan _2 15:04:05.000000"
        StampNano  = "Jan _2 15:04:05.000000000"
)

存在しない時間を指定するとエラーになる

もちろん、エラーになります。

package main

import (
  "fmt"
  "time"
)

func main() {
  layout := "2006年01月02日 15時04分05秒 (MST)"

  // 例えば、25時という存在しない時間にすると・・・
  value := "2019年07月23日 25時10分11秒 (JST)"
  t, e := time.Parse(layout, value)

  if e != nil {
  // 下記のように時間が0-23の範囲外であるというエラーが出てきます。
    fmt.Println(e)
    // parsing time "2019年07月23日 25時10分11秒 (JST)": hour out of range
  }

  fmt.Println(t)
  // 0001-01-01 00:00:00 +0000 UTC
}

タイムゾーンを省略したけど、日本時間にしたい - time.ParseInLocation で指定したタイムゾーンとみなしてパースする

例えば、日本国内のみで使うなら、タイムゾーンをいちいち設定するのは大変面倒だと思います。

time.Parse では、フォーマット定義(とパースしたい文字列)でタイムゾーンが指定されていない場合 UTC と判断していましたが、
time.ParseInLocatoin では、指定したタイムゾーンと見做すことができます。

package main

import (
  "fmt"
  "time"
)

func main() {
  loc, _ := time.LoadLocation("Asia/Tokyo")

  // time.ParseInLocation は、フォーマット定義でタイムゾーンが指定されていない場合
  // loc で指定されたタイムゾーンとしてパースします 
  layout := "Jan 2, 2006 at 3:04pm"
  value := "Jul 3, 2019 at 8:07pm"
  t, e := time.ParseInLocation(layout, value, loc)

  if e != nil {
    fmt.Println(e)
  }

  // 上記の場合、 loc が日本なので、 JST とみなします
  fmt.Println(t)
  // 2019-07-03 20:07:00 +0900 JST



  // time.Pasere の場合は UTC とみなします
  layout = "Jan 2, 2006 at 3:04pm"
  value = "Jul 3, 2019 at 8:07pm"
  t, e = time.Parse(layout, value)

  if e != nil {
    fmt.Println(e)
  }

  fmt.Println(t)
  // 2019-07-03 20:07:00 +0000 UTC



  // フォーマット定義にタイムゾーンが指定されている場合には、指定されたタイムゾーン通りにパースします
  layout = "Jan 2, 2006 at 3:04pm (MST)"
  value = "Jul 3, 2019 at 8:07pm (PST)"
  t, e = time.ParseInLocation(layout, value, loc)

  if e != nil {
    fmt.Println(e)
  }

  fmt.Println(t)
  // 2019-07-03 20:07:00 +0000 PST
}

43
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
24