形成肌肉记忆是一件好事,大脑可以从低级工作中解放出来在潜意识思考高级问题。 锻炼肌肉记忆的一种方法就是将需要训练的内容整理出来,反复练习即可。
Python中的 datetime
模块已经相当熟练,几乎不再需要翻文档。 Golang 写得还不多,
同样整理一遍,多加练习。
如果想不起来,多翻翻文档,大多数情景在标准库里都可以解决。
package main
import (
"fmt"
"log"
"time"
)
func main() {
var err error
// 1. 当前时间
log.Println("===== 1. current time =====")
// 1.1 获取当前时间 (带时区信息)
now := time.Now()
log.Printf("now: %s", now)
// 1.2 获取当前时间戳 int64 (获取任何 Time 对象的时间戳)
timestamp := time.Now().Unix()
log.Printf("timestamp: %d", timestamp)
// 1.3 获取当前时间戳纳秒 int64 (获取任何 Time 对象的时间戳)
timestampNano := time.Now().UnixNano()
log.Printf("timestampNano: %d", timestampNano)
// 1.4 获取 UTC 时间 (获取任何 Time 对象对应的 UTC 时间)
utc := time.Now().UTC()
log.Printf("utc: %s", utc)
// 2. 格式化
// Format 的字符串不是 UNIX STRFTIME(3)
// 而是 golang 自己定的规则,cheatsheet 请参考
// https://yourbasic.org/golang/format-parse-string-time-date-example/
// 特别说明:
// - 24-小时格式时,无法指定不带 0 前缀的小时格式
// - 表示半夜时间不可使用 24:00 只能带上日期一起使用
// - 不支持润秒 23:59:60 , golang time 包假设没有润秒的公历
// 格式化记忆方法,考虑以下表示法,更容易理解
// 01/02 03:04:05PM '06 -0700
// 表示 -7 时区 , 2006 年,(上午)3点4分5秒,1月2日
// 那么想表达24小时制时,应该使用什么呢? 15:04:05
// 完整格式速查
// Type Option
// -------------------
// Year 06 2006
// Month 01 1 Jan January
// Day 02 2 _2 (width two, right justified)
// Weekday Mon Monday
// Hours 03 3 15
// Minutes 04 4
// Seconds 05 5
// ms us ns .000 .000000 .000000000
// ms us ns .999 .999999 .999999999 (remove trailing zero)
// am/pm PM pm
// Timezone MST
// Offset -0700 -07 -07:00 Z0700 Z07:00
log.Println("")
log.Println("")
log.Println("===== 2. format (Time -> string) =====")
// 2.1 最常见的格式
log.Printf("%%Y-%%m-%%d %%H:%%M:%%S: %s",
now.Format("2006-01-02 15:04:05"))
// 2.2 RFC3389 格式
log.Printf("RFC3389: %s", now.Format(time.RFC3339))
// 2.3 ISO886 周
_, w := now.ISOWeek()
log.Printf("ISO8601 Week: %d", w)
// 3. 从字符串得到对应的时间
log.Println("")
log.Println("")
log.Println("===== 3. parse (string -> Time) =====")
// 3.1 RFC3389 (带时区)
var t2 time.Time
rfc3339 := "2019-01-20T16:45:34+08:00"
t2, err = time.Parse(time.RFC3339, rfc3339)
if err != nil {
log.Fatal(err)
}
log.Printf("\"%s\" => %s", rfc3339, t2)
// 3.2 日期 没有时区 (需加上,否则默认得到 UTC 时间)
date := "2019-07-11"
input := fmt.Sprintf("%s+0800", date)
t2, err = time.Parse("2006-01-02-0700", input)
if err != nil {
log.Fatal(err)
}
log.Printf("\"%s\" => %s", date, t2)
// 3.3 日期时间 没有时区 (需加上,否则默认得到 UTC 时间)
date2 := "2008-12-31 09:12:47"
input2 := fmt.Sprintf("%s +0800", date2)
t2, err = time.Parse("2006-01-02 15:04:05 -0700", input2)
if err != nil {
log.Fatal(err)
}
log.Printf("\"%s\" => %s", date2, t2)
// 3.4 时间,有小数点 (需加上,否则默认得到 UTC 时间)
date3 := "15:37:00.965376860"
t2, err = time.Parse("15:04:05.000000000", date3)
if err != nil {
log.Fatal(err)
}
log.Printf("\"%s\" => %s", date3, t2)
// 4. 从时间戳得到时间
// 定义上时间戳本身是 UTC ,转换出来会根据系统配置设计设置时区
log.Println("")
log.Println("")
log.Println("===== 4. parse (int timestamp -> Time) =====")
i1 := int64(1562922019)
t3 := time.Unix(i1, 0)
log.Printf("%d => %v", i1, t3)
// 5. 时间的比较
log.Println("")
log.Println("")
log.Println("===== 5. compare =====")
// 需注意, == 操作会比较小数点以后的
// Equal 操作则会考虑时区
nt1 := time.Now()
nt2 := time.Now()
log.Printf("%v > %v ?: %t", nt1, nt2, nt1.After(nt2))
log.Printf("%v == %v ?: %t", nt1, nt2, nt1.Equal(nt2))
log.Printf("%v < %v ?: %t", nt1, nt2, nt1.Before(nt2))
// 6. 时间计算
log.Println("")
log.Println("")
log.Println("===== 5. calculate =====")
after := time.Now()
// 6.1 差值 (都利用 Sub 方法) 返回 time.Duration
d1 := now.Sub(after)
log.Printf("%v = now - %v", d1, after)
d2 := after.Sub(now)
log.Printf("%v = %v - now", d2, after)
// 6.2 加减操作 () 参数为 time.Duration
second := 240
nt3 := now.Add(time.Duration(second) * time.Second)
log.Printf("now + %ds = %v", second, nt3)
nt4 := now.Add(-time.Duration(second) * time.Second)
log.Printf("now - %ds = %v", second, nt4)
// 7. 时区操作
// 时区定义请参考 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
log.Println("")
log.Println("")
log.Println("===== 7. timezone =====")
var zoneName string
var location *time.Location
log.Printf("now location: \"%v\"", now.Location())
// 7.1 加载地区信息
zoneName = "US/Alaska"
location, err = time.LoadLocation(zoneName)
log.Printf("\"%s\" location: %v", zoneName, location)
// 7.2 得到不同时区的时间
log.Printf("now in \"%v\": %v", location, now.In(location))
zoneName = "Asia/Tokyo"
location, err = time.LoadLocation(zoneName)
log.Printf("\"%s\" location: %v", zoneName, location)
log.Printf("now in \"%v\": %v", location, now.In(location))
}