time
time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。
Constants
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
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
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// 方便的时间戳
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"
)
这些预定义的版式用于Time.Format和Time.Parse函数。用在版式中的参考时间是:
Mon Jan 2 15:04:05 MST 2006
对应的Unix时间是1136239445。因为MST的时区是GMT-0700,参考时间也可以表示为如下:
01/02 03:04:05PM '06 -0700
要定义你自己的格式,写下该参考时间应用于你的格式的情况;例子请参见ANSIC、StampMicro或Kitchen等常数的值。该模型是为了演示参考时间的格式化效果,如此一来Format和Parse方法可以将相同的转换规则用于一个普通的时间值。
在格式字符串中,用前置的'0'表示一个可以被可以被数字替换的'0'(如果它后面的数字有两位);使用下划线表示一个可以被数字替换的空格(如果它后面的数字有两位);以便兼容Unix定长时间格式。
小数点后跟0到多个'0',表示秒数的小数部分,输出时会生成和'0'一样多的小数位;小数点后跟0到多个'9',表示秒数的小数部分,输出时会生成和'9'一样多的小数位但会将拖尾的'0'去掉。(只有)解析时,输入可以在秒字段后面紧跟一个小数部分,即使格式字符串里没有指明该部分。此时,小数点及其后全部的数字都会成为秒的小数部分。
数字表示的时区格式如下:
-0700 ±hhmm
-07:00 ±hh:mm
将格式字符串中的负号替换为Z会触发ISO 8601行为(当时区是UTC时,输出Z而不是时区偏移量),这样:
Z0700 Z or ±hhmm
Z07:00 Z or ±hh:mm
type ParseError
type ParseError struct {
Layout string
Value string
LayoutElem string
ValueElem string
Message string
}
ParseError描述解析时间字符串时出现的错误。
func (*ParseError) Error
func (e *ParseError) Error() string
Error返回ParseError的字符串表示。
type Weekday
type Weekday int
Weekday代表一周的某一天。
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func (Weekday) String
func (d Weekday) String() string
String返回该日(周几)的英文名("Sunday"、"Monday",……)
type Month
type Month int
Month代表一年的某个月。
const (
January Month = 1 + iota
February
March
April
May
June
July
August
September
October
November
December
)
func main() {
_, month, day := time.Now().Date()
if month == time.November && day == 10 {
fmt.Println("Happy Go day!")
}
}
func (Month) String
func (m Month) String() string
String返回月份的英文名("January","February",……)
type Location
type Location struct {
name string
zone []zone
tx []zoneTrans
extend string
cacheStart int64
cacheEnd int64
cacheZone *zone
}
Location代表一个(关联到某个时间点的)地点,以及该地点所在的时区。
var Local *Location = &localLoc
Local代表系统本地,对应本地时区。
var UTC *Location = &utcLoc
UTC代表通用协调时间,对应零时区。
func LoadLocation
func LoadLocation(name string) (*Location, error)
LoadLocation返回使用给定的名字创建的Location。
如果name是""或"UTC",返回UTC;如果name是"Local",返回Local;否则name应该是IANA时区数据库里有记录的地点名(该数据库记录了地点和对应的时区),如"America/New_York"。
LoadLocation函数需要的时区数据库可能不是所有系统都提供,特别是非Unix系统。此时LoadLocation会查找环境变量ZONEINFO指定目录或解压该变量指定的zip文件(如果有该环境变量);然后查找Unix系统的惯例时区数据安装位置,最后查找$GOROOT/lib/time/zoneinfo.zip。
func FixedZone
func FixedZone(name string, offset int) *Location
FixedZone使用给定的地点名name和时间偏移量offset(单位秒)创建并返回一个Location
func (*Location) String
func (l *Location) String() string
String返回对时区信息的描述,返回值绑定为LoadLocation或FixedZone函数创建l时的name参数。
type Time
type Time struct {
wall uint64
ext int64
loc *Location
}
Time代表一个纳秒精度的时间点。
程序中应使用Time类型值来保存和传递时间,而不能用指针。就是说,表示时间的变量和字段,应为time.Time类型,而不是*time.Time.类型。一个Time类型值可以被多个go程同时使用。时间点可以使用Before、After和Equal方法进行比较。Sub方法让两个时间点相减,生成一个Duration类型值(代表时间段)。Add方法给一个时间点加上一个时间段,生成一个新的Time类型时间点。
Time零值代表时间点January 1, year 1, 00:00:00.000000000 UTC。因为本时间点一般不会出现在使用中,IsZero方法提供了检验时间是否显式初始化的一个简单途径。
每一个时间都具有一个地点信息(及对应地点的时区信息),当计算时间的表示格式时,如Format、Hour和Year等方法,都会考虑该信息。Local、UTC和In方法返回一个指定时区(但指向同一时间点)的Time。修改地点/时区信息只是会改变其表示;不会修改被表示的时间点,因此也不会影响其计算。
func main() {
t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
fmt.Printf("Go launched at %s\n", t.Local())
}
func Date
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Date返回一个时区为loc、当地时间为:
year-month-day hour:min:sec + nsec nanoseconds
month、day、hour、min、sec和nsec的值可能会超出它们的正常范围,在转换前函数会自动将之规范化。如October 32被修正为November 1。
夏时制的时区切换会跳过或重复时间。如,在美国,March 13, 2011 2:15am从来不会出现,而November 6, 2011 1:15am 会出现两次。此时,时区的选择和时间是没有良好定义的。Date会返回在时区切换的两个时区其中一个时区
正确的时间,但本函数不会保证在哪一个时区正确。
如果loc为nil会panic。
func Now
func Now() Time
Now返回当前本地时间。
func main() {
const longForm = "Jan 2, 2006 at 3:04pm (MST)"
t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
fmt.Println(t)
const shortForm = "2006-Jan-02"
t, _ = time.Parse(shortForm, "2013-Feb-03")
fmt.Println(t)
}
func Parse
func Parse(layout, value string) (Time, error)
Parse解析一个格式化的时间字符串并返回它代表的时间。layout定义了参考时间:
Mon Jan 2 15:04:05 -0700 MST 2006
在输入格式下的字符串表示,作为输入的格式的示例。同样的格式规则会被用于输入字符串。
预定义的ANSIC、UnixDate、RFC3339和其他版式描述了参考时间的标准或便捷表示。要获得更多参考时间的定义和格式,参见本包的ANSIC和其他版式常量。
value中漏掉的元素会被视为0;如果不能是0,会被视为1。因此,解析"3:04pm"会返回对应时间点:Jan 1, year 0, 15:04:00 UTC的Time(注意因为year为0,该时间在Time零值之前)。年份必须在0000..9999范围内。周几会被检查其语法,但是会被忽略。
如果缺少表示时区的信息,Parse会将时区设置为UTC。
当解析具有时区偏移量的时间字符串时,如果该时区偏移量和本地时区相同,Parse会在返回值中将Location设置为本地和本地时区。否则,它会将Location设置为一个虚构的具有该时区偏移量的值。
当解析具有时区缩写的时间字符串时,如果该时区缩写具有已定义的时间偏移量,会使用该偏移量。如果时区缩写是"UTC",会将该时间视为UTC时间,不考虑Location。如果时区缩写是未知的,Parse会将Location设置为一个虚构的地点为时区缩写,时间偏移量为0的值。这种做法是为了让一个时间可以在同一版式下不丢失信息的被解析和重新格式化;但字符串表示和具体表示的时间点会因为实际时区偏移量而不同。为了避免这些问题,请使用数字表示的时区偏移量,或者使用ParseInLocation函数。
func main() {
loc, _ := time.LoadLocation("Europe/Berlin")
const longForm = "Jan 2, 2006 at 3:04pm (MST)"
t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc)
fmt.Println(t)
// Note: without explicit zone, returns time in given location.
const shortForm = "2006-Jan-02"
t, _ = time.ParseInLocation(shortForm, "2012-Jul-09", loc)
fmt.Println(t)
}
func ParseInLocation
func ParseInLocation(layout, value string, loc *Location) (Time, error)
ParseInLocation类似Parse但有两个重要的不同之处。第一,当缺少时区信息时,Parse将时间解释为UTC时间,而ParseInLocation将返回值的Location设置为loc;第二,当时间字符串提供了时区偏移量信息时,Parse会尝试去匹配本地时区,而ParseInLocation会去匹配loc。
func Unix
func Unix(sec int64, nsec int64) Time
Unix创建一个本地时间,对应sec和nsec表示的Unix时间(从January 1, 1970 UTC至该时间的秒数和纳秒数)。
nsec的值在[0, 999999999]范围外是合法的。
func (Time) Location
func (t Time) Location() *Location
Location返回t的地点和时区信息。
func (Time) Zone
func (t Time) Zone() (name string, offset int)
Zone计算t所在的时区,返回该时区的规范名(如"CET")和该时区相对于UTC的时间偏移量(单位秒)。
func (Time) IsZero
func (t Time) IsZero() bool
IsZero报告t是否代表Time零值的时间点,January 1, year 1, 00:00:00 UTC。
func (Time) Local
func (t Time) Local() Time
Local返回采用本地和本地时区,但指向同一时间点的Time。
func (Time) UTC
func (t Time) UTC() Time
UTC返回采用UTC和零时区,但指向同一时间点的Time。
func (Time) In
func (t Time) In(loc *Location) Time
In返回采用loc指定的地点和时区,但指向同一时间点的Time。如果loc为nil会panic。
func (Time) Unix
func (t Time) Unix() int64
Unix将t表示为Unix时间,即从时间点January 1, 1970 UTC到时间点t所经过的时间(单位秒)。
func (Time) UnixNano
func (t Time) UnixNano() int64
UnixNano将t表示为Unix时间,即从时间点January 1, 1970 UTC到时间点t所经过的时间(单位纳秒)。如果纳秒为单位的unix时间超出了int64能表示的范围,结果是未定义的。注意这就意味着Time零值调用UnixNano方法的话,结果是未定义的。
func (Time) Equal
func (t Time) Equal(u Time) bool
判断两个时间是否相同,会考虑时区的影响,因此不同时区标准的时间也可以正确比较。本方法和用t==u不同,这种方法还会比较地点和时区信息。
func (Time) Before
func (t Time) Before(u Time) bool
如果t代表的时间点在u之前,返回真;否则返回假。
func (Time) After
func (t Time) After(u Time) bool
如果t代表的时间点在u之后,返回真;否则返回假。
func (Time) Date
func (t Time) Date() (year int, month Month, day int)
返回时间点t对应的年、月、日。
func (Time) Clock
func (t Time) Clock() (hour, min, sec int)
返回t对应的那一天的时、分、秒。
func (Time) Year
func (t Time) Year() int
返回时间点t对应的年份。
func (Time) Month
func (t Time) Month() Month
返回时间点t对应那一年的第几月。
func (Time) ISOWeek
func (t Time) ISOWeek() (year, week int)
返回时间点t对应的ISO 9601标准下的年份和星期编号。星期编号范围[1,53],1月1号到1月3号可能属于上一年的最后一周,12月29号到12月31号可能属于下一年的第一周。
func (Time) YearDay
func (t Time) YearDay() int
返回时间点t对应的那一年的第几天,平年的返回值范围[1,365],闰年[1,366]。
func (Time) Day
func (t Time) Day() int
返回时间点t对应那一月的第几日。
func (Time) Weekday
func (t Time) Weekday() Weekday
返回时间点t对应的那一周的周几。
func (Time) Hour
func (t Time) Hour() int
返回t对应的那一天的第几小时,范围[0, 23]。
func (Time) Minute
func (t Time) Minute() int
返回t对应的那一小时的第几分种,范围[0, 59]。
func (Time) Second
func (t Time) Second() int
返回t对应的那一分钟的第几秒,范围[0, 59]。
func (Time) Nanosecond
func (t Time) Nanosecond() int
返回t对应的那一秒内的纳秒偏移量,范围[0, 999999999]。
func (Time) Add
func (t Time) Add(d Duration) Time
Add返回时间点t+d。
func (Time) AddDate
func (t Time) AddDate(years int, months int, days int) Time
AddDate返回增加了给出的年份、月份和天数的时间点Time。例如,时间点January 1, 2011调用AddDate(-1, 2, 3)会返回March 4, 2010。
AddDate会将结果规范化,类似Date函数的做法。因此,举个例子,给时间点October 31添加一个月,会生成时间点December 1。(从时间点November 31规范化而来)
func (Time) Sub
func (t Time) Sub(u Time) Duration
返回一个时间段t-u。如果结果超出了Duration可以表示的最大值/最小值,将返回最大值/最小值。要获取时间点t-d(d为Duration),可以使用t.Add(-d)。
func (Time) Round
func (t Time) Round(d Duration) Time
返回距离t最近的时间点,该时间点应该满足从Time零值到该时间点的时间段能整除d;如果有两个满足要求的时间点,距离t相同,会向上舍入;如果d <= 0,会返回t的拷贝。
func main() {
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"))
}
}
func (Time) Truncate
func (t Time) Truncate(d Duration) Time
类似Round,但是返回的是最接近但早于t的时间点;如果d <= 0,会返回t的拷贝。
func main() {
t, _ := time.Parse("2006 Jan 02 15:04:05", "2012 Dec 07 12:15:30.918273645")
trunc := []time.Duration{
time.Nanosecond,
time.Microsecond,
time.Millisecond,
time.Second,
2 * time.Second,
time.Minute,
10 * time.Minute,
time.Hour,
}
for _, d := range trunc {
fmt.Printf("t.Truncate(%6s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))
}
}
func (Time) Format
func (t Time) Format(layout string) string
Format根据layout指定的格式返回t代表的时间点的格式化文本表示。layout定义了参考时间:
Mon Jan 2 15:04:05 -0700 MST 2006
格式化后的字符串表示,它作为期望输出的例子。同样的格式规则会被用于格式化时间。
预定义的ANSIC、UnixDate、RFC3339和其他版式描述了参考时间的标准或便捷表示。要获得更多参考时间的定义和格式,参见本包的ANSIC和其他版式常量。
func main() {
// layout shows by example how the reference time should be represented.
const layout = "Jan 2, 2006 at 3:04pm (MST)"
t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local)
fmt.Println(t.Format(layout))
fmt.Println(t.UTC().Format(layout))
}
func (Time) String
func (t Time) String() string
String返回采用如下格式字符串的格式化时间。
"2006-01-02 15:04:05.999999999 -0700 MST"
func (Time) GobEncode
func (t Time) GobEncode() ([]byte, error)
GobEncode实现了gob.GobEncoder接口。
func (*Time) GobDecode
func (t *Time) GobDecode(data []byte) error
GobEncode实现了gob.GobDecoder接口。
func (Time) MarshalBinary
func (t Time) MarshalBinary() ([]byte, error)
MarshalBinary实现了encoding.BinaryMarshaler接口。
func (*Time) UnmarshalBinary
func (t *Time) UnmarshalBinary(data []byte) error
UnmarshalBinary实现了encoding.BinaryUnmarshaler接口。
func (Time) MarshalJSON
func (t Time) MarshalJSON() ([]byte, error)
MarshalJSON实现了json.Marshaler接口。返回值是用双引号括起来的采用RFC 3339格式进行格式化的时间表示,如果需要会提供小于秒的精度。
func (*Time) UnmarshalJSON
func (t *Time) UnmarshalJSON(data []byte) (err error)
UnmarshalJSON实现了json.Unmarshaler接口。时间被期望是双引号括起来的RFC 3339格式。
func (Time) MarshalText
func (t Time) MarshalText() ([]byte, error)
MarshalText实现了encoding.TextMarshaler接口。返回值是采用RFC 3339格式进行格式化的时间表示,如果需要会提供小于秒的精度。
func (*Time) UnmarshalText
func (t *Time) UnmarshalText(data []byte) (err error)
UnmarshalText实现了encoding.TextUnmarshaler接口。时间被期望采用RFC 3339格式。
type Duration
type Duration int64
Duration类型代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约290年。
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
常用的时间段。没有定义一天或超过一天的单元,以避免夏时制的时区切换的混乱。
要将Duration类型值表示为某时间单元的个数,用除法:
second := time.Second
fmt.Print(int64(second/time.Millisecond)) // prints 1000
要将整数个某时间单元表示为Duration类型值,用乘法:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
func ParseDuration
func ParseDuration(s string) (Duration, error)
ParseDuration解析一个时间段字符串。一个时间段字符串是一个序列,每个片段包含可选的正负号、十进制数、可选的小数部分和单位后缀,如"300ms"、"-1.5h"、"2h45m"。合法的单位有"ns"、"us" /"µs"、"ms"、"s"、"m"、"h"。
func Since
func Since(t Time) Duration
Since返回从t到现在经过的时间,等价于time.Now().Sub(t)。
func (Duration) Hours
func (d Duration) Hours() float64
Hours将时间段表示为float64类型的小时数。
func (Duration) Minutes
func (d Duration) Minutes() float64
Hours将时间段表示为float64类型的分钟数。
func (Duration) Seconds
func (d Duration) Seconds() float64
Hours将时间段表示为float64类型的秒数。
func (Duration) Nanoseconds
func (d Duration) Nanoseconds() int64
Hours将时间段表示为int64类型的纳秒数,等价于int64(d)。
func (Duration) String
func (d Duration) String() string
返回时间段采用"72h3m0.5s"格式的字符串表示。最前面可以有符号,数字+单位为一个单元,开始部分的0值单元会被省略;如果时间段<1s,会使用"ms"、"us"、"ns"来保证第一个单元的数字不是0;如果时间段为0,会返回"0"。
type Timer
type Timer struct {
C <-chan Time
// 内含隐藏或非导出字段
}
Timer类型代表单次时间事件。当Timer到期时,当时的时间会被发送给C,除非Timer是被AfterFunc函数创建的。
func NewTimer
func NewTimer(d Duration) *Timer
NewTimer创建一个Timer,它会在最少过去时间段d后到期,向其自身的C字段发送当时的时间。
func AfterFunc
func AfterFunc(d Duration, f func()) *Timer
AfterFunc另起一个go程等待时间段d过去,然后调用f。它返回一个Timer,可以通过调用其Stop方法来取消等待和对f的调用。
func (*Timer) Reset
func (t *Timer) Reset(d Duration) bool
Reset使t重新开始计时,(本方法返回后再)等待时间段d过去后到期。如果调用时t还在等待中会返回真;如果t已经到期或者被停止了会返回假。
func (*Timer) Stop
func (t *Timer) Stop() bool
Stop停止Timer的执行。如果停止了t会返回真;如果t已经被停止或者过期了会返回假。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
type Ticker
type Ticker struct {
C <-chan Time // 周期性传递时间信息的通道
// 内含隐藏或非导出字段
}
Ticker保管一个通道,并每隔一段时间向其传递"tick"。
func NewTicker
func NewTicker(d Duration) *Ticker
NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。
func (*Ticker) Stop
func (t *Ticker) Stop()
Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
func Sleep
func Sleep(d Duration)
Sleep阻塞当前go程至少d代表的时间段。d<=0时,Sleep会立刻返回。
func After
func After(d Duration) <-chan Time
After会在另一线程经过时间段d后向返回值发送当时的时间。等价于NewTimer(d).C。
select {
case m := <-c:
handle(m)
case <-time.After(5 * time.Minute):
fmt.Println("timed out")
}
func Tick
func Tick(d Duration) <-chan Time
Tick是NewTicker的封装,只提供对Ticker的通道的访问。如果不需要关闭Ticker,本函数就很方便。
c := time.Tick(1 * time.Minute)
for now := range c {
fmt.Printf("%v %s\n", now, statusUpdate())
}
有疑问加站长微信联系(非本文作者)