forked from dgrijalva/jwt-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
time.go
78 lines (69 loc) · 2.05 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
package jwt
import (
"encoding/json"
"reflect"
"time"
)
// TimePrecision determines how precisely time is measured
// by this library. When serializing and deserialzing tokens,
// time values are automatically truncated to this precision.
// See the time package's Truncate method for more detail
const TimePrecision = time.Microsecond
// Time is how this library represents time values. It's mostly
// a wrapper for the standard library's time.Time, but adds
// specialized JSON decoding behavior to interop with the way
// time is represented by JWT. Also makes it possible to represent
// nil values.
type Time struct {
time.Time
}
// NewTime creates a new Time value from a float64, following
// the JWT spec.
func NewTime(t float64) *Time {
return At(time.Unix(0, int64(t*float64(time.Second))))
}
// Now returns a new Time value using the current time.
// You can override Now by changing the value of TimeFunc
func Now() *Time {
return At(TimeFunc())
}
// At makes a Time value from a standard library time.Time value
func At(at time.Time) *Time {
return &Time{at.Truncate(TimePrecision)}
}
// ParseTime is used for creating a Time value from various
// possible representations that can occur in serialization.
func ParseTime(value interface{}) (*Time, error) {
switch v := value.(type) {
case int64:
return NewTime(float64(v)), nil
case float64:
return NewTime(v), nil
case json.Number:
vv, err := v.Float64()
if err != nil {
return nil, err
}
return NewTime(vv), nil
case nil:
return nil, nil
default:
return nil, &json.UnsupportedTypeError{Type: reflect.TypeOf(v)}
}
}
// UnmarshalJSON implements the json package's Unmarshaler interface
func (t *Time) UnmarshalJSON(data []byte) error {
var value json.Number
err := json.Unmarshal(data, &value)
if err != nil {
return err
}
v, err := ParseTime(value)
*t = *v
return err
}
// MarshalJSON implements the json package's Marshaler interface
func (t *Time) MarshalJSON() ([]byte, error) {
f := float64(t.Truncate(TimePrecision).UnixNano()) / float64(time.Second)
return json.Marshal(f)
}