-
Notifications
You must be signed in to change notification settings - Fork 1
/
timestamp.go
193 lines (156 loc) · 4.76 KB
/
timestamp.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Package timestamp is used for marshaling/unmarshaling UNIX timestamps
// to/from JSON, GOB and BSON by implementing the appropriate interfaces for
// encoding/json, encoding/gob and labix.org/v2/mgo respectively.
package timestamp
import (
"encoding/xml"
"fmt"
"github.com/globalsign/mgo/bson"
bson2 "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"strconv"
"time"
)
// Timestamp is a named alias for time.Time,
// it represents a UNIX timestamp
// and provides functions for marshaling and unmarshaling both to/from JSON and
// to/from BSON
type Timestamp time.Time
func (t Timestamp) MarshalJSON() ([]byte, error) {
ts := t.Time().Unix()
stamp := fmt.Sprint(ts)
return []byte(stamp), nil
}
// UnmarshalJSON defines how encoding/json unmarshals the object from JSON,
// a UNIX timestamp string is converted to int which is used for the Timestamp
// object value
func (t *Timestamp) UnmarshalJSON(b []byte) error {
ts, err := strconv.Atoi(string(b))
if err != nil {
return err
}
int64ts := int64(ts)
if len(b) > 10 {
//support for milisecond timestamps
int64ts = int64(ts / 1000)
}
*t = Timestamp(time.Unix(int64ts, 0).UTC())
return nil
}
// GetBSON defines how labix.org/v2/mgo marshals the object to BSON,
// the result is a time.Time object which is then handled by mgo
func (t Timestamp) GetBSON() (interface{}, error) {
if t.Time().IsZero() {
return nil, nil
}
return t.Time(), nil
}
// SetBSON defines how labix.org/v2/mgo unmarshals the object from BSON,
// the raw BSON data is unmarshaled to a time.Time object which is used for the
// Timestamp object value
func (t *Timestamp) SetBSON(raw bson.Raw) error {
var tm time.Time
if err := raw.Unmarshal(&tm); err != nil {
return err
}
*t = Timestamp(tm)
return nil
}
func (t *Timestamp) MarshalBSONValue() (bsontype.Type, []byte, error) {
if t == nil {
return bson2.MarshalValue(time.Time{})
}
tm := t.Time()
return bson2.MarshalValue(tm)
}
func (t *Timestamp) UnmarshalBSONValue(typ bsontype.Type, data []byte) error {
var tm time.Time
rv := bson2.RawValue{Type: typ, Value: data}
if err := rv.Unmarshal(&tm); err != nil {
return err
}
*t = Timestamp(tm)
return nil
}
// String returns the string representation of the Timestamp object,
// it is equal to the time.Time string representation of the Timestamp object
// value
func (t Timestamp) String() string {
return t.Time().String()
}
// Time returns a time.Time object with the same time value as the Timestamp
// object
func (t Timestamp) Time() time.Time {
if time.Time(t).IsZero() {
return time.Unix(0, 0)
}
return time.Time(t)
}
// Now returns a pointer to a Timestamp object with the current time,
// it is equal to creating a Timestamp object from time.Now()
func Now() *Timestamp {
t := Timestamp(time.Now())
return &t
}
// Unix calls the Unix() method of a time.Time object with the same time values
// as the timestamp object
func (t Timestamp) Unix() int64 {
return t.Time().Unix()
}
// Time returns a pointer to a Timestamp object which is created
// from a time.Time object
func Time(t time.Time) *Timestamp {
ts := Timestamp(t)
return &ts
}
// Unix returns a pointer to a Timestamp object which is created from
// a UNIX timestamp
func Unix(sec, nsec int64) *Timestamp {
t := time.Unix(sec, nsec).UTC()
return Time(t)
}
// GobEncode returns a byte slice representing the encoding of the Timestamp
// object, it implements the GobEncoder interface
func (t Timestamp) GobEncode() ([]byte, error) {
return t.Time().MarshalBinary()
}
// GobDecode decodes a Timestamp object from a byte slice
// and overwrites the receiver,
// it implements the GobDecoder interface
// GobDecode implements the gob.GobDecoder interface.
func (t *Timestamp) GobDecode(data []byte) error {
var tm time.Time
if err := tm.UnmarshalBinary(data); err != nil {
return err
}
*t = Timestamp(tm)
return nil
}
// MarshalXML defines how encoding/xml marshals the object to XML,
// the result is a string of the UNIX timestamp
func (t Timestamp) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
ts := t.Time().Unix()
stamp := fmt.Sprint(ts)
return e.EncodeElement(stamp, start)
}
// UnmarshalXML defines how encoding/xml unmarshals the object from XML,
// a UNIX timestamp string is converted to int which is used for the Timestamp
// object value
func (t *Timestamp) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var content string
if err := d.DecodeElement(&content, &start); err != nil {
return err
}
ts, err := strconv.Atoi(content)
if err != nil {
return err
}
*t = Timestamp(time.Unix(int64(ts), 0))
return nil
}
func (t Timestamp) ToMili() int64 {
return t.Time().UnixNano() / int64(time.Millisecond)
}
func (t *Timestamp) IsEmpty() bool {
return t == nil || t.Time().IsZero() || t.Unix() == 0
}