diff --git a/llx/primitives.go b/llx/primitives.go index ea27db36d7..6ec3a6e875 100644 --- a/llx/primitives.go +++ b/llx/primitives.go @@ -93,10 +93,10 @@ func TimePrimitive(t *time.Time) *Primitive { } // NeverFutureTime is an indicator for what we consider infinity when looking at time -var NeverFutureTime = time.Unix(1<<63-1, 0) +var NeverFutureTime = time.Unix(1<<63-1, 0).UTC() // NeverPastTime is an indicator for what we consider negative infinity when looking at time -var NeverPastTime = time.Unix(-(1<<63 - 1), 0) +var NeverPastTime = time.Unix(-(1<<63 - 1), 0).UTC() // NeverFuturePrimitive is the special time primitive for the infinite future time var NeverFuturePrimitive = TimePrimitive(&NeverFutureTime) diff --git a/llx/rawdata.go b/llx/rawdata.go index 2e334853a6..61fede63b4 100644 --- a/llx/rawdata.go +++ b/llx/rawdata.go @@ -33,6 +33,12 @@ func (r *RawData) MarshalJSON() ([]byte, error) { return json.Marshal(errData{Error: r.Error.Error()}) } + if r.Type == types.Time { + tv := r.Value.(*time.Time) + ut := tv.Unix() + return json.Marshal(RawData{Type: r.Type, Value: ut}) + } + type rd2 RawData return json.Marshal((*rd2)(r)) } @@ -44,11 +50,17 @@ func (r *RawData) UnmarshalJSON(data []byte) error { case types.Int: r.Value = int64(r.Value.(float64)) case types.Time: - v, err := time.Parse(time.RFC3339, r.Value.(string)) - if err != nil { - return errors.New("failed to parse time into raw data: " + err.Error()) + tv := r.Value.(float64) + // JSON serialization of numbers is limited to 1**53 precision, see: + // https://stackoverflow.com/questions/13502398/json-integers-limit-on-size#comment80159722_13502497 + if tv > (1 << 53) { + r.Value = &NeverFutureTime + } else if tv < (-(1 << 53)) { + r.Value = &NeverPastTime + } else { + v := time.Unix(int64(tv), 0).UTC() + r.Value = &v } - r.Value = &v } return nil } diff --git a/llx/rawdata_test.go b/llx/rawdata_test.go index 5311b6158d..8a770c609e 100644 --- a/llx/rawdata_test.go +++ b/llx/rawdata_test.go @@ -190,8 +190,10 @@ func TestRawData_JSON(t *testing.T) { RegexData(""), RegexData("r"), TimeData(time.Time{}), + TimeData(NeverFutureTime), + TimeData(NeverPastTime), // TODO: the raw comparison here does not come out right, because of nano time - // TimeData(now), + // TimeData(now.UTC()), ArrayData([]interface{}{"a", "b"}, types.String), MapData(map[string]interface{}{"a": "b"}, types.String), {Error: errors.New("test")},