時間計算是頗複雜的一件事情,只能挑一些常用來說明
1.取得現在時間,這時區是根據執行這段語法的主機,所以主機如果設定成UTC就會呈現UTC的時間
current := time.Now()
//2020-09-22 11:50:21.646586 +0800 CST m=+0.000084078
2.取得時間的timestamp
st := time.Now().Unix()
//1600746812
3.timestamp轉回time格式
d := time.Unix(1600746812, 0)
//2020-09-22 11:55:51 +0800 CST
4.取得year,month,day的數值
y, m, d := time.Now().Date()
//這時侯的m是time.month型態,所以如果要換成int的話,直接用int(m)處理就可以
//2020 September 22
5.取得hour,min,sec的數值
h := time.Now().Hour()
m := time.Now().Minute()
s := time.Now().Second()
//hour:13 minute:53 second:55
6.數值轉成time
qq := time.Date(2020, 9, 20, 0, 0, 0, 0, time.Local)
//2020-09-20 00:00:00 +0800 CST
7.format,golang的format格式有點奇妙.. 有興趣可以看一下這篇文章 2006-01-02 15:04:05
qq := time.Now().Format("2006-01-02 15:04:05")
//2020-09-20 15:23:10
要如何轉成指定時區的時間呢,可以透過time.LoadLocation進行轉換,比使用單純的加減時間準確
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
var localLocation *time.Location
var err error
//設定時區為UTC
localLocation, err = time.LoadLocation("UTC")
if err != nil {
return
}
//t.In(localLocation) local時區轉換成utc時區
fmt.Println("utc timestamp:", t.In(localLocation).Unix(), "local time:", t.In(localLocation), "utc time:", t)
//utc timestamp: 1600754558 local time: 2020-09-22 06:02:38.612689 +0000 UTC utc time: 2020-09-22 14:02:38.612689 +0800 CST m=+0.000082078
}
//取得今天的0點0分 timestamp
y, m, d := t.Date()
utc := time.Date(y, m, d, 0, 0, 0, 0, localLocation).Unix()
local := time.Date(y, m, d, 0, 0, 0, 0, time.Local).Unix()
//local: 1600704000 utc: 1600732800
package main
import (
"fmt"
"time"
)
func main() {
//計算start到end花了多少時間,可以拿來計算func執行多久
start := time.Now()
//也可以寫這樣子 time.Sleep(time.Duration(5) * time.Second)
time.Sleep(5 * time.Second)
end := time.Since(start)
fmt.Println(end)
//Add 時間加上特定時間後的時間
add := start.Add(5 * time.Second)
fmt.Println("before:", start, "after:", add)
//before: 2020-09-22 14:31:40.656482 +0800 CST m=+0.000087995 after: 2020-09-22 14:31:45.656482 +0800 CST m=+5.000087995
//二個時間的差距
start2 := start.Add(-5 * time.Second)
sub := start.Sub(start2)
fmt.Println(sub)
//5s
}
可以當成是個定時器,每n時間執行什麼事情
package main
import (
"fmt"
"time"
)
func main() {
d := time.Duration(time.Second * 2)
//設定一個ticker,每二秒
t := time.NewTicker(d)
defer t.Stop()
var count = 0
for {
<-t.C
if count == 10 {
fmt.Println("stop do something")
t.Stop()
break
}
fmt.Println("do something")
count++
}
}
golang原生對json的操作是主要有二個
1.Marshal:把struct轉成[]byte
2.Unmarshal:把[]byte轉成struct,官方有段註解說明對應的型態
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
// bool, for JSON booleans
// float64, for JSON numbers
// string, for JSON strings
// []interface{}, for JSON arrays
// map[string]interface{}, for JSON objects
// nil for JSON null
package main
import (
"encoding/json"
"fmt"
)
type ColorGroup struct {
ID int
Name string
Colors []string
}
const test = `
{"ID":2,"Name":"QQ","Colors":["A","B","C","D"]}
`
func main() {
//Marshal:struct to []byte
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
//把struct轉成[]byte
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(b, string(b))
var g ColorGroup
//把json轉到strcut
err3 := json.Unmarshal([]byte(test), &g)
if err3 != nil {
fmt.Println("error3:", err3)
}
fmt.Println("g:", g)
}
如果會大量使用到Marshal/Unmarshal或是json object很巨大,又對效能很敏感的話,可以考慮使用這套件
json-iterator,使用方案跟原生的一樣,可以無痛接軌XD
import jsoniter "github.com/json-iterator/go"
//記得把"encoding/json"原生套件移除
var json = jsoniter.ConfigCompatibleWithStandardLibrary
//宣告一個全域變動json的物件,這樣子就可以使用json.Marshal/json.Unmarshal
這邊有二個套件推薦,可以視情形選擇使用
1.jsonparser:優點,抓取的path裡面文字有包含標號.時不會被影響到,ex mail或是ip
2.gjson:主要優點是可以用類似正則式的方式去操作,缺點是他的path是用.來分割,所以遇到key值是mail或是ip這類格式的資料時就會走鐘,抓成下層結點。
原生的logger僅能輸出文件字串,如果需要搭配elk這一類的日誌分析軟體去做更進一步的資料鑽研,
可以考慮使用json格式輸出的logrus
go get github.com/sirupsen/logrus
如果沒設定輸出格式的話還是會呈現預設ASCII formatter
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
//INFO[0000] A group of walrus emerges from the ocean animal=walrus size=10
}
需要先設定JSONFormatter,這樣子才能輸出成json格式的log
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func init() {
// Log as JSON instead of the default ASCII formatter.
log.SetFormatter(&log.JSONFormatter{})
// Output to stdout instead of the default stderr
// Can be any io.Writer, see below for File example
log.SetOutput(os.Stdout)
// Only log the warning severity or above.
log.SetLevel(log.InfoLevel)
}
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
log.WithFields(log.Fields{
"omg": true,
"number": 122,
}).Warn("The group's number increased tremendously!")
//{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2020-09-22T17:21:21+08:00"}
//{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2020-09-22T17:21:21+08:00"}
}