time 包是 Go 語言中用於處理時間和日期的標準庫。它提供了許多函數和類型,用於表示和操作時間、計時器、持續時間和時區等。
簡要介紹#
常用的函數和類型包括:
時間表示和創建函數:Date ()、Now ()、Parse ()、Unix () 等函數用於創建和獲取時間對象,以不同的方式表示時間。
時間格式化和解析:Format () 和 Parse () 函數用於時間對象與字符串之間的相互轉換。通過定義特定的格式模板,可以按照需要格式化或解析時間。
時間計算和比較:Add ()、AddDate ()、Sub () 等函數用於進行時間的加減運算,例如增加一定的時間量、計算兩個時間之間的間隔,並支持時間之間的比較。
持續時間處理:Duration 類型用於表示時間間隔或持續時間,可以用於表示以納秒、微秒、毫秒、秒、分鐘、小時為單位的時間段,並提供了一系列的方法用於操作和轉換持續時間。
時區處理:Location 類型用於表示時區信息,可以加載系統預定義的時區或自定義的時區。可以使用 LoadLocation () 函數加載時區信息,並使用 In () 和 UTC () 方法將時間轉換為特定時區或 UTC 時間。
計時器:Timer 和 Ticker 類型用於定時觸發事件。Timer 用於在指定的時間後觸發單個事件,Ticker 用於以固定時間間隔觸發重複事件。
time 包中還包含了其他一些用於時間操作和格式化的函數,以及表示月份、星期幾的類型等。
Time 包下的內容比較多,我覺得通過示例來學習 time 包比較好,下面我就按照在 go 官方的 time 包下的類型,依次介紹 time 包中常用函數的示例:
函數#
func After(d Duration) <-chan Time
func Sleep(d Duration)
func Tick(d Duration) <-chan Time
package main
import (
"fmt"
"time"
)
func main() {
// After 函數返回一個通道,指定時間過後,通道會接收到一個時間值
select {
case <-time.After(2 * time.Second):
fmt.Println("After")
}
// Sleep 函數使程序暫停指定的時間
fmt.Println("Start")
time.Sleep(2 * time.Second)
fmt.Println("End")
// Tick 函數返回一個通道,每隔指定的時間間隔,通道會接收到一個時間值
ticker := time.Tick(1 * time.Second)
for tick := range ticker {
fmt.Println("Tick:", tick)
}
}
# 輸出
After
Start
End
Tick: 2023-05-28 19:52:59.051953 +0800 CST m=+5.002580117
Tick: 2023-05-28 19:53:00.051654 +0800 CST m=+6.002592024
Tick: 2023-05-28 19:53:01.050407 +0800 CST m=+7.001636794
Tick: 2023-05-28 19:53:02.050139 +0800 CST m=+8.001642844
...
Duration#
Duration
表示一段時間間隔。
func ParseDuration(s string) (Duration, error)
func Since(t Time) Duration
func Until(t Time) Duration
func (d Duration) Abs() Duration
func (d Duration) Hours() float64
func (d Duration) Microseconds() int64
func (d Duration) Milliseconds() int64
func (d Duration) Minutes() float64
func (d Duration) Nanoseconds() int64
func (d Duration) Round(m Duration) Duration
func (d Duration) Seconds() float64
func (d Duration) String() string
func (d Duration) Truncate(m Duration) Duration
package main
import (
"fmt"
"time"
)
func main() {
// ParseDuration 函數將字符串解析為 Duration 類型
d, _ := time.ParseDuration("1h30m")
fmt.Println("Parsed Duration:", d)
// Since 函數返回當前時間和指定時間之間的時間差,作為 Duration 類型
t := time.Date(2023, time.May, 7, 12, 0, 0, 0, time.UTC)
duration := time.Since(t)
fmt.Println("Time Since:", duration)
// Until 函數返回指定時間和當前時間之間的時間差,作為 Duration 類型
duration = time.Until(t)
fmt.Println("Time Until:", duration)
// Duration 類型的常用方法示例
duration = 2 * time.Hour + 30 * time.Minute
fmt.Println("Hours:", duration.Hours())
fmt.Println("Minutes:", duration.Minutes())
fmt.Println("Seconds:", duration.Seconds())
fmt.Println("Milliseconds:", duration.Milliseconds())
fmt.Println("Microseconds:", duration.Microseconds())
fmt.Println("Nanoseconds:", duration.Nanoseconds())
// 格式化輸出 Duration 類型的時間間隔
fmt.Println("Duration String:", duration.String())
}
# 返回值
Parsed Duration: 1h30m0s
Time Since: 504h21m51.536756s
Time Until: -504h21m51.536761s
Hours: 2.5
Minutes: 150
Seconds: 9000
Milliseconds: 9000000
Microseconds: 9000000000
Nanoseconds: 9000000000000
Duration String: 2h30m0s
Location#
Location
類型表示地點的意思,我們可以通過 LoadLocation 設置我們的時間地點。
type Location:
func FixedZone(name string, offset int) *Location
func LoadLocation(name string) (*Location, error)
func LoadLocationFromTZData(name string, data []byte) (*Location, error)
func (l *Location) String() string
package main
import (
"fmt"
"time"
)
func main() {
// FixedZone 函數創建一個固定偏移量的時區
zone := time.FixedZone("CST", int(8*time.Hour.Seconds()))
fmt.Println("Fixed Zone:", zone)
// LoadLocation 函數加載指定名稱的時區
shanghai, err := time.LoadLocation("Asia/Shanghai") // UTC+08:00
if err != nil {
fmt.Println("Failed to load Asia/Shanghai location:", err)
return
}
timeInShanghai := time.Date(2023, 5, 28, 20, 0, 0, 0, shanghai)
fmt.Println("Time in Shanghai:", sameTimeInShanghai)
newYork, err := time.LoadLocation("America/New_York")
if err != nil {
fmt.Println("Failed to load America/New_York location:", err)
return
}
timeInNewYork := sameTimeInShanghai.In(newYork)
fmt.Println("Time in New York:", sameTimeInNewYork)
timesAreEqual := sameTimeInShanghai.Equal(sameTimeInNewYork)
fmt.Println(timesAreEqual)
}
現在,timeInShanghai 被轉換為紐約時區,所以它與 timeInNewYork 表示相同的時間點,Equal 方法將返回 true。
Month#
Month 類型
func (m Month) String() string
package main
import (
"fmt"
"time"
)
func main() {
// String 方法返回 Month 類型的字符串表示形式
month := time.May
fmt.Println("Month String:", month.String())
}
ParseError#
func (e *ParseError) Error() string
package main
import (
"fmt"
"time"
)
func main() {
// Parse 函數解析時間字符串時可能返回 ParseError 類型的錯誤
_, err := time.Parse("2006-01-02", "invalid")
if err != nil {
parseError := err.(*time.ParseError)
fmt.Println("Parse Error:", parseError.Error())
}
}
Ticker#
Ticker 主要是一個定時器
func NewTicker(d Duration) *Ticker
func (t *Ticker) Reset(d Duration)
func (t *Ticker) Stop()
package main
import (
"fmt"
"time"
)
func main() {
// NewTicker 函數創建一個定時觸發的 Ticker 對象
ticker := time.NewTicker(1 * time.Second)
go func() {
for tick := range ticker.C {
fmt.Println("Tick:", tick)
}
}()
// 停止 Ticker
time.Sleep(5 * time.Second)
ticker.Stop()
fmt.Println("Ticker Stopped")
}
Time 類型#
Time 類型是 time 包下最常使用到的類型
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
func Now() Time
func Parse(layout, value string) (Time, error)
func ParseInLocation(layout, value string, loc *Location) (Time, error)
func Unix(sec int64, nsec int64) Time
func UnixMicro(usec int64) Time
func UnixMilli(msec int64) Time
func (t Time) Add(d Duration) Time
func (t Time) AddDate(years int, months int, days int) Time
func (t Time) After(u Time) bool
func (t Time) AppendFormat(b []byte, layout string) []byte
func (t Time) Before(u Time) bool
func (t Time) Clock() (hour, min, sec int)
func (t Time) Compare(u Time) int
func (t Time) Date() (year int, month Month, day int)
func (t Time) Day() int
func (t Time) Equal(u Time) bool
func (t Time) Format(layout string) string
func (t Time) GoString() string
func (t *Time) GobDecode(data []byte) error
func (t Time) GobEncode() ([]byte, error)
func (t Time) Hour() int
func (t Time) ISOWeek() (year, week int)
func (t Time) In(loc *Location) Time
func (t Time) IsDST() bool
func (t Time) IsZero() bool
func (t Time) Local() Time
func (t Time) Location() *Location
func (t Time) MarshalBinary() ([]byte, error)
func (t Time) MarshalJSON() ([]byte, error)
func (t Time) MarshalText() ([]byte, error)
func (t Time) Minute() int
func (t Time) Month() Month
func (t Time) Nanosecond() int
func (t Time) Round(d Duration) Time
func (t Time) Second() int
func (t Time) String() string
func (t Time) Sub(u Time) Duration
func (t Time) Truncate(d Duration) Time
func (t Time) UTC() Time
func (t Time) Unix() int64
func (t Time) UnixMicro() int64
func (t Time) UnixMilli() int64
func (t Time) UnixNano() int64
func (t *Time) UnmarshalBinary(data []byte) error
func (t *Time) UnmarshalJSON(data []byte) error
func (t *Time) UnmarshalText(data []byte) error
func (t Time) Weekday() Weekday
func (t Time) Year() int
func (t Time) YearDay() int
func (t Time) Zone() (name string, offset int)
func (t Time) ZoneBounds() (start, end Time)
package main
import (
"fmt"
"time"
)
func main() {
// Date 函數根據指定的年、月、日、時、分、秒、納秒和時區創建一個 Time 對象
date := time.Date(2023, time.May, 7, 12, 0, 0, 0, time.UTC)
fmt.Println("Date:", date)
// Now 函數返回當前時間的 Time 對象
now := time.Now()
fmt.Println("Now:", now)
// Parse 函數將指定的時間字符串解析為 Time 對象
// 這裡第一個參數只能是 2006-01-02 15:04:05
parsedTime, _ := time.Parse("2006-01-02 15:04:05", "2023-05-07 12:00:00")
fmt.Println("Parsed Time:", parsedTime)
// Unix 函數根據 Unix 時間戳創建一個 Time 對象
unixTime := time.Unix(1670140800, 0)
fmt.Println("Unix Time:", unixTime)
// Time 類型的常用方法示例
fmt.Println("Year:", now.Year())
fmt.Println("Month:", now.Month())
fmt.Println("Day:", now.Day())
fmt.Println("Hour:", now.Hour())
fmt.Println("Minute:", now.Minute())
fmt.Println("Second:", now.Second())
fmt.Println("Nanosecond:", now.Nanosecond())
fmt.Println("Weekday:", now.Weekday())
// 格式化輸出 Time 對象的字符串表示
fmt.Println("Formatted Time:", now.Format("2006-01-02 15:04:05"))
// 時間比較
otherTime := time.Date(2023, time.May, 7, 10, 0, 0, 0, time.UTC)
fmt.Println("Before:", now.Before(otherTime))
fmt.Println("After:", now.After(otherTime))
fmt.Println("Equal:", now.Equal(otherTime))
// 時間計算
afterTime := now.Add(2 * time.Hour)
fmt.Println("After 2 Hours:", afterTime)
addedDate := now.AddDate(1, 0, 0) // 增加一年
fmt.Println("Added Date:", addedDate)
// 時區相關操作
loc, _ := time.LoadLocation("America/New_York")
localTime := now.In(loc)
fmt.Println("Local Time:", localTime)
utcTime := localTime.UTC()
fmt.Println("UTC Time:", utcTime)
// 時間戳
unix := now.Unix()
unixMicro := now.UnixMicro()
unixMilli := now.UnixMilli()
unixNano := now.UnixNano()
fmt.Println("Unix:", unix)
fmt.Println("Unix Micro:", unixMicro)
fmt.Println("Unix Milli:", unixMilli)
fmt.Println("Unix Nano:", unixNano)
}
// 輸出
Date: 2023-05-07 12:00:00 +0000 UTC
Now: 2023-05-28 20:37:21.055316 +0800 CST m=+0.000293065
Parsed Time: 2023-05-07 12:00:00 +0000 UTC
Unix Time: 2022-12-04 16:00:00 +0800 CST
Year: 2023
Month: May
Day: 28
Hour: 20
Minute: 37
Second: 21
Nanosecond: 55316000
Weekday: Sunday
Formatted Time: 2023-05-28 20:37:21
Before: false
After: true
Equal: false
After 2 Hours: 2023-05-28 22:37:21.055316 +0800 CST m=+7200.000293065
Added Date: 2024-05-28 20:37:21.055316 +0800 CST
Local Time: 2023-05-28 08:37:21.055316 -0400 EDT
UTC Time: 2023-05-28 12:37:21.055316 +0000 UTC
Unix: 1685277441
Unix Micro: 1685277441055316
Unix Milli: 1685277441055
Unix Nano: 1685277441055316000
以上是 time
包中一些常用函數和類型的示例,你可以根據需要進行參考和使用。
總結#
time 包的常用操作總結:
- 創建和表示時間:使用 Date ()、Now ()、Parse ()、Unix () 等函數創建和獲取時間對象。
- 格式化和解析時間:使用 Format () 和 Parse () 函數將時間對象與字符串進行轉換。
- 時間計算和比較:使用 Add ()、AddDate ()、Sub () 等函數對時間進行加減運算,比較時間的先後順序。
- 持續時間處理:使用 Duration 類型表示時間間隔,進行時間單位的轉換和操作。
- 時區處理:使用 Location 類型表示時區,加載預定義的時區信息,轉換時間到特定時區。
- 定時器和計時器:使用 Timer 和 Ticker 類型進行定時觸發事件。
以上是對 time 包的簡要總結,它是處理時間和日期相關操作的重要工具,可根據實際需求使用其中的函數和類型。