Skip to content

Commit 7872942

Browse files
author
Divjot Arora
committed
GODRIVER-1688 Remove UnixNano call from NewDateTimeFromTime (#463)
1 parent 49e0fa5 commit 7872942

File tree

5 files changed

+22
-4
lines changed

5 files changed

+22
-4
lines changed

bson/bsoncodec/default_value_encoders.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.Valu
252252
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
253253
}
254254
tt := val.Interface().(time.Time)
255-
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
255+
dt := primitive.NewDateTimeFromTime(tt)
256+
return vw.WriteDateTime(int64(dt))
256257
}
257258

258259
// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.

bson/bsoncodec/time_codec.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"go.mongodb.org/mongo-driver/bson/bsonoptions"
1515
"go.mongodb.org/mongo-driver/bson/bsonrw"
1616
"go.mongodb.org/mongo-driver/bson/bsontype"
17+
"go.mongodb.org/mongo-driver/bson/primitive"
1718
)
1819

1920
const (
@@ -101,5 +102,6 @@ func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
101102
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
102103
}
103104
tt := val.Interface().(time.Time)
104-
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
105+
dt := primitive.NewDateTimeFromTime(tt)
106+
return vw.WriteDateTime(int64(dt))
105107
}

bson/bsonrw/extjson_wrappers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func parseDatetimeString(data string) (int64, error) {
217217
return 0, fmt.Errorf("invalid $date value string: %s", data)
218218
}
219219

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

223223
func parseDatetimeObject(data *extJSONObject) (d int64, err error) {

bson/primitive/primitive.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (d DateTime) Time() time.Time {
7373

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

7979
// Null represents the BSON null value.

bson/primitive/primitive_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package primitive
99
import (
1010
"encoding/json"
1111
"testing"
12+
"time"
1213

1314
"github.com/stretchr/testify/require"
1415
"go.mongodb.org/mongo-driver/internal/testutil/assert"
@@ -102,4 +103,18 @@ func TestDateTime(t *testing.T) {
102103
assert.Equal(t, DateTime(0), dt, "expected DateTime value to be 0, got %v", dt)
103104
})
104105
})
106+
t.Run("NewDateTimeFromTime", func(t *testing.T) {
107+
t.Run("range is not limited", func(t *testing.T) {
108+
// If the implementation internally calls time.Time.UnixNano(), the constructor cannot handle times after
109+
// the year 2262.
110+
111+
timeFormat := "2006-01-02T15:04:05.999Z07:00"
112+
timeString := "3001-01-01T00:00:00Z"
113+
tt, err := time.Parse(timeFormat, timeString)
114+
assert.Nil(t, err, "Parse error: %v", err)
115+
116+
dt := NewDateTimeFromTime(tt)
117+
assert.True(t, dt > 0, "expected a valid DateTime greater than 0, got %v", dt)
118+
})
119+
})
105120
}

0 commit comments

Comments
 (0)