Skip to content

Commit 88ecf60

Browse files
committed
fix(date-time-converter): handle timestamp in microseconds
Fix CorentinTh#783
1 parent a07806c commit 88ecf60

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/tools/date-time-converter/date-time-converter.models.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, expect, test } from 'vitest';
22
import {
33
dateToExcelFormat,
44
excelFormatToDate,
5+
fromTimestamp,
56
isExcelFormat,
67
isISO8601DateTimeString,
78
isISO9075DateString,
@@ -113,6 +114,46 @@ describe('date-time-converter models', () => {
113114
expect(isTimestamp('foo')).toBe(false);
114115
expect(isTimestamp('')).toBe(false);
115116
});
117+
118+
test('should return true for valid Unix timestamps in microseconds', () => {
119+
expect(isTimestamp('1701227351995845')).toBe(true);
120+
});
121+
122+
test('should return false for invalid Unix timestamps in microseconds', () => {
123+
expect(isTimestamp('170122735199584')).toBe(false);
124+
expect(isTimestamp('17012273519958')).toBe(false);
125+
});
126+
});
127+
128+
describe('isTimestampMicroSeconds', () => {
129+
test('should return true for valid Unix timestamps in microseconds', () => {
130+
expect(isTimestamp('1649792026123123')).toBe(true);
131+
expect(isTimestamp('1701227351995845')).toBe(true);
132+
expect(isTimestamp('0')).toBe(true);
133+
});
134+
135+
test('should return false for invalid Unix timestamps in microseconds', () => {
136+
expect(isTimestamp('foo')).toBe(false);
137+
expect(isTimestamp('')).toBe(false);
138+
});
139+
140+
test('should return false for invalid Unix timestamps not in microseconds', () => {
141+
expect(isTimestamp('170122735199584')).toBe(false);
142+
expect(isTimestamp('17012273519958')).toBe(false);
143+
});
144+
});
145+
146+
describe('fromTimestamp', () => {
147+
test('should return valid Date for valid Unix timestamps in microseconds', () => {
148+
expect(fromTimestamp('1649792026123123').toString()).toBe(new Date(1649792026123).toString());
149+
expect(fromTimestamp('1701227351995845').toString()).toBe(new Date(1701227351995).toString());
150+
expect(fromTimestamp('0').toString()).toBe(new Date(0).toString());
151+
});
152+
153+
test('should return Date(0) for invalid Unix timestamps not in microseconds', () => {
154+
expect(fromTimestamp('170122735199584').toString()).toBe(new Date(0).toString());
155+
expect(fromTimestamp('17012273519958').toString()).toBe(new Date(0).toString());
156+
});
116157
});
117158

118159
describe('isUTCDateString', () => {

src/tools/date-time-converter/date-time-converter.models.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import _ from 'lodash';
2+
import { addMilliseconds } from 'date-fns';
23

34
export {
45
isISO8601DateTimeString,
@@ -12,6 +13,8 @@ export {
1213
dateToExcelFormat,
1314
excelFormatToDate,
1415
isExcelFormat,
16+
fromTimestamp,
17+
isTimestampMicroSeconds,
1518
};
1619

1720
const ISO8601_REGEX
@@ -35,7 +38,9 @@ const isISO9075DateString = createRegexMatcher(ISO9075_REGEX);
3538
const isRFC3339DateString = createRegexMatcher(RFC3339_REGEX);
3639
const isRFC7231DateString = createRegexMatcher(RFC7231_REGEX);
3740
const isUnixTimestamp = createRegexMatcher(/^[0-9]{1,10}$/);
38-
const isTimestamp = createRegexMatcher(/^[0-9]{1,13}$/);
41+
const isTimestamp = createRegexMatcher(/^([0-9]{1,13}|[0-9]{16})$/);
42+
const isTimestampMilliSeconds = createRegexMatcher(/^[0-9]{1,13}$/);
43+
const isTimestampMicroSeconds = createRegexMatcher(/^[0-9]{16}$/);
3944
const isMongoObjectId = createRegexMatcher(/^[0-9a-fA-F]{24}$/);
4045

4146
const isExcelFormat = createRegexMatcher(EXCEL_FORMAT_REGEX);
@@ -60,3 +65,14 @@ function dateToExcelFormat(date: Date) {
6065
function excelFormatToDate(excelFormat: string | number) {
6166
return new Date((Number(excelFormat) - 25569) * 86400 * 1000);
6267
}
68+
69+
function fromTimestamp(timestamp: string, type: 'auto' | 'milliseconds' | 'microseconds' = 'auto') {
70+
let milliSeconds = 0;
71+
if (type === 'microseconds' || isTimestampMicroSeconds(timestamp)) {
72+
milliSeconds = Number(timestamp) / 1000;
73+
}
74+
else if (type === 'milliseconds' || isTimestampMilliSeconds(timestamp)) {
75+
milliSeconds = Number(timestamp);
76+
}
77+
return addMilliseconds(new Date(0), milliSeconds);
78+
}

src/tools/date-time-converter/date-time-converter.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import {
1010
isDate,
1111
isValid,
1212
parseISO,
13-
parseJSON,
1413
} from 'date-fns';
1514
import type { DateFormat, ToDateMapper } from './date-time-converter.types';
1615
import {
1716
dateToExcelFormat,
1817
excelFormatToDate,
18+
fromTimestamp,
1919
isExcelFormat,
2020
isISO8601DateTimeString,
2121
isISO9075DateString,
@@ -73,7 +73,7 @@ const formats: DateFormat[] = [
7373
{
7474
name: 'Timestamp',
7575
fromDate: date => String(getTime(date)),
76-
toDate: ms => parseJSON(+ms),
76+
toDate: ms => fromTimestamp(ms),
7777
formatMatcher: date => isTimestamp(date),
7878
},
7979
{

0 commit comments

Comments
 (0)