Skip to content

Commit 6fd79d6

Browse files
committed
fix(date-time-converter): add UTC ISO Display and JS Date Constructor
Fix CorentinTh#1198
1 parent 88ecf60 commit 6fd79d6

File tree

5 files changed

+81
-8
lines changed

5 files changed

+81
-8
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"release": "node ./scripts/release.mjs"
3636
},
3737
"dependencies": {
38+
"@date-fns/utc": "^1.2.0",
3839
"@it-tools/bip39": "^0.0.4",
3940
"@it-tools/oggen": "^1.3.0",
4041
"@sindresorhus/slugify": "^2.2.1",

pnpm-lock.yaml

Lines changed: 16 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ import { describe, expect, test } from 'vitest';
22
import {
33
dateToExcelFormat,
44
excelFormatToDate,
5+
fromJSDate,
56
fromTimestamp,
67
isExcelFormat,
78
isISO8601DateTimeString,
89
isISO9075DateString,
10+
isJSDate,
911
isMongoObjectId,
1012
isRFC3339DateString,
1113
isRFC7231DateString,
1214
isTimestamp,
1315
isUTCDateString,
1416
isUnixTimestamp,
17+
toJSDate,
1518
} from './date-time-converter.models';
1619

1720
describe('date-time-converter models', () => {
@@ -218,4 +221,36 @@ describe('date-time-converter models', () => {
218221
expect(excelFormatToDate('-1000')).toEqual(new Date('1897-04-04T00:00:00.000Z'));
219222
});
220223
});
224+
225+
describe('isJSDate', () => {
226+
test('a JS date is a new Date()', () => {
227+
expect(isJSDate('new Date(2000, 0)')).toBe(true);
228+
expect(isJSDate('new Date(2000, 0, 1, 12, 12)')).toBe(true);
229+
expect(isJSDate('new Date(2000, 0, 1, 12, 12, 12)')).toBe(true);
230+
expect(isJSDate('new Date(2000, 0, 1, 12, 12, 12, 1)')).toBe(true);
231+
232+
expect(isJSDate('new Date(2000)')).toBe(false);
233+
expect(isJSDate('')).toBe(false);
234+
expect(isJSDate('foo')).toBe(false);
235+
expect(isJSDate('1.1.1')).toBe(false);
236+
});
237+
});
238+
239+
describe('fromJSDate', () => {
240+
test('convert a JS new Date() to date', () => {
241+
expect(fromJSDate('new Date(2000, 0)')).toEqual(new Date(2000, 0));
242+
expect(fromJSDate('new Date(2000, 0, 1, 12, 12)')).toEqual(new Date(2000, 0, 1, 12, 12));
243+
expect(fromJSDate('new Date(2000, 0, 1, 12, 12, 12)')).toEqual(new Date(2000, 0, 1, 12, 12, 12));
244+
expect(fromJSDate('new Date(2000, 0, 1, 12, 12, 12, 1)')).toEqual(new Date(2000, 0, 1, 12, 12, 12, 1));
245+
});
246+
});
247+
248+
describe('toJSDate', () => {
249+
test('convert a date to JS new Date()', () => {
250+
expect(toJSDate(new Date(2000, 0))).toEqual('new Date(2000, 0, 1, 0, 0, 0, 0);');
251+
expect(toJSDate(new Date(2000, 0, 1, 12, 12))).toEqual('new Date(2000, 0, 1, 12, 12, 0, 0);');
252+
expect(toJSDate(new Date(2000, 0, 1, 12, 12, 12))).toEqual('new Date(2000, 0, 1, 12, 12, 12, 0);');
253+
expect(toJSDate(new Date(2000, 0, 1, 12, 12, 12, 1))).toEqual('new Date(2000, 0, 1, 12, 12, 12, 1);');
254+
});
255+
});
221256
});

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export {
1515
isExcelFormat,
1616
fromTimestamp,
1717
isTimestampMicroSeconds,
18+
isJSDate,
19+
fromJSDate,
20+
toJSDate,
1821
};
1922

2023
const ISO8601_REGEX
@@ -29,6 +32,8 @@ const RFC7231_REGEX = /^[A-Za-z]{3},\s[0-9]{2}\s[A-Za-z]{3}\s[0-9]{4}\s[0-9]{2}:
2932

3033
const EXCEL_FORMAT_REGEX = /^-?\d+(\.\d+)?$/;
3134

35+
const JS_DATE_REGEX = /^new\s+Date\(\s*(?:(\d+)\s*,\s*)(?:(\d|11)\s*,\s*(?:(\d+)\s*,\s*(?:(\d+)\s*,\s*(?:(\d+)\s*,\s*(?:(\d+)\s*,\s*)?)?)?)?)?(\d+)\)\s*;?$/;
36+
3237
function createRegexMatcher(regex: RegExp) {
3338
return (date?: string) => !_.isNil(date) && regex.test(date);
3439
}
@@ -43,6 +48,14 @@ const isTimestampMilliSeconds = createRegexMatcher(/^[0-9]{1,13}$/);
4348
const isTimestampMicroSeconds = createRegexMatcher(/^[0-9]{16}$/);
4449
const isMongoObjectId = createRegexMatcher(/^[0-9a-fA-F]{24}$/);
4550

51+
const isJSDate = createRegexMatcher(JS_DATE_REGEX);
52+
function fromJSDate(date: string): Date {
53+
const res = JS_DATE_REGEX.exec(date);
54+
const parts = (res || []).filter(p => p !== undefined).map(p => Number.parseInt(p, 10)).slice(1);
55+
return new (Function.prototype.bind.apply(Date, [null, ...parts]))();
56+
}
57+
const toJSDate = (date: Date) => `new Date(${date.getFullYear()}, ${date.getMonth()}, ${date.getDate()}, ${date.getHours()}, ${date.getMinutes()}, ${date.getSeconds()}, ${date.getMilliseconds()});`;
58+
4659
const isExcelFormat = createRegexMatcher(EXCEL_FORMAT_REGEX);
4760

4861
function isUTCDateString(date?: string) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@ import {
1111
isValid,
1212
parseISO,
1313
} from 'date-fns';
14+
import { UTCDate } from '@date-fns/utc';
1415
import type { DateFormat, ToDateMapper } from './date-time-converter.types';
1516
import {
1617
dateToExcelFormat,
1718
excelFormatToDate,
19+
fromJSDate,
1820
fromTimestamp,
1921
isExcelFormat,
2022
isISO8601DateTimeString,
2123
isISO9075DateString,
24+
isJSDate,
2225
isMongoObjectId,
2326
isRFC3339DateString,
2427
isRFC7231DateString,
2528
isTimestamp,
2629
isUTCDateString,
2730
isUnixTimestamp,
31+
toJSDate,
2832
} from './date-time-converter.models';
2933
import { withDefaultOnError } from '@/utils/defaults';
3034
import { useValidation } from '@/composable/validation';
@@ -46,6 +50,12 @@ const formats: DateFormat[] = [
4650
toDate: parseISO,
4751
formatMatcher: date => isISO8601DateTimeString(date),
4852
},
53+
{
54+
name: 'ISO 8601 UTC',
55+
fromDate: date => (new UTCDate(date)).toISOString(),
56+
toDate: parseISO,
57+
formatMatcher: date => isISO8601DateTimeString(date),
58+
},
4959
{
5060
name: 'ISO 9075',
5161
fromDate: formatISO9075,
@@ -94,6 +104,12 @@ const formats: DateFormat[] = [
94104
toDate: excelFormatToDate,
95105
formatMatcher: isExcelFormat,
96106
},
107+
{
108+
name: 'JS Date',
109+
fromDate: date => toJSDate(date),
110+
toDate: date => fromJSDate(date),
111+
formatMatcher: isJSDate,
112+
},
97113
];
98114
99115
const formatIndex = ref(6);

0 commit comments

Comments
 (0)