Closed5

time.Since()とtimeパッケージについて深ぼる

ハガユウキハガユウキ

[到達していたい状態]

  • timeパッケージとは何かを人に説明できる。
  • time.Since()を使いこなせる。

[やること]

  • timeパッケージについて記事や本で調べる
ハガユウキハガユウキ

パッケージタイムは時間の計測と表示の機能を提供します。
暦計算は常にグレゴリオ暦を想定しており、うるう秒はありません。

要するにtime packageは時間の計測と表示の機能を提供している。
https://pkg.go.dev/time

現在の時刻を取得する

Goでは現在の時刻を、time.Time型で表します。

timeパッケージのNow関数を利用すると、現在時刻を表すtime.Time型の値を取得できます。

func main() {
	t := time.Now()
	fmt.Printf("型: %T\n", t) // => 型: time.Time
	fmt.Printf("値: %v\n", t) // => 値: 2023-06-24 12:37:29.155645 +0900 JST m=+0.000126510
}

指定した時刻を生成する

timeパッケージのDate関数を使えば、指定した時刻を表すtime.Time型の値を生成できます。
以下では、時間を全て0にしたtime.Time型の値を生成できます。

func main() {
	now := time.Now()
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
	fmt.Printf("型: %T\n", today) // => 型: time.Time
	fmt.Printf("値: %v\n", today) // => 値: 2023-06-24 00:00:00 +0900 JST
}

time.Dateの最後に与えられている引数はタイムゾーンを表しています。time.Localは実行環境のタイムゾーンと同等の日時を得られます。time.UTCを引数として渡した場合、タイムゾーンがUTCの日時を取得できます。

func main() {
	now := time.Now()
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
	fmt.Printf("型: %T\n", today) // => 型: time.Time
	fmt.Printf("値: %v\n", today) // => 値: 2023-06-24 00:00:00 +0000 UTC
}

UTCの時刻をローカルの時刻に変換する

Localメソッドを利用することで、時刻のタイムゾーンをローカルのタイムゾーンに変換した新しい時刻を生成できます。

func main() {
	now := time.Now()
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
	fmt.Printf("型: %T\n", today) // => 型: time.Time
	fmt.Printf("値: %v\n", today) // => 値: 2023-06-24 00:00:00 +0000 UTC

	//  JSTの時刻はUTCの時刻に比べて、9時間プラスされている
	jst := today.Local()
	fmt.Printf("値: %v\n", jst) // => 値: 2023-06-24 09:00:00 +0900 JST
}

また、UTCメソッドで、時刻のタイムゾーンをUTCに変換した新しい時刻を生成できます。

func main() {
	now := time.Now()
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
	fmt.Printf("型: %T\n", today) // => 型: time.Time
	fmt.Printf("値: %v\n", today) // => 値: 2023-06-24 00:00:00 +0000 UTC

	//  JSTの時刻はUTCの時刻に比べて、9時間プラスされている
	jst := today.Local()
	fmt.Printf("値: %v\n", jst) // => 値: 2023-06-24 09:00:00 +0900 JST

	//  UTCの時刻はJSTの時刻に比べて、9時間マイナスされている
	utc := jst.UTC()
	fmt.Printf("値: %v\n", utc) // => 値: 2023-06-24 00:00:00 +0000 UTC
}

指定時間のスリープ

timeパッケージに定義されているSleep関数を利用することで、実行しているゴルーチンを指定した時間停止できます(引数にはtime.Duration型の値を指定する)。
ちなみに、時間の間隔を表現したい場合、time.Duration型を利用します。

func main() {
	time.Sleep(5 * time.Second)
	fmt.Println("5秒間停止させました")
}

https://qiita.com/taizo/items/acbee530bd33c803dab4

ハガユウキハガユウキ

time.Since()を利用して、処理時間を計測する

timeパッケージのSince関数を用いることで、処理にかかった時間を計測できます。
計測地点を自分で設定して、計測したい処理の後で、Since関数を呼び出します。

func main() {
	t := time.Now()
	time.Sleep(5 * time.Second)
	fmt.Printf("経過時刻 %vms\n", time.Since(t).Milliseconds())
}

https://public-constructor.com/golang-elapsed-time/

ハガユウキハガユウキ

tickerは一定の間隔で繰り返し何かをしたいときに使う

tickerは一定の間隔で繰り返し何かをしたいときに使います。
(厳密にいうと、tickerと、ticker.Cチャネルを使うことで、定期的に繰り返し実行できます。)

tickerを生成することで、指定された間隔で定期的に値をticker.Cチャネルに送信します。ticker.Cチャネルが値を受信した場合のみ、処理を実行するように実装すれば、定期的に繰り返し実行することができます。

func main() {
	// time.Tickerは、指定された間隔で定期的に値を送信するための機能を提供します。
	// 5秒ごとに値が送信されるtime.Tickerを作成しています。
	ticker := time.NewTicker(2 * time.Second)
	done := make(chan bool)

	go func() {
		for {
			select {
			case <-done:
				// doneチャネルが値を受信した場合、以下の処理が実行される
				return
			// ticker.Cは、time.Ticker型の値から読み取れるチャネルです
			// ticker.Cチャネルは、time.Tickerが設定された間隔ごとに現在の時刻を送信します。
			case t := <-ticker.C:
				// ticker.Cチャネルが値を受信した場合、以下の処理が実行される
				fmt.Println("Tick at", t)
			}
		}
	}()

	time.Sleep(10 * time.Second)
	// tickerをオフにして、tickerから送信されるのをストップする
	ticker.Stop()

	// doneというチャネルにtrueを送信する
	done <- true
	fmt.Println("Ticker stopped")
}

実行結果

➜  cmd go run main.go
Tick at 2023-06-24 13:35:43.555469 +0900 JST m=+2.000965444
Tick at 2023-06-24 13:35:45.555745 +0900 JST m=+4.001222992
Tick at 2023-06-24 13:35:47.555711 +0900 JST m=+6.001171560
Tick at 2023-06-24 13:35:49.555755 +0900 JST m=+8.001197303
Tick at 2023-06-24 13:35:51.555797 +0900 JST m=+10.001221344
Ticker stopped

https://gobyexample.com/tickers

このスクラップは2023/06/24にクローズされました