forked from Laisky/go-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
time.go
174 lines (142 loc) · 3.82 KB
/
time.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package utils
import (
"context"
"strconv"
"sync"
"sync/atomic"
"time"
)
// UTCNow 获取当前 UTC 时间
func UTCNow() time.Time {
return time.Now().UTC()
}
// ParseUnix2String can parse unix timestamp(int64) to string
func ParseUnix2String(ts int64, layout string) string {
return ParseUnix2UTC(ts).Format(layout)
}
// ParseUnix2UTC convert unix to UTC time
func ParseUnix2UTC(ts int64) time.Time {
return time.Unix(ts, 0).UTC()
}
var (
// ParseTs2UTC can parse unix timestamp(int64) to time.Time
ParseTs2UTC = ParseUnix2UTC
// ParseTs2String can parse unix timestamp(int64) to string
ParseTs2String = ParseUnix2String
)
// ParseUnixNano2UTC convert unixnano to UTC time
func ParseUnixNano2UTC(ts int64) time.Time {
return time.Unix(ts/1e9, ts%1e9).UTC()
}
// ParseHex2UTC parse hex to UTC time
func ParseHex2UTC(ts string) (t time.Time, err error) {
var ut int64
if ut, err = strconv.ParseInt(ts, 16, 64); err != nil {
return
}
return ParseUnix2UTC(ut), nil
}
// ParseHexNano2UTC parse hex contains nano to UTC time
func ParseHexNano2UTC(ts string) (t time.Time, err error) {
var ut int64
if ut, err = strconv.ParseInt(ts, 16, 64); err != nil {
return
}
return ParseUnixNano2UTC(ut), nil
}
var ( // compatable to old version
// ParseTs2Time can parse unix timestamp(int64) to time.Time
ParseTs2Time = ParseTs2UTC
// UnixNano2UTC convert unixnano to UTC time
UnixNano2UTC = ParseUnixNano2UTC
)
// ---------------------------------------
// Clock
// ---------------------------------------
// ClockItf high performance lazy clock
type ClockItf interface {
GetTimeInRFC3339Nano() string
GetUTCNow() time.Time
SetupInterval(time.Duration)
Close()
}
const defaultClockInterval = 100 * time.Millisecond
// SetupClock setup internal Clock with step
func SetupClock(refreshInterval time.Duration) {
if Clock == nil {
Clock = NewClock(context.Background(), refreshInterval)
} else {
Clock.SetupInterval(refreshInterval)
}
}
var (
// Clock high performance time utils, replace Clock1
Clock = NewClock(context.Background(), defaultClockInterval)
// compatable to old version
// Clock2 high performance time utils
Clock2 = Clock
// NewClock2 create new Clock
NewClock2 = NewClock
)
// Clock2Type high performance clock with lazy refreshing
type Clock2Type ClockType
// ClockType high performance clock with lazy refreshing
type ClockType struct {
sync.RWMutex
stopChan chan struct{}
interval time.Duration
now int64
}
// NewClock create new Clock
func NewClock(ctx context.Context, refreshInterval time.Duration) *ClockType {
c := &ClockType{
interval: refreshInterval,
now: UTCNow().UnixNano(),
stopChan: make(chan struct{}),
}
go c.runRefresh(ctx)
return c
}
// Close stop Clock update
func (c *ClockType) Close() {
c.stopChan <- struct{}{}
}
func (c *ClockType) runRefresh(ctx context.Context) {
var interval time.Duration
for {
select {
case <-c.stopChan:
return
case <-ctx.Done():
return
default:
c.RLock()
interval = c.interval
c.RUnlock()
time.Sleep(interval)
}
atomic.StoreInt64(&c.now, time.Now().UnixNano())
}
}
// GetUTCNow return Clock current time.Time
func (c *ClockType) GetUTCNow() (t time.Time) {
return UnixNano2UTC(atomic.LoadInt64(&c.now))
}
// GetTimeInRFC3339Nano return Clock current time in string
func (c *ClockType) GetTimeInRFC3339Nano() string {
return c.GetUTCNow().Format(time.RFC3339Nano)
}
// SetupInterval setup update interval
func (c *ClockType) SetupInterval(interval time.Duration) {
c.Lock()
defer c.Unlock()
c.interval = interval
}
// GetTimeInHex return current time in hex
func (c *ClockType) GetTimeInHex() string {
return strconv.FormatInt(c.GetUTCNow().Unix(), 16)
}
// GetNanoTimeInHex return current time with nano in hex
func (c *ClockType) GetNanoTimeInHex() string {
return strconv.FormatInt(c.GetUTCNow().UnixNano(), 16)
}