1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package strfmt
16
17 import (
18 "database/sql/driver"
19 "encoding/binary"
20 "encoding/json"
21 "errors"
22 "fmt"
23 "regexp"
24 "strings"
25 "time"
26
27 "go.mongodb.org/mongo-driver/bson"
28
29 "go.mongodb.org/mongo-driver/bson/bsontype"
30 )
31
32 var (
33
34
35 UnixZero = time.Unix(0, 0).UTC()
36 )
37
38 func init() {
39 dt := DateTime{}
40 Default.Add("datetime", &dt, IsDateTime)
41 }
42
43
44 func IsDateTime(str string) bool {
45 if len(str) < 4 {
46 return false
47 }
48 s := strings.Split(strings.ToLower(str), "t")
49 if len(s) < 2 || !IsDate(s[0]) {
50 return false
51 }
52
53 matches := rxDateTime.FindAllStringSubmatch(s[1], -1)
54 if len(matches) == 0 || len(matches[0]) == 0 {
55 return false
56 }
57 m := matches[0]
58 res := m[1] <= "23" && m[2] <= "59" && m[3] <= "59"
59 return res
60 }
61
62 const (
63
64 RFC3339Millis = "2006-01-02T15:04:05.000Z07:00"
65
66 RFC3339MillisNoColon = "2006-01-02T15:04:05.000Z0700"
67
68 RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00"
69
70 RFC3339MicroNoColon = "2006-01-02T15:04:05.000000Z0700"
71
72 ISO8601LocalTime = "2006-01-02T15:04:05"
73
74 ISO8601TimeWithReducedPrecision = "2006-01-02T15:04Z"
75
76 ISO8601TimeWithReducedPrecisionLocaltime = "2006-01-02T15:04"
77
78 ISO8601TimeUniversalSortableDateTimePattern = "2006-01-02 15:04:05"
79
80 ISO8601TimeUniversalSortableDateTimePatternShortForm = "2006-01-02"
81
82 DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$`
83 )
84
85 var (
86 rxDateTime = regexp.MustCompile(DateTimePattern)
87
88
89 DateTimeFormats = []string{RFC3339Micro, RFC3339MicroNoColon, RFC3339Millis, RFC3339MillisNoColon, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime, ISO8601TimeWithReducedPrecision, ISO8601TimeWithReducedPrecisionLocaltime, ISO8601TimeUniversalSortableDateTimePattern, ISO8601TimeUniversalSortableDateTimePatternShortForm}
90
91
92 MarshalFormat = RFC3339Millis
93
94
95
96 NormalizeTimeForMarshal = func(t time.Time) time.Time { return t }
97
98
99 DefaultTimeLocation = time.UTC
100 )
101
102
103 func ParseDateTime(data string) (DateTime, error) {
104 if data == "" {
105 return NewDateTime(), nil
106 }
107 var lastError error
108 for _, layout := range DateTimeFormats {
109 dd, err := time.ParseInLocation(layout, data, DefaultTimeLocation)
110 if err != nil {
111 lastError = err
112 continue
113 }
114 return DateTime(dd), nil
115 }
116 return DateTime{}, lastError
117 }
118
119
120
121
122
123
124
125 type DateTime time.Time
126
127
128 func NewDateTime() DateTime {
129 return DateTime(time.Unix(0, 0).UTC())
130 }
131
132
133 func (t DateTime) String() string {
134 return NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat)
135 }
136
137
138 func (t *DateTime) IsZero() bool {
139 if t == nil {
140 return true
141 }
142 return time.Time(*t).IsZero()
143 }
144
145
146 func (t *DateTime) IsUnixZero() bool {
147 if t == nil {
148 return true
149 }
150 return time.Time(*t).Equal(UnixZero)
151 }
152
153
154 func (t DateTime) MarshalText() ([]byte, error) {
155 return []byte(t.String()), nil
156 }
157
158
159 func (t *DateTime) UnmarshalText(text []byte) error {
160 tt, err := ParseDateTime(string(text))
161 if err != nil {
162 return err
163 }
164 *t = tt
165 return nil
166 }
167
168
169 func (t *DateTime) Scan(raw interface{}) error {
170
171 switch v := raw.(type) {
172 case []byte:
173 return t.UnmarshalText(v)
174 case string:
175 return t.UnmarshalText([]byte(v))
176 case time.Time:
177 *t = DateTime(v)
178 case nil:
179 *t = DateTime{}
180 default:
181 return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v", v)
182 }
183
184 return nil
185 }
186
187
188 func (t DateTime) Value() (driver.Value, error) {
189 return driver.Value(t.String()), nil
190 }
191
192
193 func (t DateTime) MarshalJSON() ([]byte, error) {
194 return json.Marshal(NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat))
195 }
196
197
198 func (t *DateTime) UnmarshalJSON(data []byte) error {
199 if string(data) == jsonNull {
200 return nil
201 }
202
203 var tstr string
204 if err := json.Unmarshal(data, &tstr); err != nil {
205 return err
206 }
207 tt, err := ParseDateTime(tstr)
208 if err != nil {
209 return err
210 }
211 *t = tt
212 return nil
213 }
214
215
216 func (t DateTime) MarshalBSON() ([]byte, error) {
217 return bson.Marshal(bson.M{"data": t})
218 }
219
220
221 func (t *DateTime) UnmarshalBSON(data []byte) error {
222 var obj struct {
223 Data DateTime
224 }
225
226 if err := bson.Unmarshal(data, &obj); err != nil {
227 return err
228 }
229
230 *t = obj.Data
231
232 return nil
233 }
234
235
236
237
238
239
240 func (t DateTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
241
242
243
244 tNorm := NormalizeTimeForMarshal(time.Time(t))
245 i64 := tNorm.Unix()*1000 + int64(tNorm.Nanosecond())/1e6
246
247 buf := make([]byte, 8)
248 binary.LittleEndian.PutUint64(buf, uint64(i64))
249
250 return bson.TypeDateTime, buf, nil
251 }
252
253
254
255
256
257 func (t *DateTime) UnmarshalBSONValue(tpe bsontype.Type, data []byte) error {
258 if tpe == bson.TypeNull {
259 *t = DateTime{}
260 return nil
261 }
262
263 if len(data) != 8 {
264 return errors.New("bson date field length not exactly 8 bytes")
265 }
266
267 i64 := int64(binary.LittleEndian.Uint64(data))
268
269 *t = DateTime(time.Unix(i64/1000, i64%1000*1000000))
270
271 return nil
272 }
273
274
275 func (t *DateTime) DeepCopyInto(out *DateTime) {
276 *out = *t
277 }
278
279
280 func (t *DateTime) DeepCopy() *DateTime {
281 if t == nil {
282 return nil
283 }
284 out := new(DateTime)
285 t.DeepCopyInto(out)
286 return out
287 }
288
289
290 func (t DateTime) GobEncode() ([]byte, error) {
291 return t.MarshalBinary()
292 }
293
294
295 func (t *DateTime) GobDecode(data []byte) error {
296 return t.UnmarshalBinary(data)
297 }
298
299
300 func (t DateTime) MarshalBinary() ([]byte, error) {
301 return NormalizeTimeForMarshal(time.Time(t)).MarshalBinary()
302 }
303
304
305 func (t *DateTime) UnmarshalBinary(data []byte) error {
306 var original time.Time
307
308 err := original.UnmarshalBinary(data)
309 if err != nil {
310 return err
311 }
312
313 *t = DateTime(original)
314
315 return nil
316 }
317
318
319 func (t DateTime) Equal(t2 DateTime) bool {
320 return time.Time(t).Equal(time.Time(t2))
321 }
322
View as plain text