Golang packge time

time 包的官方文檔

中文
英文
本文章不是對time包文檔的重復,旨在加深對time實現(xiàn)的理解上差油,以上是文檔可以進行查看汽抚。

time 包中一些官方定義的結構的認識

go針對時間常量的定義:

const (
    Nanosecond  Duration = 1                  //納秒
    Microsecond          = 1000 * Nanosecond  //微秒
    Millisecond          = 1000 * Microsecond // 毫秒
    Second               = 1000 * Millisecond // 秒
    Minute               = 60 * Second        // 分
    Hour                 = 60 * Minute        // 時
)
type Weekday int  // 定義星期

const (
    Sunday Weekday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)
type Month int  // 定義月份

const (
    January Month = 1 + iota
    February
    March
    April
    May
    June
    July
    August
    September
    October
    November
    December
)

主要的結構體

type Time struct {
    // sec gives the number of seconds elapsed since
    // January 1, year 1 00:00:00 UTC.
    sec int64  //  sec表示從公元1年1月1日00:00:00UTC到要表示的整數(shù)秒數(shù), 
    // nsec specifies a non-negative nanosecond
    // offset within the second named by Seconds.
    // It must be in the range [0, 999999999].
    nsec int32  // nsec表示余下的納秒數(shù), 
    // loc specifies the Location that should be used to
    // determine the minute, hour, month, day, and year
    // that correspond to this Time.
    // The nil location means UTC.
    // All UTC times are represented with loc==nil, never loc==&utcLoc.
    loc *Location  //  loc表示時區(qū). sec和nsec處理沒有歧義的時間值, loc處理偏移量.
}
type Duration int64  // 針對時間長度的定義,單位為納秒,兩個時間點之間經過的納秒數(shù)
// Location代表一個地點喇完,以及該地點所在的時區(qū)信息檀轨。北京時間可以使用 Asia/Shanghai
type Location struct {
    name string
    zone []zone
    tx   []zoneTrans
    cacheStart int64
    cacheEnd   int64
    cacheZone  *zone
}

針對以上的結構體和類型,go提供了很多方法斥季。

1. time.Time

time.Time 代表一個納秒精度的時間點训桶。
time.Time 主要的方法有:獲取時間點,獲取時間相關信息酣倾,時間比較舵揭,計算和序列化操作。

1.1 獲取時間
  • func Now() Time {} // 當前本地時間
  • func Unix(sec int64, nsec int64) Time {} // 根據(jù)時間戳返回本地時間
  • func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {} // 返回指定時間
  • func Parse(layout, value string) (Time, error) // 根據(jù)指定的時間格式躁锡,讀取時間字符串的時間
  • func ParseInLocation(layout, value string, loc *Location) (Time, error) // 相比上一個函數(shù)午绳,多一個時區(qū)的參數(shù)
var t time.Time
t = time.Now() // 返回一個本地時間, 返回的類型是一個 time.Time 的一個結構體
fmt.Println("time.Now():", t)

// 根據(jù)時間戳返回本地時間 中國的本地時間也就是東八區(qū)的區(qū)時
t = time.Unix(12342342410, 111111)
fmt.Println("time.Unix: ", t)

// 返回指定時間 把這個確定的時間轉為一個時間time.Time結構體類型
t = time.Date(2019, time.Month(2), 20, 1, 30, 30, 1111111, time.Local)
fmt.Println("time.Date: ", t)

// 按照第一參數(shù)的格式,讀取后面的時間稚铣,格式該怎么用參考后面時間序列化
dt, err := time.Parse("2006-01-02 15:04:05", "2018-04-23 12:24:51")
if err != nil {
    fmt.Println("讀取錯誤")
}
fmt.Println(dt.Unix(), dt)
1.2 時間格式化

計算機中表示時間使用時間戳的形式來表示箱叁,但是這是我們人不能看懂的墅垮,所以就需要序列化(也就是用一個我們人能看懂的格式來表示這個時間)。
func (t Time) Format(layout string) string // 按照指定格式序列化time.Time
Format函數(shù)需要傳遞一個字符串耕漱,這個字符串就是我們需要給出的一個格式算色,Format函數(shù)會根據(jù)我們給定的格式把time.Time類型序列化。

t = time.Now()
timeStr := t.Format("年月日:2006-01-02 時分秒:15:04:05 英文的星期:Mon 英文月份:Jan 數(shù)字一個月中的號數(shù):2 時區(qū):-0700 MST")
fmt.Println(timeStr)
timeStr = t.Format("15:04:05 2006/01/02  ")
fmt.Println(timeStr)

比如年份:短年份06螟够,長年份2006灾梦,
月份:01,Jan妓笙,January
日:02若河,2,_2
時:15寞宫,3萧福,03
分:04, 4
秒:05辈赋, 5
時區(qū):-0700 MST

因為都不相等所以通過遍歷layout就可以switch case解析出每個區(qū)塊的意義和在字符串中的位置鲫忍,這樣輸入對應格式的時間字符串就可以順利解析出來。
這樣layout也可以自定義钥屈,而且順序任意悟民,只要符合下列每個區(qū)塊定義的規(guī)則即可,代碼中的注釋就是規(guī)則寫法篷就,如果要設置要給復雜的格式參考如下:

const (
    _                        = iota
    stdLongMonth             = iota + stdNeedDate  // "January"
    stdMonth                                       // "Jan"
    stdNumMonth                                    // "1"
    stdZeroMonth                                   // "01"
    stdLongWeekDay                                 // "Monday"
    stdWeekDay                                     // "Mon"
    stdDay                                         // "2"
    stdUnderDay                                    // "_2"
    stdZeroDay                                     // "02"
    stdHour                  = iota + stdNeedClock // "15"
    stdHour12                                      // "3"
    stdZeroHour12                                  // "03"
    stdMinute                                      // "4"
    stdZeroMinute                                  // "04"
    stdSecond                                      // "5"
    stdZeroSecond                                  // "05"
    stdLongYear              = iota + stdNeedDate  // "2006"
    stdYear                                        // "06"
    stdPM                    = iota + stdNeedClock // "PM"
    stdpm                                          // "pm"
    stdTZ                    = iota                // "MST"
    stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
    stdISO8601SecondsTZ                            // "Z070000"
    stdISO8601ShortTZ                              // "Z07"
    stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
    stdISO8601ColonSecondsTZ                       // "Z07:00:00"
    stdNumTZ                                       // "-0700"  // always numeric
    stdNumSecondsTz                                // "-070000"
    stdNumShortTZ                                  // "-07"    // always numeric
    stdNumColonTZ                                  // "-07:00" // always numeric
    stdNumColonSecondsTZ                           // "-07:00:00"
    stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
    stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted

    stdNeedDate  = 1 << 8             // need month, day, year
    stdNeedClock = 2 << 8             // need hour, minute, second
    stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
    stdMask      = 1<<stdArgShift - 1 // mask out argument
)

除了可以自己自定義格式外射亏,go還給了很多標準化的格式

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"
)
  • func (t Time) UTC() Time {} // 獲取指定時間在UTC 時區(qū)的時間表示
  • func (t Time) Local() Time {} // 以本地時區(qū)表示
  • func (t Time) In(loc *Location) Time {} // 給Time設置時區(qū)
// 獲取指定時間在UTC 時區(qū)(零時區(qū))的時間表示
t = time.Now()
t_by_utc := t.UTC()
fmt.Println("'t.UTC': ", t_by_utc)

// 獲取本地時間表示
t_by_local := t.Local()
fmt.Println("'t.Local': ", t_by_local)

// 時間在指定時區(qū)的表示
t_in := t.In(time.UTC)
fmt.Println("'t.In': ", t_in)
  • func (t Time) Date() (year int, month Month, day int) {}// 返回時間的日期信息
  • func (t Time) Year() int {}// 返回年
  • func (t Time) Month() Month {}// 月
  • func (t Time) Day() int {}// 日
  • func (t Time) Weekday() Weekday {} // 星期
  • func (t Time) ISOWeek() (year, week int) {}// 返回年,星期范圍編號
  • func (t Time) Clock() (hour, min, sec int) {} // 返回時間的時分秒
  • func (t Time) Hour() int {}// 返回小時
    *func (t Time) Minute() int {}// 分鐘
  • func (t Time) Second() int {}// 秒
  • func (t Time) Nanosecond() int {} // 納秒
  • func (t Time) YearDay() int {} // 一年中對應的天
  • func (t Time) Location() *Location {}// 時間的時區(qū)
  • func (t Time) Zone() (name string, offset int) {}// 時間所在時區(qū)的規(guī)范名和想對UTC 時間偏移量
  • func (t Time) Unix() int64 {} // 時間轉為時間戳
  • func (t Time) UnixNano() int64 {} // 時間轉為時間戳(納秒)
1.3 時間序列化
  • func (t Time) MarshalBinary() ([]byte, error) {}// 時間序列化
  • func (t Time) UnmarshalBinary(data []byte) error {}// 反序列化
  • func (t Time) MarshalJSON() ([]byte, error) {}// 時間序列化
  • func (t *Time) UnmarshalJSON(data []byte) (err error) // 時間反序列化
  • func (t Time) MarshalText() ([]byte, error) {}// 時間序列化
  • func (t *Time) UnmarshalText(data []byte) (err error) // 時間反序列化
  • func (t Time) GobEncode() ([]byte, error) {}// 時間序列化
  • func (t Time) GobDecode() ([]byte, error) {}// 時間序列化
b,err := t.MarshalJSON() // 序列化
if err != nil {
    log.Println(" MarshalJSON error ")
}
fmt.Println(string(b))

t.AddDate(1,1,1)
t.UnmarshalJSON(b)  // 反序列化
fmt.Println(t)
1.4 時間比較與計算
  • func (t Time) IsZero() bool {}// 是否是零時時間
  • func (t Time) After(u Time) bool {} // 時間在u 之前
  • func (t Time) Before(u Time) bool {}// 時間在u 之后
  • func (t Time) Equal(u Time) bool {}// 時間與u 相同
  • func (t Time) Add(d Duration) Time {}// 返回t +d 的時間點
  • func (t Time) Sub(u Time) Duration {}// 返回 t-u
  • func (t Time) AddDate(years int, months int, days int) Time {} //返回增加了給出的年份竭业、月份和天數(shù)的時間點Time
  • func (t Time) Round(d Duration) Time // 保留時間智润,返回距離t最近的時間點
  • func (t Time) Truncate(d Duration) Time // 在上面的基礎上向上取整
t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
round := []time.Duration{
    time.Nanosecond,
    time.Microsecond,
    time.Millisecond,
    time.Second,
    2 * time.Second,
    time.Minute,
    10 * time.Minute,
    time.Hour,
}
for _, d := range round {
    fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
}

輸出: 對時間進行保留

t.Round(   1ns) = 12:15:30.918273645
t.Round(   1us) = 12:15:30.918274
t.Round(   1ms) = 12:15:30.918
t.Round(    1s) = 12:15:31
t.Round(    2s) = 12:15:30
t.Round(  1m0s) = 12:16:00
t.Round( 10m0s) = 12:20:00
t.Round(1h0m0s) = 12:00:00

time.Duration

time.Duration 表示的是時間段,時間段的定義在文章開頭部分
常用的時間段永品。沒有定義一天或超過一天的單元做鹰,以避免夏時制的時區(qū)切換的混亂。

  • func (d Duration) String() string // 格式化輸出 Duration
  • func (d Duration) Nanoseconds() int64// 將時間段表示為納秒
  • func (d Duration) Seconds() float64 // 將時間段表示為秒
  • func (d Duration) Minutes() float64 // 將時間段表示為分鐘
  • func (d Duration) Hours() float64 // 將時間段表示為小時
// time.Duration 時間段
fmt.Println("time.Duration 時間段")
d := time.Duration(10000000000000)

fmt.Printf("'String: %v', 'Nanoseconds: %v', 'Seconds: %v', 'Minutes: %v', 'Hours: %v'\n",
    d.String(), d.Nanoseconds(), d.Seconds(), d.Minutes(), d.Hours())
  • func Since(t Time) Duration // 返回從t時間到現(xiàn)在時間的長度鼎姐,等價于time.Now().Sub(t)
  • func ParseDuration(s string) (Duration, error) // 解析一個時間段字符串。一個時間段字符串是一個序列更振,每個片段包含可選的正負號炕桨、十進制數(shù)、可選的小數(shù)部分和單位后綴肯腕,如"300ms"献宫、"-1.5h"、"2h45m"实撒。合法的單位有"ns"姊途、"us"涉瘾、"μs"、"ms"捷兰、"s"立叛、"m"、"h"贡茅。
d,err  = time.ParseDuration("-1h45m30s")
if err != nil {
    log.Println("ParseDuration 解析錯誤")
}
fmt.Printf("'String: %v', 'Nanoseconds: %v', 'Seconds: %v', 'Minutes: %v', 'Hours: %v'\n",
    d.String(), d.Nanoseconds(), d.Seconds(), d.Minutes(), d.Hours())

time.Location

time.Location的結構在文章開頭給出了秘蛇。

  • func (l *Location) String() string // 輸出時區(qū)名
  • func FixedZone(name string, offset int) *Location // FixedZone 使用給定的地點名name和時間偏移量offset(單位秒)創(chuàng)建并返回一個Location
  • func LoadLocation(name string) (*Location, error)// LoadLocation 使用給定的名字創(chuàng)建Location

IANA

var local *time.Location
local, ok := time.LoadLocation("Asia/Shanghai")
fmt.Printf("%v, %T, %v\n", local, local, ok)

local, ok = time.LoadLocation("Asia/Chongqing")
fmt.Printf("%v, %T, %v\n", local, local, ok)

var cstZone = time.FixedZone("CST", 8*3600)       // 東八
fmt.Println("SH : ", time.Now().In(cstZone).Format("2006-01-02 15:04:05"))

更多的時區(qū)相關的東西可以參考這里

time.Sleep() 常用

  • func Sleep(d Duration) // Sleep阻塞當前go程至少d代表的時間段。d<=0時顶考,Sleep會立刻返回,

查看 runtime/time.go文件中的timeSleep可知赁还,Sleep的是通過 Timer 實現(xiàn)的,把當前 goroutine 作為 arg 參數(shù)(getg())驹沿。

time.Timer time.Ticker

參考我的另一篇筆記:Golang time.Timer and time.Ticker

參考
Go 標準庫介紹二: time
深入理解GO時間處理(time.Time)
golang包time用法詳解
Time包

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末艘策,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渊季,更是在濱河造成了極大的恐慌柬焕,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梭域,死亡現(xiàn)場離奇詭異斑举,居然都是意外死亡,警方通過查閱死者的電腦和手機病涨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門富玷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人既穆,你說我怎么就攤上這事赎懦。” “怎么了幻工?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵励两,是天一觀的道長。 經常有香客問我囊颅,道長当悔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任踢代,我火速辦了婚禮盲憎,結果婚禮上,老公的妹妹穿的比我還像新娘胳挎。我一直安慰自己饼疙,他們只是感情好,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布慕爬。 她就那樣靜靜地躺著窑眯,像睡著了一般屏积。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上磅甩,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天炊林,我揣著相機與錄音,去河邊找鬼更胖。 笑死铛铁,一個胖子當著我的面吹牛,可吹牛的內容都是我干的却妨。 我是一名探鬼主播饵逐,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼彪标!你這毒婦竟也來了倍权?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤捞烟,失蹤者是張志新(化名)和其女友劉穎薄声,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體题画,經...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡默辨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苍息。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缩幸。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖竞思,靈堂內的尸體忽然破棺而出表谊,到底是詐尸還是另有隱情,我是刑警寧澤盖喷,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布爆办,位于F島的核電站,受9級特大地震影響课梳,放射性物質發(fā)生泄漏距辆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一惦界、第九天 我趴在偏房一處隱蔽的房頂上張望挑格。 院中可真熱鬧,春花似錦沾歪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挫望。三九已至,卻和暖如春狂窑,著一層夾襖步出監(jiān)牢的瞬間媳板,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工泉哈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛉幸,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓丛晦,卻偏偏與公主長得像奕纫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烫沙,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內容

  • 原文鏈接 http://ironxu.com/747 介紹Go 標準庫 time 常用導出函數(shù)匹层,結構體及其方法。 ...
    好剛編程閱讀 16,959評論 2 11
  • 本章就來學習時間相關的所有操作 1.延遲d秒后返回通過信道返回時間值 func After(d Duration)...
    酷走天涯閱讀 1,250評論 0 2
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,770評論 0 38
  • 類型 time.Time{} 時間類型,包含了秒和納秒以及Location time.Month() type M...
    吃貓的魚0閱讀 31,759評論 0 4
  • 有些傻話锌蓄,不但是要背著別人說升筏,還得背著自己說。讓自己聽見了也怪難為情的瘸爽。譬如說您访,我愛你,我一輩子都愛你剪决。 今天收到...
    徐靈閱讀 1,340評論 6 24