Go 的時間操做基本上都用 time
包,比 C 的 time 函數和 timeval 等 struct 好用多了。不過 time
包仍是有很多用法和其餘語言不一樣的,因此有必要寫個筆記記錄一下。golang
本文連接:http://www.javashuo.com/article/p-qzufhwzx-mv.html,首次發佈於雲+社區segmentfault
和其餘文章不一樣的是,本文我從時區講起。在 Go 中,表示時區的類型是 type Location struct{...}
,代碼中使用 *time.Location
對象。服務器
對於不嚴格的場景而言,能夠獲取服務器所處的時區。可是本文不建議這個方法。由於一臺服務器服務的時區是事先可知的,或者說是須要對接的時區信息也是已知的(好比對接微信,那麼時間確定是東八區,而不是 UTC 時間)。得到東八區時區的代碼以下:微信
loc, _ := time.LoadLocation("Asia/Shanghai")
以後這個 loc
能夠做爲常量使用。是否可以拿到時區,取決於機器本地的 zoneinfo 文件。後文也將使用這個 loc
做爲全局變量。函數
也能夠自定義一個時區名稱,好比咱們人工添加一個巴西利亞時間:編碼
brazil := time.FixedZone("Brazil/Brasilia", -3*60*60)
這裏咱們同時要知道一個很重要的概念,就是在 *Location
的加持下,一個 Time
類型自己是同時記錄着 UTC 時間和本地時間的,這就使得一個 Go 時間類型不會由於時區而出現歧義,好比你能夠用一個東八區的 Time
和西八區的 Time
隨意進行運算也不會出錯。這一特性使得時間類型變得極爲實用。spa
最基本的建立時間類型的接口:日誌
t := time.Now()
此外,不少資料會跟你說採用 Local()
函數得到本地時間,但基於前述理由,我建議固定指定 location:code
t := time.Now().In(loc)
其餘的幾個建立時間的函數:orm
t := time.Date(y, m, d, h, min, s, nsec, loc)
:用從年到納秒,以及時區信息,建立一個時間。參數均爲整型t := time.Unix(s, nsec)
:使用 Unix UTC 時間戳來建立時間若是將 time
類型轉換成字符串,採用如下函數:
s := t.Format("2006-01-02 15:04:05.000") // 輸出如:"2019-07-03 22:10:23.437"
經過已知格式的字符串解析時間的函數爲:
t, err := time.ParseInLocation("2006-01-02 15:04:05", s, loc)
略微瞭解過 Go time 的人都知道,Go 時間格式化採用的並非傳統的 YYYY-MM-DD hh:mm:ss
格式。這裏有一份對應表,便於組裝字符串時查閱——以時間 1609-08-12 19:02:35 PM +03:00 Aug Wed PDT
爲例,這個時間的含義是:1609年9月12日,北美太平洋地區時間下午7:02:35,應用如下格式的輸出舉例:
類型 | 格式符 | 輸出舉例 | 說明 |
---|---|---|---|
年 | 2006 |
1609 | |
| 06 |
09 | |
月 | 01 |
08 | |
| 1 |
8 | |
| Jan |
Aug | |
| January |
August | |
日 | 02 |
02 | |
| 2 |
2 | |
周幾 | Mon |
Wed | 注意,格式符裏沒有數字化的周幾信息,須要本身拼。參見後文 |
| Monday |
Wednesday | |
小時 | 03 |
07 | 12小時制,01~12,12點表示正午 |
| 3 |
7 | 12小時制,1~12,12點表示正午 |
| 15 |
19 | 24小時制,0~23,永遠都是兩位數字,不足2位補0,如早上7點:"07" |
分鐘 | 04 |
02 | |
| 4 |
2 | |
秒 | 05 |
35 | |
| 5 |
35 | |
上 / 下午 | PM |
PM | |
小數點後秒數 | .000 |
.123 | |
| .000000 |
.123456 | |
| .000000000 |
.123456789 | 實際上,能夠是小於9位的任意位數的0,只要是以 . 打頭 |
時區偏移 | -0700 |
+0300 | |
| -07:00 |
+03:00 | |
| Z0700 |
+0300 | |
| Z07:00 |
+03:00 | |
時區名 | MST |
PDT | |
若是須要自定義的星期幾名,須要搭配 time
的 Weekday()
函數,返回 Weekday
類型(等同於 int 類型),以 0 表明星期天。以下:
wday := []string{"日", "一", "二", "三", "四", "五", "六"} s := fmt.Sprintf(t.Format("2006-01-02 15:04:05 星期%s"), wday[t.Weekday()]) fmt.Println(s) // 1609-08-12 19:02:35 星期三
time.Time
提供了一個 IsZero()
函數來判斷時間類型是否爲空的狀態。空時間所指代的時間是 UTC 時間公元元年 00:00:00,這是 t := time.Time{}
所生成的時間。
主要的比較函數以下:
func (t Time) IsZero() bool
func (t Time) After(u Time) bool
:判斷是否在另外一個時間以後func (t Time) Before(u Time) bool
:判斷是否在另外一個時間以前func (t Time) Equal(u Time) bool
:判斷兩個時間是否相等func (t Time) Sub(u Time) Duration
:計算兩個時間之間的差。Duration
類型會在下一小節說明
Add()
函數的使用場景是徹底不一樣的,不得不吐槽一下二者的命名……func (t Time) Add(d Duration)
:加上一個時間段,返回一個新的時間。d 也能夠是負的時間func (t Time) AddDate(年, 月, 日)
:加上一個日期,獲返回一個新的時間。各參數均爲整型,能夠是負數
t.AddDate(0, 1, -1)
表示加上一個月以後再減一天func Since(u Time) Duration
:表示當前時間與一個過去的時間的差;若是被比較的時間是未來時間的話,那麼返回負的 Duration
time.Now().Sub(t)
func Until(u Time) Duration:這是
Since` 的反邏輯
t.Sub(time.Now())
如下函數能夠獲取時間的基本信息,返回均爲整型,很好理解:
t.Year()
t.Month()
t.Day()
t.Weekday()
:返回以星期天爲 0 的星期幾數值t.YearDay()
:返回處於每年的第幾天t.Hour()
t.Minute()
t.Second()
t.Nanosecond()
:時間的毫秒部分,int
類型t.Unix()
:返回 Unix UTX 時間戳,int64
類型Duration
類型的做用是用來表示兩個時間點之間的時間段。Duration 其實是 int64
類型,單位是納秒。但在實際編碼中,基本上不會直接賦值一個數字,而是用 time
提供的常量,如:
tenSecs := 10 * time.Second twoHours := 2 * time.Hour
其餘常量還有:
const ( Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond Millisecond = 1000 * Microsecond Second = 1000 * Millisecond Minute = 60 * Second Hour = 60 * Minute )
此外,Duration 類型還有下面的實用的方法:
func (d Duration) Round(m Duration) Duration
:表示按照 m
給定的單位,返回四捨五入func (d Duration) Truncate(m Duration) Duration
:表示按照 m
給定的單位,返回舍尾數計算func (d Duration) String() string
:給出幾小時幾分鐘幾秒的字符串格式,很是適合打日誌Hours(), Minutes(), Seconds()
:返回 float64
格式,也就是小數形式的小時 / 分鐘 / 秒數Nanoseconds()
:返回 int64
類型的納秒數本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。
原做者: amc,歡迎轉載,但請註明出處。
原文標題:Go 語言 time 包經常使用用法筆記
發佈日期:2017-07-03
原文連接:https://cloud.tencent.com/developer/article/1456484。