Goではtime.Time
を使用して日時とタイムゾーンを扱う
time.Time
の取得
現在時刻の取得
now := time.Now()
fmt.Println("現在時刻:", now)
特定の日時の取得
tz, _ := time.LoadLocation("America/Los_Angeles")
future := time.Date(2015, time.October, 21, 7, 28, 0, 0, tz)
fmt.Println("指定日時:", future)
タイムゾーンの指定
jst, _ := time.LoadLocation("Asia/Tokyo")
jstTime := time.Date(2021, time.June, 1, 12, 0, 0, 0, jst)
fmt.Println("JST:", jstTime)
time.Duration
の扱い
時間の加算
fiveMinutes := 5 * time.Minute
tenSeconds := time.Duration(10) * time.Second
now := time.Now()
fmt.Println("5分後:", now.Add(fiveMinutes))
fmt.Println("10秒後:", now.Add(tenSeconds))
日時の比較
now := time.Now()
past := time.Date(1955, time.November, 12, 6, 38, 0, 0, time.UTC)
duration := now.Sub(past)
fmt.Println("過去から現在までの差分:", duration)
データ変換
日時フォーマット変換
now := time.Now()
formattedTime := now.Format(time.RFC3339Nano)
fmt.Println("フォーマット変換:", formattedTime)
文字列からtime.Time
への変換
timeString := "2021-06-01T12:00:00+09:00"
parsedTime, _ := time.Parse(time.RFC3339, timeString)
fmt.Println("パース結果:", parsedTime)
翌月を計算するときの注意点
Goで日付の計算を行う際は、時に翌月の計算に注意が必要になる。
AddDate()
で日付や月、年の加減算を計算できる。
基本的な翌月の計算
AddDate(0, 1, 0)
で計算できる
jst, _ := time.LoadLocation("Asia/Tokyo")
now := time.Date(2021, 6, 8, 20, 56, 0, 0, jst)
nextMonth := now.AddDate(0, 1, 0)
fmt.Println("翌月:", nextMonth) // 翌月: 2021-07-08 20:56:00 +0900 JST
正規化について
日付を計算した結果、存在しない値になった時に「正規化」と呼ばれる変換が行われる。
例えば、6/31という値を格納すると、7/1に変換される。
jst, _ := time.LoadLocation("Asia/Tokyo")
endOfMonth := time.Date(2021, 5, 31, 0, 0, 0, 0, jst)
nextMonthEnd := endOfMonth.AddDate(0, 1, 0)
fmt.Println("月末の翌月:", nextMonthEnd) // 月末の翌月: 2021-07-01 00:00:00 +0900 JST
月末を考慮しながら翌月を計算する実装例
package main
import (
"fmt"
"time"
)
func NextMonth(t time.Time) time.Time {
year1, month2, day := t.Date()
first := time.Date(year1, month2, 1, 0, 0, 0, 0, time.UTC)
year2, month2, _ := first.AddDate(0, 1, 0).Date()
nextMonthTime := time.Date(year2, month2, day, 0, 0, 0, 0, time.UTC)
if month2 != nextMonthTime.Month() {
return first.AddDate(0, 2, -1) // 翌月末
}
return nextMonthTime
}
func main() {
jst, _ := time.LoadLocation("Asia/Tokyo")
endOfMonth := time.Date(2021, 5, 31, 0, 0, 0, 0, jst)
nextMonthEnd := NextMonth(endOfMonth)
fmt.Println("月末の翌月:", nextMonthEnd) // 月末の翌月: 2021-06-30 00:00:00 +0000 UTC
}
参考