/
time.go
137 lines (117 loc) · 2.77 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
package core
import (
"encoding/json"
"time"
)
const dateFormat = "2006-01-02"
// DateTime wraps time.Time and adapts its JSON representation
// to conform to a RFC3339 date (e.g. 2006-01-02).
//
// Ref: https://ijmacd.github.io/rfc3339-iso8601
type Date struct {
t *time.Time
}
// NewDate returns a new *Date. If the given time.Time
// is nil, nil will be returned.
func NewDate(t time.Time) *Date {
return &Date{t: &t}
}
// NewOptionalDate returns a new *Date. If the given time.Time
// is nil, nil will be returned.
func NewOptionalDate(t *time.Time) *Date {
if t == nil {
return nil
}
return &Date{t: t}
}
// Time returns the Date's underlying time, if any. If the
// date is nil, the zero value is returned.
func (d *Date) Time() time.Time {
if d == nil || d.t == nil {
return time.Time{}
}
return *d.t
}
// TimePtr returns a pointer to the Date's underlying time.Time, if any.
func (d *Date) TimePtr() *time.Time {
if d == nil || d.t == nil {
return nil
}
if d.t.IsZero() {
return nil
}
return d.t
}
func (d *Date) MarshalJSON() ([]byte, error) {
if d == nil || d.t == nil {
return nil, nil
}
return json.Marshal(d.t.Format(dateFormat))
}
func (d *Date) UnmarshalJSON(data []byte) error {
var raw string
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
parsedTime, err := time.Parse(dateFormat, raw)
if err != nil {
return err
}
*d = Date{t: &parsedTime}
return nil
}
// DateTime wraps time.Time and adapts its JSON representation
// to conform to a RFC3339 date-time (e.g. 2017-07-21T17:32:28Z).
//
// Ref: https://ijmacd.github.io/rfc3339-iso8601
type DateTime struct {
t *time.Time
}
// NewDateTime returns a new *DateTime.
func NewDateTime(t time.Time) *DateTime {
return &DateTime{t: &t}
}
// NewOptionalDateTime returns a new *DateTime. If the given time.Time
// is nil, nil will be returned.
func NewOptionalDateTime(t *time.Time) *DateTime {
if t == nil {
return nil
}
return &DateTime{t: t}
}
// Time returns the DateTime's underlying time, if any. If the
// date-time is nil, the zero value is returned.
func (d *DateTime) Time() time.Time {
if d == nil || d.t == nil {
return time.Time{}
}
return *d.t
}
// TimePtr returns a pointer to the DateTime's underlying time.Time, if any.
func (d *DateTime) TimePtr() *time.Time {
if d == nil || d.t == nil {
return nil
}
if d.t.IsZero() {
return nil
}
return d.t
}
func (d *DateTime) MarshalJSON() ([]byte, error) {
if d == nil || d.t == nil {
return nil, nil
}
return json.Marshal(d.t.Format(time.RFC3339))
}
func (d *DateTime) UnmarshalJSON(data []byte) error {
var raw string
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
parsedTime, err := time.Parse(time.RFC3339, raw)
if err != nil {
return err
}
*d = DateTime{t: &parsedTime}
return nil
}