現在時刻から日付だけを取り出す(今日の0:00)を作りたい時の話です。
Truncate()を使う
Time型にはTruncateメソッドが用意されていて、指定した大きさ以下の時刻を切り捨ててくれます。
func (t Time) Truncate(d Duration) Time
Truncate returns the result of rounding t down to a multiple of d (since the zero time). If d <= 0, Truncate returns t unchanged.
これに1日(24時間)を指定すれば簡単に日付を取り出せる気がします。
package main
import (
"time"
)
func main() {
t, _ := time.Parse( time.ANSIC, "Fri Feb 7 13:58:00 2014" )
println(t.Truncate( 24 * time.Hour ).Format(time.ANSIC))
}
Fri Feb 7 00:00:00 2014
上手く行っているように見えますが、これはあまりおすすめしません。なぜなら、
package main
import (
"time"
)
func main() {
t := time.Now()
println(t.Truncate( 24 * time.Hour ).Format(time.ANSIC))
}
Fri Feb 7 09:00:00 2014
こんな感じでタイムゾーンがUTCで無い時は時差分が残ってしまうからです。(Now()はLocationとして"Local"、Linuxの場合は/etc/localtimeを持ちます。Parse()はUTCになります。)
他のメソッドと違い、Truncateはタイムゾーンを考慮してくれないんですね。これは実装のdiv()あたりを読むとそんな感じになっていることがわかります。
Add()を併用する
そんな訳で、こんな感じにしないと上手く行きません。
package main
import (
"time"
)
func main() {
t := time.Now()
t = t.Truncate( time.Hour ).Add( - time.Duration(t.Hour()) * time.Hour )
println(t.Format(time.ANSIC))
}
Hourはタイムゾーンを意識した値が帰るので、これを併用すれば意図通りに時刻を切り捨てることが出来ます。
Timeはタイムゾーンとあわせて抽象化したオブジェクトだと理解しているので、出来ればTruncateもUNIXタイムで単純に計算するのではなくてタイムゾーンを意識して動いて欲しい気もします。個人的には。