taler-util: parse duration strings

This commit is contained in:
Florian Dold 2023-02-21 01:08:07 +01:00
parent a49959d2c8
commit b9b1dd73f5
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,39 @@
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import test from "ava";
import { Duration } from "./time.js";
test("duration parsing", (t) => {
const d1 = Duration.fromPrettyString("1h");
t.deepEqual(d1.d_ms, 60 * 60 * 1000);
const d2 = Duration.fromPrettyString(" 2h 1s 3m");
t.deepEqual(d2.d_ms, 2 * 60 * 60 * 1000 + 3 * 60 * 1000 + 1000);
t.throws(() => {
Duration.fromPrettyString("5g");
});
t.throws(() => {
Duration.fromPrettyString("s");
});
t.throws(() => {
Duration.fromPrettyString("s5");
});
t.throws(() => {
Duration.fromPrettyString("5 5 s");
});
});

View File

@ -113,6 +113,49 @@ export namespace Duration {
return { d_ms: deadline.t_ms - now.t_ms };
}
export function fromPrettyString(s: string): Duration {
let dMs = 0;
let currentNum = "";
let parsingNum = true;
for (let i = 0; i < s.length; i++) {
const cc = s.charCodeAt(i);
if (cc >= "0".charCodeAt(0) && cc <= "9".charCodeAt(0)) {
if (!parsingNum) {
throw Error("invalid duration, unexpected number");
}
currentNum += s[i];
continue;
}
if (s[i] == " ") {
if (currentNum != "") {
parsingNum = false;
}
continue;
}
if (currentNum == "") {
throw Error("invalid duration, missing number");
}
if (s[i] === "s") {
dMs += 1000 * Number.parseInt(currentNum, 10);
} else if (s[i] === "m") {
dMs += 60 * 1000 * Number.parseInt(currentNum, 10);
} else if (s[i] === "h") {
dMs += 60 * 60 * 1000 * Number.parseInt(currentNum, 10);
} else if (s[i] === "d") {
dMs += 24 * 60 * 60 * 1000 * Number.parseInt(currentNum, 10);
} else {
throw Error("invalid duration, unsupported unit");
}
currentNum = "";
parsingNum = true;
}
return {
d_ms: dMs,
};
}
export function max(d1: Duration, d2: Duration): Duration {
return durationMax(d1, d2);
}