Go言語が無かったので書いてみた。
現在時刻の取得
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now())
}
2013-06-19 21:46:14.186298 +0900 +0900
Time => Unix時刻変換
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().Unix())
}
1371646123
Unix時刻 => Time変換
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Unix(1371646123, 0))
}
ここからが面白くて、通常日付のフォーマットやパースは殆どの言語では %Y%m%d といった表記を使います。
しかしGo言語では、ある固定の数値を用いて表現する事で、いかにも日付らしく表現出来る手法を取っています。
package main
import (
"fmt"
"log"
"time"
)
func main() {
t, err := time.Parse(
"2006-01-02 15:04:05 -0700", // スキャンフォーマット
"2013-06-19 21:54:23 +0900") // パースしたい文字列
if err != nil {
log.Fatal(err)
}
fmt.Println(t)
}
Formatも同じく
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().Format("2006/01/02 15:04:05 MST"))
}
2013/06/19 22:01:01 +0900
この数値とタイムゾーン文字列で構成された文字列を、定数として提供しています。
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
この手法を使う事で、ちょっとした日付フォーマットの差異も自分のプログラムで吸収する事が出来る様になっています。初めてこの実装を見た時は戸惑いましたが、慣れると非常に心地よくなります。
おまけでもう少し。
Go言語では、timeパッケージを使って経過時間(Duration)も表す事が出来ます。
time.Sleep(1 * time.Second) // 1秒
time.Sleep(2 * time.Minute) // 2分
time.Sleep(3 * time.Hour) // 3時間
1時間と61秒は、61分
(1 * time.Hour + 61 * time.Second).Minutes()
日付の加算も出来る。閏年も完璧。
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Date(2012, 2, 28, 12, 13, 14, 0, time.UTC).AddDate(0, 0, 1))
// 2012-02-29 12:13:14 +0000 UTC
fmt.Println(time.Date(2012, 2, 29, 12, 13, 14, 0, time.UTC).AddDate(0, 0, 1))
// 2012-03-01 12:13:14 +0000 UTC
}
このDurationを使って、数秒後に発動するイベント(channel)も作れます。例えば、3秒以内に CTRL-C を押すかのイベントループ
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
s := make(chan os.Signal)
signal.Notify(s, syscall.SIGINT)
select {
case <- time.After(3 * time.Second):
fmt.Println("Timeout")
break
case <- s:
fmt.Println("Pressed CTRL-C")
break
}
}
3秒後にコールバック
package main
import (
"fmt"
"os"
"time"
)
func main() {
time.AfterFunc(3 * time.Second, func() {
fmt.Println("Timeout")
os.Exit(0)
})
select {}
}
とまぁ、とても便利になっています。Go言語触った事ないとか、かなりヤバいです。「えーマジGo言語童貞!?」
「Go言語童貞が許されるのは小学生までだよね」
「キモーイ」
「キャハハハハハハ」