Skip to content

Commit 6b2d8c8

Browse files
author
Brian Chen
authored
Merge 7ebc1a0 into 5ae7365
2 parents 5ae7365 + 7ebc1a0 commit 6b2d8c8

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

.changeset/rich-olives-tease.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/firestore': patch
3+
---
4+
5+
Fixed a bug where decimal inputs to `Timestamp.fromMillis()` calculated incorrectly due to floating point precision loss

packages/firestore/src/lite/timestamp.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import { primitiveComparator } from '../util/misc';
2121
// The earliest date supported by Firestore timestamps (0001-01-01T00:00:00Z).
2222
const MIN_SECONDS = -62135596800;
2323

24+
// Number of nanoseconds in a millisecond.
25+
const MS_TO_NANOS = 1e6;
26+
2427
/**
2528
* A `Timestamp` represents a point in time independent of any time zone or
2629
* calendar, represented as seconds and fractions of seconds at nanosecond
@@ -66,7 +69,7 @@ export class Timestamp {
6669
*/
6770
static fromMillis(milliseconds: number): Timestamp {
6871
const seconds = Math.floor(milliseconds / 1000);
69-
const nanos = (milliseconds - seconds * 1000) * 1e6;
72+
const nanos = Math.floor((milliseconds - seconds * 1000) * MS_TO_NANOS);
7073
return new Timestamp(seconds, nanos);
7174
}
7275

@@ -128,7 +131,7 @@ export class Timestamp {
128131
* the number of milliseconds since Unix epoch 1970-01-01T00:00:00Z.
129132
*/
130133
toMillis(): number {
131-
return this.seconds * 1000 + this.nanoseconds / 1e6;
134+
return this.seconds * 1000 + this.nanoseconds / MS_TO_NANOS;
132135
}
133136

134137
_compareTo(other: Timestamp): number {

packages/firestore/test/unit/api/timestamp.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ describe('Timestamp', () => {
134134
expect(t1 >= t2).to.be.false;
135135
});
136136

137+
it('handles decimal inputs in fromMillis()', () => {
138+
const actual = Timestamp.fromMillis(1000.1);
139+
const expected = new Timestamp(1, 100000);
140+
expect(actual.isEqual(expected)).to.be.true;
141+
});
142+
137143
it('serializes to JSON', () => {
138144
expect(new Timestamp(123, 456).toJSON()).to.deep.equal({
139145
seconds: 123,

0 commit comments

Comments
 (0)