-
Notifications
You must be signed in to change notification settings - Fork 17
/
datetime.go
164 lines (140 loc) · 3.7 KB
/
datetime.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
package easypost
import (
"net/url"
"time"
)
type DateTime time.Time
func (dt *DateTime) UnmarshalJSON(b []byte) (err error) {
// if string is empty, return nil
if string(b) == "null" {
return
}
var t time.Time
// try to parse
asDateTime, err := DateTimeFromString(string(b))
if err == nil {
*dt = asDateTime
return nil
}
// last ditch effort, fallback to whatever the JSON marshaller thinks
err = t.UnmarshalJSON(b)
if err != nil {
return err
}
*dt = DateTime(t)
return nil
}
func (dt *DateTime) MarshalJSON() ([]byte, error) {
return time.Time(*dt).MarshalJSON()
}
func (dt *DateTime) String() string {
return time.Time(*dt).String()
}
// EncodeValues implements the query.Encoder interface of how to encode the DateTime for a URL query string
func (dt *DateTime) EncodeValues(key string, values *url.Values) error {
values.Set(key, time.Time(*dt).Format(time.RFC3339)) // RFC3339 is the default format for time.Time
return nil
}
func (dt *DateTime) AsTime() time.Time {
return time.Time(*dt)
}
// NewDateTime returns the DateTime corresponding to
//
// yyyy-mm-dd hh:mm:ss + nsec nanoseconds
//
// in the appropriate zone for that time in the given location.
//
// The month, day, hour, min, sec, and nsec values may be outside
// their usual ranges and will be normalized during the conversion.
// For example, October 32 converts to November 1.
//
// A daylight savings time transition skips or repeats times.
// For example, in the United States, March 13, 2011 2:15am never occurred,
// while November 6, 2011 1:15am occurred twice. In such cases, the
// choice of time zone, and therefore the time, is not well-defined.
// NewDateTime returns a time that is correct in one of the two zones involved
// in the transition, but it does not guarantee which.
//
// NewDateTime panics if loc is nil.
func NewDateTime(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) DateTime {
timeDate := time.Date(year, month, day, hour, min, sec, nsec, loc)
return DateTimeFromTime(timeDate)
}
// DateTimeFromTime construct a DateTime from a time.Time
func DateTimeFromTime(t time.Time) DateTime {
return DateTime(t)
}
func DateTimeFromString(s string) (dt DateTime, err error) {
var t time.Time
// try to parse
// 2006-01-02
t, err = time.Parse(`"2006-01-02"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse
// 2006-01-02T15:04:05
t, err = time.Parse(`"2006-01-02T15:04:05"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse
// 2006-01-02T15:04:05Z
t, err = time.Parse(`"2006-01-02T15:04:05Z"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC3339 (default for time.Time)
// 2006-01-02T15:04:05Z07:00
t, err = time.Parse(`"`+time.RFC3339+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC3339Nano
// 2006-01-02T15:04:05.999999999Z07:00
t, err = time.Parse(`"`+time.RFC3339Nano+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC1123
// Mon, 02 Jan 2006 15:04:05 MST
t, err = time.Parse(`"`+time.RFC1123+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC1123Z
// Mon, 02 Jan 2006 15:04:05 -0700
t, err = time.Parse(`"`+time.RFC1123Z+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC822
// 02 Jan 06 15:04 MST
t, err = time.Parse(`"`+time.RFC822+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC822Z
// 02 Jan 06 15:04 -0700
t, err = time.Parse(`"`+time.RFC822Z+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
// try to parse as RFC850
// Monday, 02-Jan-06 15:04:05 MST
t, err = time.Parse(`"`+time.RFC850+`"`, s)
if err == nil {
dt = DateTime(t)
return
}
return
}