diff --git a/projects/kit/src/index.ts b/projects/kit/src/index.ts index 03a666ae8..8bace04e9 100644 --- a/projects/kit/src/index.ts +++ b/projects/kit/src/index.ts @@ -2,7 +2,11 @@ export {maskitoDateOptionsGenerator} from './lib/masks/date'; export {maskitoDateRangeOptionsGenerator} from './lib/masks/date-range'; export {maskitoDateTimeOptionsGenerator} from './lib/masks/date-time'; export {maskitoNumberOptionsGenerator, maskitoParseNumber} from './lib/masks/number'; -export {MaskitoTimeOptions, maskitoTimeOptionsGenerator} from './lib/masks/time'; +export { + maskitoParseTime, + MaskitoTimeOptions, + maskitoTimeOptionsGenerator, +} from './lib/masks/time'; export { maskitoAddOnFocusPlugin, maskitoCaretGuard, diff --git a/projects/kit/src/lib/masks/time/index.ts b/projects/kit/src/lib/masks/time/index.ts index 0f02535e6..0f58eaa5c 100644 --- a/projects/kit/src/lib/masks/time/index.ts +++ b/projects/kit/src/lib/masks/time/index.ts @@ -1,2 +1,3 @@ export {maskitoTimeOptionsGenerator} from './time-mask'; export {MaskitoTimeOptions} from './time-options'; +export {maskitoParseTime} from './utils'; diff --git a/projects/kit/src/lib/masks/time/utils/index.ts b/projects/kit/src/lib/masks/time/utils/index.ts new file mode 100644 index 000000000..5f953b5cb --- /dev/null +++ b/projects/kit/src/lib/masks/time/utils/index.ts @@ -0,0 +1 @@ +export * from './parse-time'; diff --git a/projects/kit/src/lib/masks/time/utils/parse-time.ts b/projects/kit/src/lib/masks/time/utils/parse-time.ts new file mode 100644 index 000000000..2ed46317e --- /dev/null +++ b/projects/kit/src/lib/masks/time/utils/parse-time.ts @@ -0,0 +1,33 @@ +import {DEFAULT_TIME_SEGMENT_MAX_VALUES} from '../../../constants'; +import type {MaskitoTimeSegments} from '../../../types'; +import {padTimeSegments, parseTimeString} from '../../../utils/time'; +import type {MaskitoTimeOptions} from '../time-options'; + +/** + * Converts a formatted time string to milliseconds based on the given `options.mode`. + * + * @param maskedTime a formatted time string by {@link maskitoTimeOptionsGenerator} or {@link maskitoStringifyTime} + * @param options + */ +export function maskitoParseTime( + maskedTime: string, + {mode, timeSegmentMaxValues = {}}: MaskitoTimeOptions, +): number { + const maxValues: MaskitoTimeSegments = { + ...DEFAULT_TIME_SEGMENT_MAX_VALUES, + ...timeSegmentMaxValues, + }; + + const msInSecond = maxValues.milliseconds + 1; + const msInMinute = (maxValues.seconds + 1) * msInSecond; + const msInHour = (maxValues.minutes + 1) * msInMinute; + + const parsedTime = padTimeSegments(parseTimeString(maskedTime, mode)); + + return ( + Number(parsedTime.hours ?? '') * msInHour + + Number(parsedTime.minutes ?? '') * msInMinute + + Number(parsedTime.seconds ?? '') * msInSecond + + Number(parsedTime.milliseconds ?? '') + ); +} diff --git a/projects/kit/src/lib/masks/time/utils/tests/parse-time.spec.ts b/projects/kit/src/lib/masks/time/utils/tests/parse-time.spec.ts new file mode 100644 index 000000000..92ebca2d6 --- /dev/null +++ b/projects/kit/src/lib/masks/time/utils/tests/parse-time.spec.ts @@ -0,0 +1,125 @@ +import {describe, expect, it} from '@jest/globals'; +import type {MaskitoTimeMode, MaskitoTimeOptions} from '@maskito/kit'; +import {maskitoParseTime} from '@maskito/kit'; + +const options: MaskitoTimeOptions = {mode: 'HH:MM:SS.MSS'}; + +describe('maskitoParseTime', () => { + const testCases: Record> = { + 'HH:MM:SS.MSS': [ + {ms: 0, text: ''}, + {ms: 0, text: '00:00:00.000'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + {ms: 43200000, text: '12:'}, + {ms: 45000000, text: '12:3'}, + {ms: 45000000, text: '12:30'}, + {ms: 45240000, text: '12:34'}, + {ms: 45240000, text: '12:34:'}, + {ms: 45290000, text: '12:34:5'}, + {ms: 45290000, text: '12:34:50'}, + {ms: 45296000, text: '12:34:56'}, + {ms: 45296000, text: '12:34:56.'}, + {ms: 45296700, text: '12:34:56.7'}, + {ms: 45296700, text: '12:34:56.70'}, + {ms: 45296700, text: '12:34:56.700'}, + {ms: 45296780, text: '12:34:56.78'}, + {ms: 45296780, text: '12:34:56.780'}, + {ms: 45296789, text: '12:34:56.789'}, + + {ms: 86399999, text: '23:59:59.999'}, + ], + 'HH:MM:SS': [ + {ms: 0, text: ''}, + {ms: 0, text: '00:00:00'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + {ms: 43200000, text: '12:'}, + {ms: 45000000, text: '12:3'}, + {ms: 45000000, text: '12:30'}, + {ms: 45240000, text: '12:34'}, + {ms: 45240000, text: '12:34:'}, + {ms: 45290000, text: '12:34:5'}, + {ms: 45290000, text: '12:34:50'}, + {ms: 45296000, text: '12:34:56'}, + + {ms: 86399000, text: '23:59:59'}, + ], + 'HH:MM': [ + {ms: 0, text: ''}, + {ms: 0, text: '00:00'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + {ms: 43200000, text: '12:'}, + {ms: 45000000, text: '12:3'}, + {ms: 45000000, text: '12:30'}, + {ms: 45240000, text: '12:34'}, + + {ms: 86340000, text: '23:59'}, + ], + HH: [ + {ms: 0, text: ''}, + {ms: 0, text: '00'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + + {ms: 82800000, text: '23'}, + ], + 'MM.SS.MSS': [ + {ms: 0, text: ''}, + {ms: 0, text: '00:00.000'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + {ms: 43200000, text: '12:'}, + {ms: 45000000, text: '12:3'}, + {ms: 45000000, text: '12:30'}, + {ms: 45240000, text: '12:34'}, + {ms: 45240000, text: '12:34.'}, + {ms: 45290000, text: '12:34.5'}, + {ms: 45290000, text: '12:34.50'}, + {ms: 45290000, text: '12:34.500'}, + {ms: 45296000, text: '12:34.56'}, + {ms: 45296000, text: '12:34.560'}, + {ms: 45296700, text: '12:34.567'}, + + {ms: 216039900, text: '59:59.999'}, + ], + 'SS.MSS': [ + {ms: 0, text: ''}, + {ms: 0, text: '00.000'}, + + {ms: 36000000, text: '1'}, + {ms: 36000000, text: '10'}, + {ms: 43200000, text: '12'}, + {ms: 43200000, text: '12.'}, + {ms: 45000000, text: '12.3'}, + {ms: 45000000, text: '12.30'}, + {ms: 45000000, text: '12.300'}, + {ms: 45240000, text: '12.34'}, + {ms: 45240000, text: '12.340'}, + {ms: 45290000, text: '12.345'}, + + {ms: 218430000, text: '59.999'}, + ], + }; + + Object.entries(testCases).forEach(([mode, cases]) => { + describe(`mode ${mode}`, () => { + cases.forEach(({text, ms}) => { + it(`'${text}' => ${ms}ms`, () => { + expect(maskitoParseTime(text, options)).toBe(ms); + }); + }); + }); + }); +});