fix(date-time-converter): add UTC ISO Display and JS Date Constructor
Fix #1198
This commit is contained in:
		
							parent
							
								
									88ecf60587
								
							
						
					
					
						commit
						6fd79d6e06
					
				| @ -35,6 +35,7 @@ | ||||
|     "release": "node ./scripts/release.mjs" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@date-fns/utc": "^1.2.0", | ||||
|     "@it-tools/bip39": "^0.0.4", | ||||
|     "@it-tools/oggen": "^1.3.0", | ||||
|     "@sindresorhus/slugify": "^2.2.1", | ||||
|  | ||||
							
								
								
									
										24
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										24
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @ -5,6 +5,9 @@ settings: | ||||
|   excludeLinksFromLockfile: false | ||||
| 
 | ||||
| dependencies: | ||||
|   '@date-fns/utc': | ||||
|     specifier: ^1.2.0 | ||||
|     version: 1.2.0 | ||||
|   '@it-tools/bip39': | ||||
|     specifier: ^0.0.4 | ||||
|     version: 0.0.4 | ||||
| @ -1905,6 +1908,10 @@ packages: | ||||
|       vue: 3.3.4 | ||||
|     dev: false | ||||
| 
 | ||||
|   /@date-fns/utc@1.2.0: | ||||
|     resolution: {integrity: sha512-YLq+crMPJiBmIdkRmv9nZuZy1mVtMlDcUKlg4mvI0UsC/dZeIaGoGB5p/C4FrpeOhZ7zBTK03T58S0DFkRNMnw==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@emotion/hash@0.8.0: | ||||
|     resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} | ||||
|     dev: false | ||||
| @ -3341,7 +3348,7 @@ packages: | ||||
|     dependencies: | ||||
|       '@unhead/dom': 0.5.1 | ||||
|       '@unhead/schema': 0.5.1 | ||||
|       '@vueuse/shared': 10.7.2(vue@3.3.4) | ||||
|       '@vueuse/shared': 11.0.3(vue@3.3.4) | ||||
|       unhead: 0.5.1 | ||||
|       vue: 3.3.4 | ||||
|     transitivePeerDependencies: | ||||
| @ -3983,10 +3990,10 @@ packages: | ||||
|       - vue | ||||
|     dev: false | ||||
| 
 | ||||
|   /@vueuse/shared@10.7.2(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} | ||||
|   /@vueuse/shared@11.0.3(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} | ||||
|     dependencies: | ||||
|       vue-demi: 0.14.6(vue@3.3.4) | ||||
|       vue-demi: 0.14.10(vue@3.3.4) | ||||
|     transitivePeerDependencies: | ||||
|       - '@vue/composition-api' | ||||
|       - vue | ||||
| @ -9120,8 +9127,8 @@ packages: | ||||
|       vue: 3.3.4 | ||||
|     dev: false | ||||
| 
 | ||||
|   /vue-demi@0.14.5(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} | ||||
|   /vue-demi@0.14.10(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} | ||||
|     engines: {node: '>=12'} | ||||
|     hasBin: true | ||||
|     requiresBuild: true | ||||
| @ -9135,8 +9142,8 @@ packages: | ||||
|       vue: 3.3.4 | ||||
|     dev: false | ||||
| 
 | ||||
|   /vue-demi@0.14.6(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} | ||||
|   /vue-demi@0.14.5(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} | ||||
|     engines: {node: '>=12'} | ||||
|     hasBin: true | ||||
|     requiresBuild: true | ||||
| @ -9426,6 +9433,7 @@ packages: | ||||
| 
 | ||||
|   /workbox-google-analytics@7.0.0: | ||||
|     resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} | ||||
|     deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained | ||||
|     dependencies: | ||||
|       workbox-background-sync: 7.0.0 | ||||
|       workbox-core: 7.0.0 | ||||
|  | ||||
| @ -2,16 +2,19 @@ import { describe, expect, test } from 'vitest'; | ||||
| import { | ||||
|   dateToExcelFormat, | ||||
|   excelFormatToDate, | ||||
|   fromJSDate, | ||||
|   fromTimestamp, | ||||
|   isExcelFormat, | ||||
|   isISO8601DateTimeString, | ||||
|   isISO9075DateString, | ||||
|   isJSDate, | ||||
|   isMongoObjectId, | ||||
|   isRFC3339DateString, | ||||
|   isRFC7231DateString, | ||||
|   isTimestamp, | ||||
|   isUTCDateString, | ||||
|   isUnixTimestamp, | ||||
|   toJSDate, | ||||
| } from './date-time-converter.models'; | ||||
| 
 | ||||
| describe('date-time-converter models', () => { | ||||
| @ -218,4 +221,36 @@ describe('date-time-converter models', () => { | ||||
|       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);'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @ -15,6 +15,9 @@ export { | ||||
|   isExcelFormat, | ||||
|   fromTimestamp, | ||||
|   isTimestampMicroSeconds, | ||||
|   isJSDate, | ||||
|   fromJSDate, | ||||
|   toJSDate, | ||||
| }; | ||||
| 
 | ||||
| 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}: | ||||
| 
 | ||||
| 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) { | ||||
|   return (date?: string) => !_.isNil(date) && regex.test(date); | ||||
| } | ||||
| @ -43,6 +48,14 @@ const isTimestampMilliSeconds = createRegexMatcher(/^[0-9]{1,13}$/); | ||||
| const isTimestampMicroSeconds = createRegexMatcher(/^[0-9]{16}$/); | ||||
| 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); | ||||
| 
 | ||||
| function isUTCDateString(date?: string) { | ||||
|  | ||||
| @ -11,20 +11,24 @@ import { | ||||
|   isValid, | ||||
|   parseISO, | ||||
| } from 'date-fns'; | ||||
| import { UTCDate } from '@date-fns/utc'; | ||||
| import type { DateFormat, ToDateMapper } from './date-time-converter.types'; | ||||
| import { | ||||
|   dateToExcelFormat, | ||||
|   excelFormatToDate, | ||||
|   fromJSDate, | ||||
|   fromTimestamp, | ||||
|   isExcelFormat, | ||||
|   isISO8601DateTimeString, | ||||
|   isISO9075DateString, | ||||
|   isJSDate, | ||||
|   isMongoObjectId, | ||||
|   isRFC3339DateString, | ||||
|   isRFC7231DateString, | ||||
|   isTimestamp, | ||||
|   isUTCDateString, | ||||
|   isUnixTimestamp, | ||||
|   toJSDate, | ||||
| } from './date-time-converter.models'; | ||||
| import { withDefaultOnError } from '@/utils/defaults'; | ||||
| import { useValidation } from '@/composable/validation'; | ||||
| @ -46,6 +50,12 @@ const formats: DateFormat[] = [ | ||||
|     toDate: parseISO, | ||||
|     formatMatcher: date => isISO8601DateTimeString(date), | ||||
|   }, | ||||
|   { | ||||
|     name: 'ISO 8601 UTC', | ||||
|     fromDate: date => (new UTCDate(date)).toISOString(), | ||||
|     toDate: parseISO, | ||||
|     formatMatcher: date => isISO8601DateTimeString(date), | ||||
|   }, | ||||
|   { | ||||
|     name: 'ISO 9075', | ||||
|     fromDate: formatISO9075, | ||||
| @ -94,6 +104,12 @@ const formats: DateFormat[] = [ | ||||
|     toDate: excelFormatToDate, | ||||
|     formatMatcher: isExcelFormat, | ||||
|   }, | ||||
|   { | ||||
|     name: 'JS Date', | ||||
|     fromDate: date => toJSDate(date), | ||||
|     toDate: date => fromJSDate(date), | ||||
|     formatMatcher: isJSDate, | ||||
|   }, | ||||
| ]; | ||||
| 
 | ||||
| const formatIndex = ref(6); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user