From e963114cc5dde145653b557eb1381421d3e4aa47 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 27 Sep 2024 17:25:15 +0200 Subject: [PATCH] work for #183 --- src/tests/utils/time.test.ts | 44 +++++++++++++++++++++++++++++++++--- src/utils/time.ts | 40 ++++++++++++++++++++++++-------- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/tests/utils/time.test.ts b/src/tests/utils/time.test.ts index 8d869bc..6b8c96c 100644 --- a/src/tests/utils/time.test.ts +++ b/src/tests/utils/time.test.ts @@ -1,4 +1,4 @@ -import { showDate, strToSeconds } from "../../utils/time"; +import { nextTimeUnit, showDate, strToSeconds, TimeSecond } from "../../utils/time"; describe("Date with correct timezone", () => { const map = new Map([["u_time_at", "@"]]); @@ -39,10 +39,48 @@ describe("String time to seconds", () => { }); } { - // todo: see https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues/183 const name = "12h30"; test(name, () => { - /* expect(strToSeconds(name)).toBe(45000); */ + expect(strToSeconds(name)).toBe(45000); + }); + } + { + const name = "12s30"; + test(name, () => { + expect(strToSeconds(name)).toBe(42); + }); + } + { + const name = "1w30h20"; + test(name, () => { + expect(strToSeconds(name)).toBe(714000); + }); + } +}); + +describe("Next time unit", () => { + { + const name = TimeSecond.Minute; + test(name.toString(), () => { + expect(nextTimeUnit(name)).toBe(TimeSecond.Second); + }); + } + { + const name = TimeSecond.Hour; + test(name.toString(), () => { + expect(nextTimeUnit(name)).toBe(TimeSecond.Minute); + }); + } + { + const name = TimeSecond.Second; + test(name.toString(), () => { + expect(nextTimeUnit(name)).toBe(TimeSecond.Second); + }); + } + { + const name = TimeSecond.Year; + test(name.toString(), () => { + expect(nextTimeUnit(name)).toBe(TimeSecond.Week); }); } }); diff --git a/src/utils/time.ts b/src/utils/time.ts index 51b3b70..e25d93d 100644 --- a/src/utils/time.ts +++ b/src/utils/time.ts @@ -22,7 +22,7 @@ export const showDate = (tz: string, locale: Map, date: Date) = return `${formattedDate[0]} ${locale.get("u_time_at")} ${formattedDate[1]}`; }; -enum TimeSecond { +export enum TimeSecond { Year = 31536000, Week = 604800, Day = 86400, @@ -31,6 +31,18 @@ enum TimeSecond { Second = 1, } +/** + * Get next time unit. For example the next unit after Hour is Minute + * @param currentUnit Current time unit + * @returns The next time unit + */ +export const nextTimeUnit = (currentUnit: number) => { + const units = Object.values(TimeSecond) as number[]; + + const index = units.indexOf(currentUnit); + return units[index + 1] || TimeSecond.Second; +}; + /** * Take a cooldown, for example 2min and transform it to seconds, here: 120s * @param time time in human format @@ -42,14 +54,15 @@ export const strToSeconds = (time: string) => { return -1; } + const noUnit = "unmarked"; const regex = RegexC( - `(?<${TimeSecond[TimeSecond.Year]}>[0-9]+(?=[y|a]))|(?<${ - TimeSecond[TimeSecond.Week] - }>[0-9]+(?=[w]))|(?<${TimeSecond[TimeSecond.Day]}>[0-9]+(?=[d|j]))|(?<${ - TimeSecond[TimeSecond.Hour] - }>[0-9]+(?=[h]))|(?<${TimeSecond[TimeSecond.Minute]}>[0-9]+(?=[m]))|(?<${ - TimeSecond[TimeSecond.Second] - }>[0-9]+(?=[s]?))`, + `(?<${TimeSecond[TimeSecond.Year]}>[0-9]+(?=[y|a]))|` + + `(?<${TimeSecond[TimeSecond.Week]}>[0-9]+(?=[w]))|` + + `(?<${TimeSecond[TimeSecond.Day]}>[0-9]+(?=[d|j]))|` + + `(?<${TimeSecond[TimeSecond.Hour]}>[0-9]+(?=[h]))|` + + `(?<${TimeSecond[TimeSecond.Minute]}>[0-9]+(?=[m]))|` + + `(?<${TimeSecond[TimeSecond.Second]}>[0-9]+(?=[s]))|` + + `(?<${noUnit}>[0-9]+)`, RegExpFlags.Global | RegExpFlags.Insensitive, ); @@ -60,10 +73,19 @@ export const strToSeconds = (time: string) => { } let res = 0; + let lastUnit = TimeSecond.Second; data.forEach((match) => { Object.entries(match.groups!).forEach(([key, value]) => { if (value) { - res += +value * TimeSecond[key as keyof typeof TimeSecond]; + let unit; + if (key === noUnit) { + unit = nextTimeUnit(lastUnit); + res += +value * unit; + } else { + unit = TimeSecond[key as keyof typeof TimeSecond]; + res += +value * unit; + } + lastUnit = unit; } }); });