Go時間包提供了處理時間和日期的功能。
包中的主要類型:
- 結構time.Time表示了時間和日期的值
- time.Duration 代表了時間差,單位為nanoseconds
- time.Second, time.Millisecond 等是time.Duration中的常量,比nanoseconds方便使用
獲取當前日期和時間:
now := time.Now()
用給定的時間點構造時間和日期
t := time.Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
loc必須提供并代表時區。 將time.UTC變量用于UTC時區。
比較時間是否相等
areEqual := t1.Equal(t2)
加一段時間
newTime := now.Add(5 * time.Second + time.Millisecond * 100)
時間值是不可變的。 Add返回一個新值。
減一段時間
newTime := now.Add(-6 * time.Second)
要減去6秒,我們需要加上-6秒。
時間加減要求是時間小于24小時。要按日歷年,月或日加減時間,如下所示:
years := 2
months := 3
days := 13
t2 := t.AddDate(years, months, days)
Convert time to Unix representation of time
For interoperability with existing code you often need to use Unix time, which is defined as number of seconds since January 1, 1970 UTC.
unixTime := t.Unix()
獲取年月日
year, month, day := t.Day()
格式化日期時間
大多數語言都從strftime函數C庫繼承了時間格式化方法,該函數使用了一些神秘的格式字符串,例如%Y-%m-%d。
Go設計人員提出了更直觀的時間解析和格式設置的方法,即在其中傳入一個模板:
t := time.Date(2017, 9, 4, 3, 38, 45, 0, time.UTC)
fmt.Println(t.Format("2006-02-01 15:04:05.000 MST"))
fmt.Println(t.Format("2006-02-1 15pm"))
fmt.Println(t.Format("Jan 06 Mon 2 01"))
fmt.Println(t.Format("January 6 Mon 2 1"))
fmt.Println(t.Format("Month: Jan '1', '01', _2"))
2017-04-09 03:38:45.000 UTC
2017-04-9 03am
Sep 17 Mon 4 09
September 6 Mon 4 9
Month: Sep '9', '09', 4
格式化字符串是將一個任意字符串中某些部分被time.Time值中的數據替換:
- 2006, 06 4或2位年
- 2 月, 1-12
- 1 d天, 1-31
- 15 小時
- 5 秒
- MST 時區字符串
- -0700 時區數字偏移
- Jan, January 月的單詞
- Mon, Monday 星期單詞
通過將格式編號加0,可以將天,月,年,小時,分鐘和秒補零。 僅顯示數字<10。02表示零填充月份,即04或11。
某些值可以用空格填充。 _2將是4或11。
打包時間還定義了一些眾所周知的日期/時間格式的常量,例如日期/時間格式。 time.RFC822是RFC 822中定義的日期格式,它是電子郵件中的日期格式。
以下是預定義格式的完整列表:
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"
)
如果你喜歡格式化時間的strftime樣式怎么辦? 也可以。
解析時間
解析時間和格式化相反
s := "2017-04-09 03:38:45.000 UTC"
t, err := time.Parse("2006-02-01 15:04:05.000 MST", s)
if err != nil {
log.Fatalf("time.Parse() failed wiht '%s'\n", err)
}
fmt.Printf("year: %d, month: %d, day: %d\n", t.Year(), t.Month(), t.Day())
year: 2017, month: 9, day: 4
解析模板使用與格式化相同的樣式。
如果你更喜歡strftime樣式的解析時間怎么辦? 也可以。
像strftime一樣格式化時間
如果你喜歡格式化時間值的strftime樣式(如在Python或Ruby中使用的)或使用該樣式的移植代碼,則可以使用以下幾種庫之一。
這是使用github.com/jehiah/go-strftime軟件包的示例:
t := time.Date(2017, 9, 4, 3, 38, 45, 0, time.UTC)
fmt.Println(strftime.Format("%Y-%m-%d %H:%M:%S", t))
關于軟件包命名的附帶說明:由于軟件包名稱為strftime,因此導入路徑/存儲庫路徑應為github.com/jehiah/strftime。 添加go或go-to-repository路徑的樣式不好。
不幸的是,當涉及到解析時,效果并不理想。 有兩個軟件包:
- https://godoc.org/github.com/jeffjen/datefmt
-
https://godoc.org/github.com/knz/strtime
但是它們都是圍繞C庫的cgo包裝器,這使它們的構建更加靈活,尤其是在Windows上。
strftime指令列表:
- %a Weekday as locale’s abbreviated name. Mon
- %A Weekday as locale’s full name. Monday
- %b The abbreviated month name Jan
- %B The full month name January
- %d Day of the month 01..31
- %e Day of the month without a leading zero 1..31
- %j Day of the year 001..366
- %m Month of the year 01..12
- %U Week number of the current year, starting with the first Sunday as the first day of the first week 00..53
- %W Week number of the current year, starting with the first Monday as the first day of the first week 00..53
- %w Day of the week (Sunday is 0) 0..6
- %x Preferred representation for the date alone, no time
- %y Year without a century 00..99
- %Y Year with century
- %H Hour of the day, 24-hour clock 00..23
- %I Hour of the day, 12-hour clock 01..12
- %l Hour of the day, 12-hour clock without a leading zero 1..12
- %M Minute of the hour 00..59
- %P Meridian indicator ("am" or "pm") am
- %p Meridian indicator ("AM" or "PM") PM
- %S Second of the minute 00..60
- %X Preferred representation for the time alone, no date
- %Z Time zone name
- %c The preferred local date and time representation
- %% Literal "%" character
你還可以使用http://www.strfti.me/服務來幫助你構建strftime格式字符串。
比較時間和日期
有時你將需要使用2個日期對象來知道是否存在與同一日期相對應的日期,或者找到哪個日期在另一個日期之后。
在Go中,有4種比較日期的方式:
- date1 == date2, returns true when the 2 are the same moment
- date1 != date2, returns true when the 2 are different moment
- date1.Before(date2), returns true when the first is strictly before the second
- date1.After(date2), returns true when the first is strictly after the second
警告:當兩個比較時間相同(或對應于完全相同的日期)時,After和Before函數將返回false,因為日期既不早于其本身也不在其后-date1 == date1,則返回true-date1!= date1,返回false-date1。After(date1),返回false-date1.Before(date1),返回false
提示:如果你需要知道某個日期是否在另一個日期之前或等于該日期,則只需組合4個運算符-date1 == date2 || date1.After(date2),當date1在date2之后或等于date2或使用!返回true。 (date1.Before(date2))-date1 == date2 || date1.Before(date2),如果date1在date2之前或等于date2或使用!(date1.After(date2)),則返回true。
使用示例:
//初始化時間
var date1 = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
var date2 = time.Date(2017, time.July, 25, 16, 22, 42, 123, time.UTC)
var date3 = time.Date(2017, time.July, 25, 16, 22, 42, 123, time.UTC)
bool1 := date1.Before(date2) // true, because date1 is before date2
bool2 := date1.After(date2) // false, because date1 is not after date2
bool3 := date2.Before(date1) // false, because date2 is not before date1
bool4 := date2.After(date1) // true, because date2 is after date1
bool5 := date1 == date2 // false, not the same moment
bool6 := date1 == date3 // true, different objects but representing the exact same time
bool7 := date1 != date2 // true, different moments
bool8 := date1 != date3 // false, not different moments
bool9 := date1.After(date3) // false, because date1 is not after date3 (that are the same)
bool10:= date1.Before(date3) // false, because date1 is not before date3 (that are the same)
bool11 := !(date1.Before(date3)) // true, because date1 is not before date3
bool12 := !(date1.After(date3)) // true, because date1 is not after date3