Skip to content

GODRIVER-1688 Remove UnixNano call from NewDateTimeFromTime #463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
})
})
}