...
1
2
3
4
5 package uuid
6
7 import (
8 "encoding/binary"
9 "sync"
10 "time"
11 )
12
13
14
15 type Time int64
16
17 const (
18 lillian = 2299160
19 unix = 2440587
20 epoch = unix - lillian
21 g1582 = epoch * 86400
22 g1582ns100 = g1582 * 10000000
23 )
24
25 var (
26 timeMu sync.Mutex
27 lasttime uint64
28 clockSeq uint16
29
30 timeNow = time.Now
31 )
32
33
34
35 func (t Time) UnixTime() (sec, nsec int64) {
36 sec = int64(t - g1582ns100)
37 nsec = (sec % 10000000) * 100
38 sec /= 10000000
39 return sec, nsec
40 }
41
42
43
44
45 func GetTime() (Time, uint16, error) {
46 defer timeMu.Unlock()
47 timeMu.Lock()
48 return getTime()
49 }
50
51 func getTime() (Time, uint16, error) {
52 t := timeNow()
53
54
55 if clockSeq == 0 {
56 setClockSequence(-1)
57 }
58 now := uint64(t.UnixNano()/100) + g1582ns100
59
60
61
62 if now <= lasttime {
63 clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
64 }
65 lasttime = now
66 return Time(now), clockSeq, nil
67 }
68
69
70
71
72
73
74
75
76 func ClockSequence() int {
77 defer timeMu.Unlock()
78 timeMu.Lock()
79 return clockSequence()
80 }
81
82 func clockSequence() int {
83 if clockSeq == 0 {
84 setClockSequence(-1)
85 }
86 return int(clockSeq & 0x3fff)
87 }
88
89
90
91 func SetClockSequence(seq int) {
92 defer timeMu.Unlock()
93 timeMu.Lock()
94 setClockSequence(seq)
95 }
96
97 func setClockSequence(seq int) {
98 if seq == -1 {
99 var b [2]byte
100 randomBits(b[:])
101 seq = int(b[0])<<8 | int(b[1])
102 }
103 oldSeq := clockSeq
104 clockSeq = uint16(seq&0x3fff) | 0x8000
105 if oldSeq != clockSeq {
106 lasttime = 0
107 }
108 }
109
110
111
112 func (uuid UUID) Time() Time {
113 var t Time
114 switch uuid.Version() {
115 case 6:
116 time := binary.BigEndian.Uint64(uuid[:8])
117 t = Time(time)
118 case 7:
119 time := binary.BigEndian.Uint64(uuid[:8])
120 t = Time((time>>16)*10000 + g1582ns100)
121 default:
122 time := int64(binary.BigEndian.Uint32(uuid[0:4]))
123 time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
124 time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
125 t = Time(time)
126 }
127 return t
128 }
129
130
131
132 func (uuid UUID) ClockSequence() int {
133 return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
134 }
135
View as plain text