mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 05:19:12 -04:00
Merge 3ef7e50b5b
into b47d132839
This commit is contained in:
commit
e31aae4408
6 changed files with 134 additions and 4 deletions
|
@ -36,6 +36,7 @@
|
||||||
"release": "node ./scripts/release.mjs"
|
"release": "node ./scripts/release.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@date-fns/utc": "^1.2.0",
|
||||||
"@it-tools/bip39": "^0.0.4",
|
"@it-tools/bip39": "^0.0.4",
|
||||||
"@it-tools/oggen": "^1.3.0",
|
"@it-tools/oggen": "^1.3.0",
|
||||||
"@regexper/render": "^1.0.0",
|
"@regexper/render": "^1.0.0",
|
||||||
|
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
|
@ -5,6 +5,9 @@ settings:
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@date-fns/utc':
|
||||||
|
specifier: ^1.2.0
|
||||||
|
version: 1.2.0
|
||||||
'@it-tools/bip39':
|
'@it-tools/bip39':
|
||||||
specifier: ^0.0.4
|
specifier: ^0.0.4
|
||||||
version: 0.0.4
|
version: 0.0.4
|
||||||
|
@ -1941,6 +1944,10 @@ packages:
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@date-fns/utc@1.2.0:
|
||||||
|
resolution: {integrity: sha512-YLq+crMPJiBmIdkRmv9nZuZy1mVtMlDcUKlg4mvI0UsC/dZeIaGoGB5p/C4FrpeOhZ7zBTK03T58S0DFkRNMnw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@emotion/hash@0.8.0:
|
/@emotion/hash@0.8.0:
|
||||||
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
|
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
|
@ -11,7 +11,7 @@ test.describe('Date time converter - json to yaml', () => {
|
||||||
|
|
||||||
test('Format is auto detected from a date and the date is correctly converted', async ({ page }) => {
|
test('Format is auto detected from a date and the date is correctly converted', async ({ page }) => {
|
||||||
const initialFormat = await page.getByTestId('date-time-converter-format-select').innerText();
|
const initialFormat = await page.getByTestId('date-time-converter-format-select').innerText();
|
||||||
expect(initialFormat.trim()).toEqual('Timestamp');
|
expect(initialFormat.trim()).toEqual('Unix timestamp');
|
||||||
|
|
||||||
await page.getByTestId('date-time-converter-input').fill('2023-04-12T23:10:24+02:00');
|
await page.getByTestId('date-time-converter-input').fill('2023-04-12T23:10:24+02:00');
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ test.describe('Date time converter - json to yaml', () => {
|
||||||
'Wed Apr 12 2023 23:10:24 GMT+0200 (Central European Summer Time)',
|
'Wed Apr 12 2023 23:10:24 GMT+0200 (Central European Summer Time)',
|
||||||
);
|
);
|
||||||
expect((await page.getByTestId('ISO 8601').inputValue()).trim()).toEqual('2023-04-12T23:10:24+02:00');
|
expect((await page.getByTestId('ISO 8601').inputValue()).trim()).toEqual('2023-04-12T23:10:24+02:00');
|
||||||
|
expect((await page.getByTestId('ISO 8601 UTC').inputValue()).trim()).toEqual('2023-04-12T21:10:24.000Z');
|
||||||
expect((await page.getByTestId('ISO 9075').inputValue()).trim()).toEqual('2023-04-12 23:10:24');
|
expect((await page.getByTestId('ISO 9075').inputValue()).trim()).toEqual('2023-04-12 23:10:24');
|
||||||
expect((await page.getByTestId('Unix timestamp').inputValue()).trim()).toEqual('1681333824');
|
expect((await page.getByTestId('Unix timestamp').inputValue()).trim()).toEqual('1681333824');
|
||||||
expect((await page.getByTestId('RFC 7231').inputValue()).trim()).toEqual('Wed, 12 Apr 2023 21:10:24 GMT');
|
expect((await page.getByTestId('RFC 7231').inputValue()).trim()).toEqual('Wed, 12 Apr 2023 21:10:24 GMT');
|
||||||
|
|
|
@ -2,15 +2,20 @@ import { describe, expect, test } from 'vitest';
|
||||||
import {
|
import {
|
||||||
dateToExcelFormat,
|
dateToExcelFormat,
|
||||||
excelFormatToDate,
|
excelFormatToDate,
|
||||||
|
fromJSDate,
|
||||||
|
fromTimestamp,
|
||||||
isExcelFormat,
|
isExcelFormat,
|
||||||
isISO8601DateTimeString,
|
isISO8601DateTimeString,
|
||||||
isISO9075DateString,
|
isISO9075DateString,
|
||||||
|
isJSDate,
|
||||||
isMongoObjectId,
|
isMongoObjectId,
|
||||||
isRFC3339DateString,
|
isRFC3339DateString,
|
||||||
isRFC7231DateString,
|
isRFC7231DateString,
|
||||||
isTimestamp,
|
isTimestamp,
|
||||||
|
isTimestampMicroSeconds,
|
||||||
isUTCDateString,
|
isUTCDateString,
|
||||||
isUnixTimestamp,
|
isUnixTimestamp,
|
||||||
|
toJSDate,
|
||||||
} from './date-time-converter.models';
|
} from './date-time-converter.models';
|
||||||
|
|
||||||
describe('date-time-converter models', () => {
|
describe('date-time-converter models', () => {
|
||||||
|
@ -113,6 +118,45 @@ describe('date-time-converter models', () => {
|
||||||
expect(isTimestamp('foo')).toBe(false);
|
expect(isTimestamp('foo')).toBe(false);
|
||||||
expect(isTimestamp('')).toBe(false);
|
expect(isTimestamp('')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should return true for valid Unix timestamps in microseconds', () => {
|
||||||
|
expect(isTimestamp('1701227351995845')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid Unix timestamps in microseconds', () => {
|
||||||
|
expect(isTimestamp('170122735199584')).toBe(false);
|
||||||
|
expect(isTimestamp('17012273519958')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isTimestampMicroSeconds', () => {
|
||||||
|
test('should return true for valid Unix timestamps in microseconds', () => {
|
||||||
|
expect(isTimestampMicroSeconds('1649792026123123')).toBe(true);
|
||||||
|
expect(isTimestampMicroSeconds('1701227351995845')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid Unix timestamps in microseconds', () => {
|
||||||
|
expect(isTimestampMicroSeconds('foo')).toBe(false);
|
||||||
|
expect(isTimestampMicroSeconds('')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid Unix timestamps not in microseconds', () => {
|
||||||
|
expect(isTimestampMicroSeconds('170122735199584')).toBe(false);
|
||||||
|
expect(isTimestampMicroSeconds('17012273519958')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fromTimestamp', () => {
|
||||||
|
test('should return valid Date for valid Unix timestamps in microseconds', () => {
|
||||||
|
expect(fromTimestamp('1649792026123123').toString()).toBe(new Date(1649792026123).toString());
|
||||||
|
expect(fromTimestamp('1701227351995845').toString()).toBe(new Date(1701227351995).toString());
|
||||||
|
expect(fromTimestamp('0').toString()).toBe(new Date(0).toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return Date(0) for invalid Unix timestamps not in microseconds', () => {
|
||||||
|
expect(fromTimestamp('170122735199584').toString()).toBe(new Date(0).toString());
|
||||||
|
expect(fromTimestamp('17012273519958').toString()).toBe(new Date(0).toString());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isUTCDateString', () => {
|
describe('isUTCDateString', () => {
|
||||||
|
@ -177,4 +221,36 @@ describe('date-time-converter models', () => {
|
||||||
expect(excelFormatToDate('-1000')).toEqual(new Date('1897-04-04T00:00:00.000Z'));
|
expect(excelFormatToDate('-1000')).toEqual(new Date('1897-04-04T00:00:00.000Z'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isJSDate', () => {
|
||||||
|
test('a JS date is a new Date()', () => {
|
||||||
|
expect(isJSDate('new Date(2000, 0)')).toBe(true);
|
||||||
|
expect(isJSDate('new Date(2000, 0, 1, 12, 12)')).toBe(true);
|
||||||
|
expect(isJSDate('new Date(2000, 0, 1, 12, 12, 12)')).toBe(true);
|
||||||
|
expect(isJSDate('new Date(2000, 0, 1, 12, 12, 12, 1)')).toBe(true);
|
||||||
|
|
||||||
|
expect(isJSDate('new Date(2000)')).toBe(false);
|
||||||
|
expect(isJSDate('')).toBe(false);
|
||||||
|
expect(isJSDate('foo')).toBe(false);
|
||||||
|
expect(isJSDate('1.1.1')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fromJSDate', () => {
|
||||||
|
test('convert a JS new Date() to date', () => {
|
||||||
|
expect(fromJSDate('new Date(2000, 0)')).toEqual(new Date(2000, 0));
|
||||||
|
expect(fromJSDate('new Date(2000, 0, 1, 12, 12)')).toEqual(new Date(2000, 0, 1, 12, 12));
|
||||||
|
expect(fromJSDate('new Date(2000, 0, 1, 12, 12, 12)')).toEqual(new Date(2000, 0, 1, 12, 12, 12));
|
||||||
|
expect(fromJSDate('new Date(2000, 0, 1, 12, 12, 12, 1)')).toEqual(new Date(2000, 0, 1, 12, 12, 12, 1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toJSDate', () => {
|
||||||
|
test('convert a date to JS new Date()', () => {
|
||||||
|
expect(toJSDate(new Date(2000, 0))).toEqual('new Date(2000, 0, 1, 0, 0, 0, 0);');
|
||||||
|
expect(toJSDate(new Date(2000, 0, 1, 12, 12))).toEqual('new Date(2000, 0, 1, 12, 12, 0, 0);');
|
||||||
|
expect(toJSDate(new Date(2000, 0, 1, 12, 12, 12))).toEqual('new Date(2000, 0, 1, 12, 12, 12, 0);');
|
||||||
|
expect(toJSDate(new Date(2000, 0, 1, 12, 12, 12, 1))).toEqual('new Date(2000, 0, 1, 12, 12, 12, 1);');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { addMilliseconds } from 'date-fns';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isISO8601DateTimeString,
|
isISO8601DateTimeString,
|
||||||
|
@ -12,6 +13,11 @@ export {
|
||||||
dateToExcelFormat,
|
dateToExcelFormat,
|
||||||
excelFormatToDate,
|
excelFormatToDate,
|
||||||
isExcelFormat,
|
isExcelFormat,
|
||||||
|
fromTimestamp,
|
||||||
|
isTimestampMicroSeconds,
|
||||||
|
isJSDate,
|
||||||
|
fromJSDate,
|
||||||
|
toJSDate,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ISO8601_REGEX
|
const ISO8601_REGEX
|
||||||
|
@ -26,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}:
|
||||||
|
|
||||||
const EXCEL_FORMAT_REGEX = /^-?\d+(\.\d+)?$/;
|
const EXCEL_FORMAT_REGEX = /^-?\d+(\.\d+)?$/;
|
||||||
|
|
||||||
|
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*;?$/;
|
||||||
|
|
||||||
function createRegexMatcher(regex: RegExp) {
|
function createRegexMatcher(regex: RegExp) {
|
||||||
return (date?: string) => !_.isNil(date) && regex.test(date);
|
return (date?: string) => !_.isNil(date) && regex.test(date);
|
||||||
}
|
}
|
||||||
|
@ -35,9 +43,19 @@ const isISO9075DateString = createRegexMatcher(ISO9075_REGEX);
|
||||||
const isRFC3339DateString = createRegexMatcher(RFC3339_REGEX);
|
const isRFC3339DateString = createRegexMatcher(RFC3339_REGEX);
|
||||||
const isRFC7231DateString = createRegexMatcher(RFC7231_REGEX);
|
const isRFC7231DateString = createRegexMatcher(RFC7231_REGEX);
|
||||||
const isUnixTimestamp = createRegexMatcher(/^[0-9]{1,10}$/);
|
const isUnixTimestamp = createRegexMatcher(/^[0-9]{1,10}$/);
|
||||||
const isTimestamp = createRegexMatcher(/^[0-9]{1,13}$/);
|
const isTimestamp = createRegexMatcher(/^([0-9]{1,13}|[0-9]{16})$/);
|
||||||
|
const isTimestampMilliSeconds = createRegexMatcher(/^[0-9]{1,13}$/);
|
||||||
|
const isTimestampMicroSeconds = createRegexMatcher(/^[0-9]{16}$/);
|
||||||
const isMongoObjectId = createRegexMatcher(/^[0-9a-fA-F]{24}$/);
|
const isMongoObjectId = createRegexMatcher(/^[0-9a-fA-F]{24}$/);
|
||||||
|
|
||||||
|
const isJSDate = createRegexMatcher(JS_DATE_REGEX);
|
||||||
|
function fromJSDate(date: string): Date {
|
||||||
|
const res = JS_DATE_REGEX.exec(date);
|
||||||
|
const parts = (res || []).filter(p => p !== undefined).map(p => Number.parseInt(p, 10)).slice(1);
|
||||||
|
return new (Function.prototype.bind.apply(Date, [null, ...parts]))();
|
||||||
|
}
|
||||||
|
const toJSDate = (date: Date) => `new Date(${date.getFullYear()}, ${date.getMonth()}, ${date.getDate()}, ${date.getHours()}, ${date.getMinutes()}, ${date.getSeconds()}, ${date.getMilliseconds()});`;
|
||||||
|
|
||||||
const isExcelFormat = createRegexMatcher(EXCEL_FORMAT_REGEX);
|
const isExcelFormat = createRegexMatcher(EXCEL_FORMAT_REGEX);
|
||||||
|
|
||||||
function isUTCDateString(date?: string) {
|
function isUTCDateString(date?: string) {
|
||||||
|
@ -60,3 +78,14 @@ function dateToExcelFormat(date: Date) {
|
||||||
function excelFormatToDate(excelFormat: string | number) {
|
function excelFormatToDate(excelFormat: string | number) {
|
||||||
return new Date((Number(excelFormat) - 25569) * 86400 * 1000);
|
return new Date((Number(excelFormat) - 25569) * 86400 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fromTimestamp(timestamp: string, type: 'auto' | 'milliseconds' | 'microseconds' = 'auto') {
|
||||||
|
let milliSeconds = 0;
|
||||||
|
if (type === 'microseconds' || isTimestampMicroSeconds(timestamp)) {
|
||||||
|
milliSeconds = Number(timestamp) / 1000;
|
||||||
|
}
|
||||||
|
else if (type === 'milliseconds' || isTimestampMilliSeconds(timestamp)) {
|
||||||
|
milliSeconds = Number(timestamp);
|
||||||
|
}
|
||||||
|
return addMilliseconds(new Date(0), milliSeconds);
|
||||||
|
}
|
||||||
|
|
|
@ -10,21 +10,25 @@ import {
|
||||||
isDate,
|
isDate,
|
||||||
isValid,
|
isValid,
|
||||||
parseISO,
|
parseISO,
|
||||||
parseJSON,
|
|
||||||
} from 'date-fns';
|
} from 'date-fns';
|
||||||
|
import { UTCDate } from '@date-fns/utc';
|
||||||
import type { DateFormat, ToDateMapper } from './date-time-converter.types';
|
import type { DateFormat, ToDateMapper } from './date-time-converter.types';
|
||||||
import {
|
import {
|
||||||
dateToExcelFormat,
|
dateToExcelFormat,
|
||||||
excelFormatToDate,
|
excelFormatToDate,
|
||||||
|
fromJSDate,
|
||||||
|
fromTimestamp,
|
||||||
isExcelFormat,
|
isExcelFormat,
|
||||||
isISO8601DateTimeString,
|
isISO8601DateTimeString,
|
||||||
isISO9075DateString,
|
isISO9075DateString,
|
||||||
|
isJSDate,
|
||||||
isMongoObjectId,
|
isMongoObjectId,
|
||||||
isRFC3339DateString,
|
isRFC3339DateString,
|
||||||
isRFC7231DateString,
|
isRFC7231DateString,
|
||||||
isTimestamp,
|
isTimestamp,
|
||||||
isUTCDateString,
|
isUTCDateString,
|
||||||
isUnixTimestamp,
|
isUnixTimestamp,
|
||||||
|
toJSDate,
|
||||||
} from './date-time-converter.models';
|
} from './date-time-converter.models';
|
||||||
import { withDefaultOnError } from '@/utils/defaults';
|
import { withDefaultOnError } from '@/utils/defaults';
|
||||||
import { useValidation } from '@/composable/validation';
|
import { useValidation } from '@/composable/validation';
|
||||||
|
@ -46,6 +50,12 @@ const formats: DateFormat[] = [
|
||||||
toDate: parseISO,
|
toDate: parseISO,
|
||||||
formatMatcher: date => isISO8601DateTimeString(date),
|
formatMatcher: date => isISO8601DateTimeString(date),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'ISO 8601 UTC',
|
||||||
|
fromDate: date => (new UTCDate(date)).toISOString(),
|
||||||
|
toDate: parseISO,
|
||||||
|
formatMatcher: date => isISO8601DateTimeString(date),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'ISO 9075',
|
name: 'ISO 9075',
|
||||||
fromDate: formatISO9075,
|
fromDate: formatISO9075,
|
||||||
|
@ -73,7 +83,7 @@ const formats: DateFormat[] = [
|
||||||
{
|
{
|
||||||
name: 'Timestamp',
|
name: 'Timestamp',
|
||||||
fromDate: date => String(getTime(date)),
|
fromDate: date => String(getTime(date)),
|
||||||
toDate: ms => parseJSON(+ms),
|
toDate: ms => fromTimestamp(ms),
|
||||||
formatMatcher: date => isTimestamp(date),
|
formatMatcher: date => isTimestamp(date),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -94,6 +104,12 @@ const formats: DateFormat[] = [
|
||||||
toDate: excelFormatToDate,
|
toDate: excelFormatToDate,
|
||||||
formatMatcher: isExcelFormat,
|
formatMatcher: isExcelFormat,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'JS Date',
|
||||||
|
fromDate: date => toJSDate(date),
|
||||||
|
toDate: date => fromJSDate(date),
|
||||||
|
formatMatcher: isJSDate,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const formatIndex = ref(6);
|
const formatIndex = ref(6);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue