diff options
Diffstat (limited to 'vendor/github.com/gopackage/ddp/time.go')
-rw-r--r-- | vendor/github.com/gopackage/ddp/time.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/vendor/github.com/gopackage/ddp/time.go b/vendor/github.com/gopackage/ddp/time.go new file mode 100644 index 00000000..584f9ce0 --- /dev/null +++ b/vendor/github.com/gopackage/ddp/time.go @@ -0,0 +1,49 @@ +package ddp + +import ( + "encoding/json" + "io" + "strconv" + "time" +) + +// utcOffset in milliseconds for the current local time (east of UTC). +var utcOffset int64 + +func init() { + _, offsetSeconds := time.Now().Zone() + utcOffset = int64(offsetSeconds * 1000) +} + +// Time is an alias for time.Time with custom json marshalling implementations to support ejson. +type Time struct { + time.Time +} + +// UnixMilli creates a new Time from the given unix millis but in UTC (as opposed to time.UnixMilli which returns +// time in the local time zone). This supports the proper loading of times from EJSON $date objects. +func UnixMilli(i int64) Time { + return Time{Time: time.UnixMilli(i - utcOffset)} +} + +func (t *Time) UnmarshalJSON(b []byte) error { + var data map[string]float64 + err := json.Unmarshal(b, &data) + if err != nil { + return err + } + val, ok := data["$date"] + if !ok { + return io.ErrUnexpectedEOF + } + // The time MUST be UTC but time.UnixMilli uses local time. + // We see what time it is in local time and calculate the offset to UTC + *t = UnixMilli(int64(val)) + + return nil +} + +func (t Time) MarshalJSON() ([]byte, error) { + return []byte("{\"$date\":" + strconv.FormatInt(t.UnixMilli(), 10) + "}"), nil +} + |