This repository has been archived by the owner on Apr 5, 2021. It is now read-only.
/
time.go
117 lines (95 loc) · 2.72 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
package firebase
import (
"strconv"
"time"
)
const (
// serverTimestampValue is the special value sent to Firebase for server
// timestamps.
serverTimestampValue = `{".sv":"timestamp"}`
)
// ServerTimestamp provides a json.Marshal'able (and Unmarshal'able) type for
// use with Firebase.
//
// When this type has a zero value, and is serialized to Firebase, Firebase
// will store the current time in milliseconds since the Unix epoch. When the
// value is unserialized from Firebase, then the stored time (ie, milliseconds
// since the Unix epoch) will be returned.
type ServerTimestamp time.Time
// MarshalJSON satisfies the json.Marshaler interface.
func (st ServerTimestamp) MarshalJSON() ([]byte, error) {
t := time.Time(st)
// special firebase value
if t.IsZero() {
return []byte(serverTimestampValue), nil
}
return []byte(strconv.FormatInt(t.UnixNano()/int64(time.Millisecond), 10)), nil
}
// UnmarshalJSON satisfies the json.Unmarshaler interface.
func (st *ServerTimestamp) UnmarshalJSON(buf []byte) error {
// special firebase value
v := string(buf)
switch v {
case serverTimestampValue:
*st = ServerTimestamp(time.Now())
return nil
case "null":
*st = ServerTimestamp{}
return nil
}
i, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return err
}
*st = ServerTimestamp(time.Unix(0, i*int64(time.Millisecond)))
return nil
}
// Time returns the ServerTimestamp as time.Time.
func (st ServerTimestamp) Time() time.Time {
return time.Time(st)
}
// String satisfies the stringer interface.
func (st ServerTimestamp) String() string {
return time.Time(st).String()
}
// Time provides a json.Marshal'able (and Unmarshal'able) type for that is
// compatible with Firebase server timestamps.
//
// The Firebase representation of time is a JSON Number of milliseconds since
// the Unix epoch.
type Time time.Time
// MarshalJSON satisfies the json.Marshaler interface.
func (t Time) MarshalJSON() ([]byte, error) {
z := time.Time(t)
return []byte(strconv.FormatInt(z.UnixNano()/int64(time.Millisecond), 10)), nil
}
// UnmarshalJSON satisfies the json.Unmarshaler interface.
func (t *Time) UnmarshalJSON(buf []byte) error {
v := string(buf)
if v == "null" {
*t = Time{}
return nil
}
i, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return err
}
*t = Time(time.Unix(0, i*int64(time.Millisecond)))
return nil
}
// Time returns the Time as time.Time.
func (t Time) Time() time.Time {
return time.Time(t)
}
// String satisfies the stringer interface.
func (t Time) String() string {
return time.Time(t).String()
}
// Error is a general Firebase error.
type Error struct {
Err string `json:"error"`
}
// Error satisfies the error interface.
func (e *Error) Error() string {
return "firebase: " + e.Err
}