日付と時刻

日付と時刻 #

現在の日時を取得する #

time.Now で現在の日時のオブジェクトを取得する。 タイムゾーンは実行しているシステムのタイムゾーンになる。 (The Go Playground ではシステムのタイムゾーンが UTC になっている。)

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	fmt.Println(t) // == 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

任意の日時を取得する #

任意の日時を取得したい場合は time.Date を使う。 引数は「年、月、日、時、分、秒、ナノ秒、タイムゾーン」を指定する。

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2020, 12, 31, 23, 59, 1, 0, time.UTC)
	fmt.Println(t) // == 2020-12-31 23:59:01 +0000 UTC
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

日時オブジェクトから年月日などを取得する #

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC)
	// 年
	fmt.Println(t.Year()) // == 2020
	// 月
	fmt.Println(t.Month()) // == January
	// 日
	fmt.Println(t.Day()) // == 2
	// 時
	fmt.Println(t.Hour()) // == 3
	// 分
	fmt.Println(t.Minute()) // == 4
	// 秒
	fmt.Println(t.Second()) // == 5
	// ナノ秒
	fmt.Println(t.Nanosecond()) // == 6
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

タイムゾーンが UTC の日時を取得する #

package main

import (
	"fmt"
	"time"
)

func main() {
	// Time.UTC メソッドで UTC の日時に変換される
	t := time.Now().UTC()
	fmt.Println(t) // == 2009-11-10 23:00:00 +0000 UTC

	// time.Date での日時作成時のタイムゾーンに time.UTC を指定して UTC の日時を取得する
	t = time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC)
	fmt.Println(t) // == 2020-01-02 03:04:05.000000006 +0000 UTC
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

タイムゾーンが実行システムのタイムゾーンである日時を取得する #

package main

import (
	"fmt"
	"time"
)

func main() {
	// Time.Local メソッドで実行システムのタイムゾーンの日時に変換される
	// (The Go Playground ではシステムのタイムゾーンが UTC になっている)
	t := time.Now().Local()
	fmt.Println(t) // == 2009-11-10 23:00:00 +0000 UTC

	// time.Date での日時作成時のタイムゾーンに time.Local を指定して実行システムのタイムゾーンの日時を取得する
	t = time.Date(2020, 1, 2, 3, 4, 5, 6, time.Local)
	fmt.Println(t) // == 2020-01-02 03:04:05.000000006 +0000 UTC
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

任意のタイムゾーンの日時を取得する #

タイムゾーンオブジェクトの初期化には func LoadLocation(name string) (*Location, error) を使う。

name にはタイムゾーンの文字列を指定する。 タイムゾーンの文字列は IANA Time Zone database に記載されているものが利用できる。

任意のオフセットのタイムゾーンを作成したい場合は func FixedZone(name string, offset int) *Location が使える。

name には任意のタイムゾーン名を、offset にはオフセットの秒数を指定する。

package main

import (
	"fmt"
	"time"
)

func main() {
	// タイムゾーンの初期化
	loc, err := time.LoadLocation("Asia/Tokyo")
	if err != nil {
		panic(err)
	}

	// time.Date にタイムゾーンオブジェクトを渡して任意のタイムゾーンの日時オブジェクトを作成する
	t := time.Date(2020, 1, 2, 3, 4, 5, 6, loc)
	fmt.Println(t) // == 2020-01-02 03:04:05.000000006 +0900 JST

	// 任意のオフセットのタイムゾーンを初期化
	loc = time.FixedZone("UTC-8", -8*60*60)
	t = time.Date(2020, 1, 2, 3, 4, 5, 6, loc)
	fmt.Println(t) // == 2020-01-02 03:04:05.000000006 -0800 UTC-8
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

日時を文字列に変換する #

日時を文字列に変換するには func (t Time) Format(layout string) string を使う。

layout には time パッケージ独自の日時フォーマット指定子を入れる。

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()

	// Time.Format による文字列への変換
	fmt.Println(t.Format("2006-01-02T15:04:05Z07:00")) // == 2009-11-10T23:00:00Z

	// 前記の指定子を分解すると以下の通り

	// 年
	fmt.Println(t.Format("2006")) // == 2009

	// 月
	fmt.Println(t.Format("01")) // == 11

	// 日
	fmt.Println(t.Format("02")) // == 10

	// 時
	fmt.Println(t.Format("15")) // == 23

	// 分
	fmt.Println(t.Format("04")) // == 00

	// 秒
	fmt.Println(t.Format("05")) // == 00

	// タイムゾーンとオフセット
	fmt.Println(t.Format("Z07:00")) // == Z

	// 年月日
	fmt.Println(t.Format("2006-01-02")) // == 2009-11-10

	// RFC3339 など頻用するものは const として定義されている
	fmt.Println(t.Format(time.RFC3339)) // == 2009-11-10T23:00:00Z
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

文字列を日時に変換する #

文字列から日時への変換には func Parse(layout, value string) (Time, error) を使う。

value は変換したい文字列で、layout には time パッケージ独自の日時フォーマット指定子を入れる。

package main

import (
	"fmt"
	"time"
)

func main() {
	// 文字列から日時へ変換
	t, err := time.Parse("2006-01-02", "1999-12-31")
	fmt.Printf("%+v, %+v\n", t, err) // == 1999-12-31 00:00:00 +0000 UTC, <nil>

	// 存在しない日時の文字列を変換しようとするとエラーになる
	t, err = time.Parse("2006-01-02", "1999-02-29")
	fmt.Printf("%+v, %+v\n", t, err) // == 0001-01-01 00:00:00 +0000 UTC, parsing time "1999-02-29": day out of range
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

ユニックスタイムと日時の相互変換 #

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(1999, 12, 31, 23, 59, 59, 0, time.UTC)

	// 日時からユニックスタイムへ変換
	ut := t.Unix()
	fmt.Println(ut) // == 946684799

	// ユニックスタイムから日時へ変換
	t2 := time.Unix(ut, 0)
	fmt.Println(t2) // == 1999-12-31 23:59:59 +0000 UTC
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

日時の加算と減算 #

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(1999, 12, 31, 23, 59, 59, 0, time.UTC)

	// Time.Add メソッドで 1 分後の日時を取得
	t1 := t.Add(60 * time.Second)
	fmt.Println(t1) // == 2000-01-01 00:00:59 +0000 UTC

	// 1 日前の日時を取得
	t2 := t.Add(-24 * 60 * 60 * time.Second)
	fmt.Println(t2) // == 1999-12-30 23:59:59 +0000 UTC
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

日時同士の比較 #

package main

import (
	"fmt"
	"time"
)

func main() {
	t1 := time.Date(1999, 12, 31, 23, 59, 59, 0, time.UTC)
	t2 := time.Date(1999, 12, 31, 23, 59, 59, 0, time.UTC)
	t3 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)

	// Time.Before で呼び出し元の日時が引数の日時よりも過去であるかどうかを判定する
	fmt.Println(t1.Before(t2)) // 同一なら false
	fmt.Println(t1.Before(t3)) // t1 が t3 より過去なので true

	// Time.After で呼び出し元の日時が引数の日時よりも未来であるかどうかを判定する
	fmt.Println(t1.After(t2)) // 同一なら false
	fmt.Println(t1.After(t3)) // t1 が t3 より過去なので false
	fmt.Println(t3.After(t1)) // t3 が t1 より未来なので true

	// Time.Equal で呼び出し元の日時と引数の日時が同一であるかどうかを判定する
	fmt.Println(t1.Equal(t2)) // 同一なので true
	fmt.Println(t1.Equal(t3)) // 異なるので false
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

日時同士の差 #

package main

import (
	"fmt"
	"time"
)

func main() {
	t1 := time.Date(2000, 2, 1, 0, 0, 0, 0, time.UTC)
	t2 := time.Date(2000, 3, 1, 0, 0, 0, 0, time.UTC)

	// Time.Sub メソッドで呼び出し元の日時と引数の日時の差を算出する
	diff := t2.Sub(t1)
	fmt.Printf("difference = %v\n", diff) // == difference = 696h0m0s
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time

任意の日時の存在を確認する #

time.Parse は存在しない日時を受け取るとエラーを出すので、存在する日時であるかどうかの判定に使うことができる。

package main

import (
	"fmt"
	"time"
)

func main() {
	if _, err := time.Parse("2006-01-02", "2001-02-29"); err != nil {
		fmt.Println(err) // == parsing time "2001-02-29": day out of range
	}
}

play_circleRun open_in_newRun In The Playground

参考ドキュメント: time