Skip to content

Commit

Permalink
GODRIVER-1688 Remove UnixNano call from NewDateTimeFromTime (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
Divjot Arora committed Jul 22, 2020
1 parent 49e0fa5 commit 7872942
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 4 deletions.
3 changes: 2 additions & 1 deletion bson/bsoncodec/default_value_encoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.Valu
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
}
tt := val.Interface().(time.Time)
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
dt := primitive.NewDateTimeFromTime(tt)
return vw.WriteDateTime(int64(dt))
}

// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
Expand Down
4 changes: 3 additions & 1 deletion bson/bsoncodec/time_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"go.mongodb.org/mongo-driver/bson/bsonoptions"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/bson/primitive"
)

const (
Expand Down Expand Up @@ -101,5 +102,6 @@ func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
}
tt := val.Interface().(time.Time)
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
dt := primitive.NewDateTimeFromTime(tt)
return vw.WriteDateTime(int64(dt))
}
2 changes: 1 addition & 1 deletion bson/bsonrw/extjson_wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func parseDatetimeString(data string) (int64, error) {
return 0, fmt.Errorf("invalid $date value string: %s", data)
}

return t.Unix()*1e3 + int64(t.Nanosecond())/1e6, nil
return int64(primitive.NewDateTimeFromTime(t)), nil
}

func parseDatetimeObject(data *extJSONObject) (d int64, err error) {
Expand Down
2 changes: 1 addition & 1 deletion bson/primitive/primitive.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (d DateTime) Time() time.Time {

// NewDateTimeFromTime creates a new DateTime from a Time.
func NewDateTimeFromTime(t time.Time) DateTime {
return DateTime(t.UnixNano() / 1000000)
return DateTime(t.Unix()*1e3 + int64(t.Nanosecond())/1e6)
}

// Null represents the BSON null value.
Expand Down
15 changes: 15 additions & 0 deletions bson/primitive/primitive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package primitive
import (
"encoding/json"
"testing"
"time"

"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/internal/testutil/assert"
Expand Down Expand Up @@ -102,4 +103,18 @@ func TestDateTime(t *testing.T) {
assert.Equal(t, DateTime(0), dt, "expected DateTime value to be 0, got %v", dt)
})
})
t.Run("NewDateTimeFromTime", func(t *testing.T) {
t.Run("range is not limited", func(t *testing.T) {
// If the implementation internally calls time.Time.UnixNano(), the constructor cannot handle times after
// the year 2262.

timeFormat := "2006-01-02T15:04:05.999Z07:00"
timeString := "3001-01-01T00:00:00Z"
tt, err := time.Parse(timeFormat, timeString)
assert.Nil(t, err, "Parse error: %v", err)

dt := NewDateTimeFromTime(tt)
assert.True(t, dt > 0, "expected a valid DateTime greater than 0, got %v", dt)
})
})
}

0 comments on commit 7872942

Please sign in to comment.