From 19e6e698f8169caaff1bbd9f9caaa7520b3829f0 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Mon, 11 Jul 2022 13:31:13 +0800 Subject: [PATCH] refactor(gui-v2): add duration helper --- packages/nc-gui-v2/utils/durationHelper.ts | 193 +++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 packages/nc-gui-v2/utils/durationHelper.ts diff --git a/packages/nc-gui-v2/utils/durationHelper.ts b/packages/nc-gui-v2/utils/durationHelper.ts new file mode 100644 index 0000000000..17983c644a --- /dev/null +++ b/packages/nc-gui-v2/utils/durationHelper.ts @@ -0,0 +1,193 @@ +export const durationOptions = [ + { + id: 0, + title: 'h:mm', + example: '(e.g. 1:23)', + regex: /(\d+)(?::(\d+))?/ + }, { + id: 1, + title: 'h:mm:ss', + example: '(e.g. 3:45, 1:23:40)', + regex: /(\d+)?(?::(\d+))?(?::(\d+))?/ + }, { + id: 2, + title: 'h:mm:ss.s', + example: '(e.g. 3:34.6, 1:23:40.0)', + regex: /(\d+)?(?::(\d+))?(?::(\d+))?(?:.(\d{0,4})?)?/ + }, { + id: 3, + title: 'h:mm:ss.ss', + example: '(e.g. 3.45.67, 1:23:40.00)', + regex: /(\d+)?(?::(\d+))?(?::(\d+))?(?:.(\d{0,4})?)?/ + }, { + id: 4, + title: 'h:mm:ss.sss', + example: '(e.g. 3.45.678, 1:23:40.000)', + regex: /(\d+)?(?::(\d+))?(?::(\d+))?(?:.(\d{0,4})?)?/ + } + ] + + // pad zero + // mm && ss + // e.g. 3 -> 03 + // e.g. 12 -> 12 + // sss + // e.g. 1 -> 001 + // e.g. 10 -> 010 + const padZero = (val: number, isSSS = false) => { + return (val + '').padStart(isSSS ? 3 : 2, '0') + } + + export const convertMS2Duration = (val: any, durationType: number) => { + if (val === "" || val === null || val === undefined) { return val } + // 600.000 s --> 10:00 (10 mins) + const milliseconds = Math.round((val % 1) * 1000) + const centiseconds = Math.round(milliseconds / 10) + const deciseconds = Math.round(centiseconds / 10) + const hours = Math.floor(parseInt(val, 10) / (60 * 60)) + const minutes = Math.floor((parseInt(val, 10) - (hours * 60 * 60)) / 60) + const seconds = parseInt(val, 10) - (hours * 60 * 60) - (minutes * 60) + + if (durationType === 0) { + // h:mm + return `${padZero(hours)}:${padZero(minutes + (seconds >= 30 ? 1 : 0))}` + } else if (durationType === 1) { + // h:mm:ss + return `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}` + } else if (durationType === 2) { + // h:mm:ss.s + return `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}.${deciseconds}` + } else if (durationType === 3) { + // h:mm:ss.ss + return `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}.${padZero(centiseconds)}` + } else if (durationType === 4) { + // h:mm:ss.sss + return `${padZero(hours)}:${padZero(minutes)}:${padZero(seconds)}.${padZero(milliseconds, true)}` + } + return val + } + + export const convertDurationToSeconds = (val: any, durationType: number) => { + // 10:00 (10 mins) -> 600.000 s + const res = { + _sec: 0, + _isValid: true + } + const durationRegex = durationOptions[durationType].regex + if (durationRegex.test(val)) { + let h, mm, ss + const groups = val.match(durationRegex) + if (groups[0] && groups[1] && !groups[2] && !groups[3] && !groups[4]) { + const val = parseInt(groups[1], 10) + if (groups.input.slice(-1) === ':') { + // e.g. 30: + h = groups[1] + mm = 0 + ss = 0 + } else if (durationType === 0) { + // consider it as minutes + // e.g. 360 -> 06:00 + h = Math.floor(val / 60) + mm = Math.floor((val - ((h * 3600)) / 60)) + ss = 0 + } else { + // consider it as seconds + // e.g. 3600 -> 01:00:00 + h = Math.floor(groups[1] / 3600) + mm = Math.floor(groups[1] / 60) % 60 + ss = val % 60 + } + } else if (durationType !== 0 && groups[1] && groups[2] && !groups[3]) { + // 10:10 means mm:ss instead of h:mm + // 10:10:10 means h:mm:ss + h = 0 + mm = groups[1] + ss = groups[2] + } else { + h = groups[1] || 0 + mm = groups[2] || 0 + ss = groups[3] || 0 + } + + if (durationType === 0) { + // h:mm + res._sec = h * 3600 + mm * 60 + } else if (durationType === 1) { + // h:mm:ss + res._sec = h * 3600 + mm * 60 + ss * 1 + } else if (durationType === 2) { + // h:mm:ss.s (deciseconds) + const ds = groups[4] || 0 + const len = Math.log(ds) * Math.LOG10E + 1 | 0 + const ms = ( + // e.g. len = 4: 1234 -> 1, 1456 -> 1 + // e.g. len = 3: 123 -> 1, 191 -> 2 + // e.g. len = 2: 12 -> 1 , 16 -> 2 + len === 4 + ? Math.round(ds / 1000) + : len === 3 + ? Math.round(ds / 100) + : len === 2 + ? Math.round(ds / 10) + // take whatever it is + : ds + ) * 100 + res._sec = h * 3600 + mm * 60 + ss * 1 + ms / 1000 + } else if (durationType === 3) { + // h:mm:ss.ss (centiseconds) + const cs = groups[4] || 0 + const len = Math.log(cs) * Math.LOG10E + 1 | 0 + const ms = ( + // e.g. len = 4: 1234 -> 12, 1285 -> 13 + // e.g. len = 3: 123 -> 12, 128 -> 13 + // check the third digit + len === 4 + ? Math.round(cs / 100) + : len === 3 + ? Math.round(cs / 10) + // take whatever it is + : cs + ) * 10 + res._sec = h * 3600 + mm * 60 + ss * 1 + ms / 1000 + } else if (durationType === 4) { + // h:mm:ss.sss (milliseconds) + let ms = groups[4] || 0 + const len = Math.log(ms) * Math.LOG10E + 1 | 0 + ms = ( + // e.g. 1235 -> 124 + // e.g. 1234 -> 123 + len === 4 + ? Math.round(ms / 10) + // take whatever it is + : ms + ) * 1 + res._sec = h * 3600 + mm * 60 + ss * 1 + ms / 1000 + } + } else { + res._isValid = false + } + return res + } + + /** + * @copyright Copyright (c) 2021, Xgene Cloud Ltd + * + * @author Wing-Kam Wong + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + \ No newline at end of file