Overview
Parsing is the reverse of formatting: it converts human-readable duration strings like “2h 30m” into numeric milliseconds. Enhanced MS provides the parseDuration() function and the ms() factory function to handle this conversion.
How parsing works
The parsing process uses language-specific regular expressions to extract time values from strings (~/workspace/source/src/parse/index.ts:18):
export function parseDuration(
duration: string,
language: Language = getLanguage('en'),
) {
const matches = duration.toLowerCase().match(language.matcherRegex);
if (!matches || matches.length === 0) return 0;
let total = 0;
for (let i = 0; i < matches.length; i += 2) {
const [amount, unit] = matches.slice(i, i + 2) as [string, string];
const ms = language.timeUnits[unit]?.ms;
if (ms) total += Number(amount) * ms;
}
return total;
}
Step-by-step breakdown
- Convert to lowercase - Makes parsing case-insensitive
- Match patterns - Use regex to find number-unit pairs
- Sum values - Convert each pair to milliseconds and add them up
- Return total - Return the sum or
0 if no valid matches
Basic usage
Using parseDuration
Using ms() factory
import { parseDuration, getLanguage } from 'enhanced-ms';
parseDuration("2h 30m");
// 9000000 (2 hours + 30 minutes in milliseconds)
parseDuration("2 hours 30 minutes");
// 9000000
parseDuration("1 day, 5 hours, 30 minutes");
// 105000000
import { createMs } from 'enhanced-ms';
const ms = createMs({ language: 'en' });
ms("2h 30m");
// 9000000
ms("2 hours 30 minutes");
// 9000000
The parser is flexible and accepts various input formats:
Abbreviated units
ms("2h 30m 15s");
// 9015000
ms("1d 12h");
// 129600000
Full unit names
ms("2 hours 30 minutes 15 seconds");
// 9015000
ms("1 day 12 hours");
// 129600000
ms("1d 30 minutes 15s");
// 88215000 (mixing abbreviations and full names)
With punctuation
The parser handles common punctuation:
ms("1 day, 2 hours, 30 minutes");
// 95400000
ms("2h, 30m");
// 9000000
Decimal values
The parser uses language-specific decimal separators defined in the language configuration.
// English (uses . as decimal separator)
ms("1.5 hours");
// 5400000 (1.5 hours = 90 minutes)
// German (uses , as decimal separator)
const msDE = createMs({ language: 'de' });
msDE("1,5 stunden");
// 5400000
Matching patterns
Each language defines which strings match each unit (~/workspace/source/src/languages/en.ts:1). For example, English accepts:
// Hour variations
ms("1 hour"); // ✓
ms("2 hours"); // ✓
ms("1h"); // ✓
// Minute variations
ms("1 minute"); // ✓
ms("2 minutes"); // ✓
ms("1m"); // ✓
// Second variations
ms("1 second"); // ✓
ms("2 seconds"); // ✓
ms("1s"); // ✓
The matcher regex is built dynamically from the language’s unit definitions (~/workspace/source/src/languages/helpers/make-language.ts:24):
const matcherRegex = new RegExp(
`(?![${decimalSeparator}${thousandSeparator}])` + // Don't match separators alone
`[\\d${decimalSeparator}${thousandSeparator}]+|` + // Match numbers
'(?<=\\s|\\d)((?:-)?(' + // Match units after space or digit
Object.values(languageDefinition.units)
.flatMap(({ matches }) => matches)
.sort((a, b) => b.length - a.length) // Longer matches first
.join('|') +
'))',
'gi',
);
Longer unit names are matched first to prevent “months” from matching as “m” (minutes).
Order and accumulation
Units can appear in any order and are accumulated:
ms("30m 2h");
// 9000000 (2h + 30m)
ms("15s 30m 2h");
// 9015000 (2h + 30m + 15s)
Duplicate units are also accumulated:
ms("1h 30m 30m");
// 7200000 (1h + 30m + 30m = 2h total)
Localized parsing
You can parse strings in any supported language:
import { createMs } from 'enhanced-ms';
// German
const msDE = createMs({ language: 'de' });
msDE("2 stunden 30 minuten");
// 9000000
// French
const msFR = createMs({ language: 'fr' });
msFR("2 heures 30 minutes");
// 9000000
// Spanish
const msES = createMs({ language: 'es' });
msES("2 horas 30 minutos");
// 9000000
Each language has its own set of accepted unit names and abbreviations. See the Localization guide for details.
Edge cases
The parser handles various edge cases gracefully:
Invalid strings
Returns 0 for unrecognized formats:
ms("invalid");
// 0
ms("xyz");
// 0
ms("");
// 0
Partial matches
Extracts valid parts and ignores the rest:
ms("wait 2h then 30m later");
// 9000000 (ignores "wait" and "then" and "later")
Numbers without units
Ignored (numbers must be followed by units):
ms("42");
// 0 (no unit specified)
ms("42 minutes");
// 2520000 (unit specified)
Case insensitivity
Parsing works regardless of case:
ms("2H 30M");
// 9000000
ms("2 HOURS 30 MINUTES");
// 9000000
All supported units
Enhanced MS can parse all time units from nanoseconds to millennia:
| Unit | Example | Milliseconds |
|---|
| Nanosecond | "1ns" | 0.000001 |
| Microsecond | "1μs" | 0.001 |
| Millisecond | "1ms" | 1 |
| Second | "1s" | 1,000 |
| Minute | "1m" | 60,000 |
| Hour | "1h" | 3,600,000 |
| Day | "1d" | 86,400,000 |
| Week | "1w" | 604,800,000 |
| Month | "1mo" | 2,592,000,000 |
| Year | "1y" | 31,536,000,000 |
| Decade | "1dec" | 315,360,000,000 |
| Century | "1c" | 3,153,600,000,000 |
| Millennium | "1mil" | 31,536,000,000,000 |
Be careful with ambiguous abbreviations like “m” (minute vs month). Enhanced MS prioritizes minutes for “m” and requires “mo” for months.