LoginSignup
80
67

More than 3 years have passed since last update.

Goのtimeパッケージチートシート

Last updated at Posted at 2018-03-21

はじめに

以下は 2020年6月に実行した結果です。
go1.14.3を使用しています

現在時刻を取得

ʕ◔ϖ◔ʔ
package main

import (
    "fmt"
    "time"
)

func main() {

    // tはtime.Time型
    t := time.Now()
    fmt.Println(t) // 2020-06-01 19:29:04.82858 +0900 JST m=+0.000333352

    t = time.Date(2020, 6, 1, 17, 44, 13, 0, time.Local)
    fmt.Println(t)              // 2020-06-01 17:44:13 +0900 JST
    fmt.Println(t.Year())       // 2020
    fmt.Println(t.YearDay())    // 153 通算日(1~366)
    fmt.Println(t.Month())      // June
    fmt.Println(t.Weekday())    // Monday
    fmt.Println(t.Day())        // 1
    fmt.Println(t.Hour())       // 17
    fmt.Println(t.Minute())     // 44
    fmt.Println(t.Second())     // 13
    fmt.Println(t.Nanosecond()) // 0
    fmt.Println(t.Zone())       // JST 32400
}

月・曜日

Go
package main

import (
    "fmt"
    "time"
)

func main() {

    t := time.Now()

    // 月は1からの連番
    if time.January == 1 {

        /*
         * ※ time.goパッケージにて定数を定義しているが、String()を実装している為、Printlnの出力は数値ではない
         */
        fmt.Println(time.January)  // January
        fmt.Println(time.December) // December
    }

    // 曜日は日曜日から0スタートの連番
    if time.Sunday == 0 {
        fmt.Println(time.Sunday)   // Sunday
        fmt.Println(time.Saturday) // Saturday
    }

    // 日本語化
    weekDays := [...]string{"日", "月", "火", "水", "木", "金", "土"}
    fmt.Println(weekDays[t.Weekday()]) // 月
}

文字列をパースしてtime.Time型を生成

func ParseDuration(s string) (Duration, error)

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    t, _ := time.ParseDuration("1h30m")
    fmt.Println(t.Minutes()) // 90
}

時刻の加算

func (t Time) Add(d Duration) Time

Go
package main

import (
    "fmt"
    "time"
)

func main() {

    t := time.Date(2020, 12, 31, 23, 59, 59, 0, time.Local)
    fmt.Println(t) // 2020-12-31 23:59:59 +0900 JST

    t = t.Add(1 * time.Second)
    fmt.Println(t) // 2021-01-01 00:00:00 +0900 JST
}

時刻の差分

Go
package main

import (
    "fmt"
    "time"
)

func main() {

    // 2020年末
    yearEnd := time.Date(2020, 12, 31, 23, 59, 59, 999999999, time.Local)

    // 6月1日
    now := time.Date(2020, 6, 1, 0, 0, 0, 0, time.Local)

    diff := yearEnd.Sub(now)
    fmt.Println(diff) // 5135h59m59.999999999s

    // time.Sinceはtime.Now().Sub(t)のラッパー
    diff = time.Since(yearEnd)
    fmt.Println(diff) // -5135h59m59.999999999s

    diff *= -1
    fmt.Println(diff) // 5135h59m59.999999999s
}

年月日の加算・減算

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Date(2019, 12, 31, 23, 59, 59, 999999999, time.Local)

    // 加算
    t1 := t.AddDate(0, 0, 1) // AddDate(y,m,d)
    fmt.Println(t1)         // 2020-01-01 23:59:59.999999999 +0900 JST

    // 減算
    t2 := t.AddDate(0, 0, -1) // AddDate(y,m,d)
    fmt.Println(t2)         // 2019-12-30 23:59:59.999999999 +0900 JST}
}

月末を取得

2020年6月に実行した結果です

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    y := time.Now().Year()  // type int
    m := time.Now().Month() // type Month

    t := time.Date(y, m, 1, 23, 59, 59, 999999999, time.Local).AddDate(0, 1, -1)

    fmt.Println(t) // 2020-06-30 23:59:59.999999999 +0900 JST
}

時刻の比較

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    Jan := time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
    Feb := time.Date(2020, 2, 1, 0, 0, 0, 0, time.Local)
    fmt.Println(Jan.Before(Feb)) // true  (1月は2月よりも前か?)
    fmt.Println(Jan.After(Feb))  // false (1月は2月よりも後か?)
}

Before AはBよりも前か?
After AはBよりも後か?
と覚えとくと間違えない

期間内か

go
package main

import (
    "fmt"
    "time"
)

func main() {

    // 判定方法その1
    {
        first := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
        now := time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)
        end := time.Date(2020, 12, 31, 23, 59, 59, 999999999, time.UTC)

        if (first.Equal(now) || first.Before(now)) && (end.Equal(now) || end.After(now)) {
            fmt.Println("期間内")
        } else {
            fmt.Println("期間外")
        }
    }

    // 判定方法その2
    // 開始と終了をずらす
    {
        first := time.Date(2019, 12, 31, 23, 59, 59, 999999999, time.UTC)
        now := time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)
        end := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)

        if first.Before(now) && end.After(now) {
            fmt.Println("期間内")
        } else {
            fmt.Println("期間外")
        }
    }
}

if文の条件が複雑なので、関数を定義するか構造体のメソッドにすると良い

go
package main

import (
    "fmt"
    "time"
)

type Term struct {
    BeginAt time.Time
    EndAt   time.Time
}

func (term Term) Within(t time.Time) bool {

    if term.BeginAt.Equal(t) {
        return true
    }

    if term.EndAt.Equal(t) {
        return true
    }

    if term.BeginAt.After(t) {
        return false
    }

    if term.EndAt.Before(t) {
        return false
    }

    return true
}

func main() {

    now := time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)

    t := Term{
        BeginAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
        EndAt:   time.Date(2020, 12, 31, 23, 59, 59, 999999999, time.UTC),
    }
    if t.Within(now) {
        fmt.Println("期間内")
    } else {
        fmt.Println("期間外")
    }
}

文字列から時刻を生成

layoutとvalue(時刻)を指定する
layoutがなぜこのフォーマットなのかはこちらを参照

func Parse(layout, value string) (Time, error)

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Time{}
    layout := "2006/01/02"
    value := "2020/06/01"
    t, _ = time.Parse(layout, value)
    fmt.Println(t) // 2020-06-01 00:00:00 +0000 UTC

    layout = "2006年01月02日 15時04分05秒"
    value = "2020年06月01日 11時32分40秒"
    t, _ = time.Parse(layout, value)

    fmt.Println(t)         // 2018-03-03 20:01:30 +0000 UTC
    fmt.Println(t.Local()) // 2018-03-04 05:01:30 +0900 JST
}

時刻から文字列を生成

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Now()
    fmt.Println(t)                                 // 2020-06-01 20:10:25.857202105 +0900 JST m=+0.000093900
    fmt.Println(t.Format(time.RFC822))             // 01 Jun 20 20:10 JST
    fmt.Println(t.Format(time.RFC3339Nano))        // 2020-06-01T20:10:25.857202105+09:00
    fmt.Println(t.Format("2006/01/02"))            // 2020/06/01
    fmt.Println(t.Format("2006年01月02日 15時04分05秒")) // 2020年06月01日 20時10分25秒
}

その他フォーマット https://golang.org/pkg/time/#pkg-constants

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

Unix時刻との相互変換

Go
package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Now()
    fmt.Println(t.Unix())      // 1591096873
    fmt.Println(t.UnixNano())  // 1591096873618624554

    // UNIXからtime.Timeに変換
    t = time.Unix(t.Unix(), 0)
    fmt.Println(t)             // 2020-06-01 20:07:47 +0900 JST
}

タイムゾーンの指定

go
package main

import (
    "fmt"
    "time"
)

func main() {
    t1 := time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)
    fmt.Println(t1)

    t2 := time.Date(2020, 6, 1, 0, 0, 0, 0, Location())
    fmt.Println(t2)
}

// 東京のタイムゾーンを取得
//
// @return *time.Location
func Location() *time.Location {
    return time.FixedZone("Asia/Tokyo", 9*60*60)
}

参考

Goで時刻を取り扱う
逆引きGolang (日付と時刻)

80
67
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
80
67