Problems › JavaScript › dates
Read a duration a human typed
A config file lets people write timeouts as "1h30m" instead of counting seconds, and the loader has to turn that into a number without trusting it.
- The units are h, m and s. Each may appear at most once, and they must be in that order.
- Each unit is preceded by a run of digits: "2h", "30m", "45s".
- An empty string is zero seconds.
- Anything that does not fit — a stray letter, a number with no unit, units out of order — gives -1.
parseDuration(text: string) → int
Where you start
function parseDuration(text) {
}
Worked examples
| Call | Result |
|---|---|
parseDuration("1h30m") | 5400 |
parseDuration("45s") | 45 |
parseDuration("2h") | 7200 |
parseDuration("90m") | 5400 |
Hint
Scan digits, then expect exactly one unit letter. Remember which units you have already taken so order and repeats are both caught by the same check.
Reference solution in JavaScript
function parseDuration(text) {
const rank = { h: 1, m: 2, s: 3 };
const mult = { h: 3600, m: 60, s: 1 };
let i = 0, total = 0, last = 0;
while (i < text.length) {
let n = 0, digits = 0;
while (i < text.length && text[i] >= '0' && text[i] <= '9') { n = n * 10 + (text.charCodeAt(i) - 48); i++; digits++; }
if (digits === 0 || i >= text.length) return -1;
const u = text[i];
if (!(u in rank) || rank[u] <= last) return -1;
last = rank[u];
total += n * mult[u];
i++;
}
return total;
}