From a0820d51ed1b759e0cfc362f0fce3bc7a0e82cb0 Mon Sep 17 00:00:00 2001 From: James Crosby Date: Tue, 19 Feb 2019 13:51:18 +0000 Subject: [PATCH] fix(timestamp): getTimestamp support times beyond 2038 * Fix getTimestamp for times beyond 2038 Avoid treating timestamps with the most significant bit set as negative. The mongodb documentation describe the timetsamp portion of objectids as 'seconds since the unix epoch', so this seems to be the correct behaviour, although I cannot find a formal specification for it.however this is technically a breaking change if people were relying on timestamp values before 1970. * use readUInt32BE instead of bit twiddling * remove comment that no longer applies * add test case --- lib/objectid.js | 2 +- test/node/object_id_tests.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/objectid.js b/lib/objectid.js index 089c8918..874adc3a 100644 --- a/lib/objectid.js +++ b/lib/objectid.js @@ -249,7 +249,7 @@ class ObjectId { */ getTimestamp() { const timestamp = new Date(); - const time = this.id[3] | (this.id[2] << 8) | (this.id[1] << 16) | (this.id[0] << 24); + const time = this.id.readUInt32BE(0); timestamp.setTime(Math.floor(time) * 1000); return timestamp; } diff --git a/test/node/object_id_tests.js b/test/node/object_id_tests.js index 15a7dd8d..ba2a8144 100644 --- a/test/node/object_id_tests.js +++ b/test/node/object_id_tests.js @@ -99,4 +99,9 @@ describe('ObjectId', function() { expect(() => new ObjectId('abcdefghijkl').toHexString()).to.not.throw(); expect(() => new ObjectId('abcdefŽhijkl').toHexString()).to.throw(TypeError); }); + + it('should correctly interpret timestamps beyond 2038', function() { + var farFuture = new Date('2040-01-01T00:00:00.000Z').getTime(); + expect(new BSON.ObjectId(BSON.ObjectId.generate(farFuture/1000)).getTimestamp().getTime()).to.equal(farFuture); + }); });