はじめに
Goのtimeパッケージ
で「次の水曜日の18:30」を作る方法を備忘録として残します。ここではエラー処理は省略します。
作ったコードは以下の通りです。
// ロケーション情報を取得
loc, _ := time.LoadLocation("Asia/Tokyo")
// 指定ロケーション(Asia/Tokyo)の現在時刻を取得
now := time.Now().In(loc)
// 指定ロケーション(Asia/Tokyo)の18:30を作成
next := time.Date(now.Year(), now.Month(), now.Day(), 18, 30, 0, 0, loc)
// 水曜日まで進める
d := time.Wednesday - next.Weekday()
if d <= 0 {
d += 7
}
next = next.AddDate(0, 0, int(d))
fmt.Println(next)
コードの説明
timeパッケージのドキュメントはこちらにあります。詳細ドキュメントを参照してください。ここでは上記のコードの説明だけを簡単に記載します。
ロケーション情報を取得
ローカルPC上や固定のサーバ上で動作させる場合local指定でもいいと思いますが、時差のある場所で動作させる場合に困るのでロケーションはAsia/Tokyo
を指定しました。
loc
はtimeパッケージ
のtype Location
です。
loc, _ := time.LoadLocation("Asia/Tokyo")
仕様はこちら
func LoadLocation
現在時刻を取得
上で作ったloc
を使って、現在時刻("取得日"と表現します)を取得します。
now := time.Now().In(loc)
ロケーション指定しない場合は次のようにfunc (Time)In
を使わずに書きます。
now := time.Now()
仕様はこちら
func Now
func (Time)In
18:30を作成する
他にも方法はあると思いますが、timeパッケージ
のexampleにならった方法にしました。(Durationのexampleを参照)
func Date
は年月日と時刻を与えてtype Time
を取得する関数です。
年月日には上で取得した現在時刻(取得した日付)を使うことで、現在時刻を"次の水曜日"を探す基準にしています。
func Date
の引数の時刻部分はint
なので使い勝手がいいです。
next := time.Date(now.Year(), now.Month(), now.Day(), 18, 30, 0, 0, loc)
仕様はこちら
func Date
次の水曜日まで進める
曜日はtimeパッケージ
のtype Weekday
でiota
を使ってSunday=0としてSaturday=6まで連番で定義されているので、水曜日と"取得日"の曜日の差分を使って次の水曜日に進めます。(この方法は@tenntennさんに教えてもらいました)
"取得日"の曜日はfunc (Time)Weekday
で取得します。
差分d==0の場合は該当曜日が"取得日"と同じことを表します。"取得日"が木曜日など該当曜日=水曜日よりも後の場合はd<0となるため、d<=0の場合は+7日して次週の日程とします。
d := time.Wednesday - next.Weekday()
if d <= 0 {
d += 7
}
日付を進めるためにはfunc (Time)AddDate
を使います。この関数はyear, month, dayを引数に取り、指定されただけ日付を進めます。1日ずつ進めるには第三引数day=1を指定します。
next = next.AddDate(0, 0, int(d))