
parse-duration-ms is a lightweight JavaScript utility library that converts human-readable duration strings into milliseconds.
It’s ideal for developers who need to parse timeout values, cache TTLs, rate limits, and other duration-based configuration without writing custom parsing logic.
Features:
- Combined Unit Support: Parses multiple units in one string, such as “1h 30m” or “2 days 5 hours 30 minutes”.
- Multiple Format Variations: Accepts shortened forms like “1hr 30min”, full words like “1 hour 30 minutes”, and compact formats like “1h30m”.
- Decimal Precision: Handles fractional value,s including “1.5h” or “0.5 minutes”.
- Case Insensitive: Processes “1H”, “30M”, and “1 HOUR” identically.
- Negative Duration Support: Returns negative milliseconds for inputs like “-1h” or “-30m”.
- Full Unit Coverage: Supports nanoseconds, milliseconds, seconds, minutes, hours, days, and weeks.
How To Use It:
1. Install the package and import it into your project.
# NPM $ npm install parse-duration-ms
import parseDuration from 'parse-duration-ms';
2. Parse duration strings. Supported unit:
| Unit | Short | Shorter Forms | Long Singular | Long Plural |
|---|---|---|---|---|
| Nanoseconds | ns | nsec, nsecs | nanosecond | nanoseconds |
| Milliseconds | ms | msec, msecs | millisecond | milliseconds |
| Seconds | s | sec, secs | second | seconds |
| Minutes | m | min, mins | minute | minutes |
| Hours | h | hr, hrs | hour | hours |
| Days | d | – | day | days |
| Weeks | w | – | week | weeks |
// Parse a single unit
const oneHour = parseDuration('1h');
// Returns: 3600000 (1 hour in milliseconds)
// Parse combined units
const duration = parseDuration('2 days 5 hours 30 minutes');
// Returns: 192600000 (total milliseconds for the combined duration)
// Parse shortened forms
const shortForm = parseDuration('1hr 30min');
// Returns: 5400000 (1.5 hours in milliseconds)
// Parse decimal values
const decimal = parseDuration('1.5 hours');
// Returns: 5400000 (90 minutes in milliseconds)
// Parse compact format without spaces
const compact = parseDuration('1h41m');
// Returns: 6060000 (101 minutes in milliseconds)
// Handle invalid input
const invalid = parseDuration('invalid');
// Returns: undefined (parsing failed)3. You should always validate parsed values before using them in production:
function parseConfigDuration(configValue, defaultMs, maxMs) {
const parsed = parseDuration(configValue);
// Return default if parsing failed
if (parsed === undefined) {
console.warn(`Invalid duration: ${configValue}. Using default.`);
return defaultMs;
}
// Enforce maximum limit
if (parsed > maxMs) {
console.warn(`Duration ${configValue} exceeds maximum. Capping at ${maxMs}ms.`);
return maxMs;
}
// Reject negative values if inappropriate
if (parsed < 0) {
console.warn(`Negative duration not allowed. Using default.`);
return defaultMs;
}
return parsed;
}
// Usage in configuration
const sessionTimeout = parseConfigDuration(
process.env.SESSION_TIMEOUT,
3600000, // Default: 1 hour
86400000 // Max: 24 hours
);Real-World Implementation Examples:
1. Environment Variable Timeout Parsing:
// Parse timeout from environment variable
const timeout = parseDuration(process.env.REQUEST_TIMEOUT || '30s');
// Use the parsed value in fetch with timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch('https://api.example.com/data', {
signal: controller.signal
});
clearTimeout(timeoutId);
// Process response
} catch (error) {
if (error.name === 'AbortError') {
console.error('Request timed out');
}
}2. Cache Expiration with Redis:
import parseDuration from 'parse-duration-ms';
import { createClient } from 'redis';
const client = createClient();
await client.connect();
// Parse TTL from configuration
const cacheTTL = parseDuration('1h 30m'); // Returns: 5400000
// Set cache value with expiration in milliseconds
await client.set('user:123', JSON.stringify(userData), {
PX: cacheTTL // Redis PX option accepts milliseconds
});3. Rate Limiting Window:
class RateLimiter {
constructor(maxRequests, windowDuration) {
this.maxRequests = maxRequests;
// Convert human-readable window to milliseconds
this.window = parseDuration(windowDuration);
this.requests = new Map();
}
canMakeRequest(userId) {
const now = Date.now();
const userRequests = this.requests.get(userId) || [];
// Filter requests within the current window
const recentRequests = userRequests.filter(
timestamp => now - timestamp < this.window
);
if (recentRequests.length < this.maxRequests) {
recentRequests.push(now);
this.requests.set(userId, recentRequests);
return true;
}
return false;
}
}
// Create limiter: 100 requests per 1 hour
const limiter = new RateLimiter(100, '1h');Alternatives:
- ms: A popular utility by Vercel. It converts strings to milliseconds and vice versa. It does not support combined units like “1h 30m”.
- pretty-ms: This performs the inverse operation. It converts milliseconds back into human-readable strings.
FAQs:
Q: Why does the library return undefined instead of throwing an error for invalid input?
A: Returning undefined allows for safer parsing in configuration contexts where you can provide fallback values. You can write const timeout = parseDuration(config.timeout) || 30000 to default to 30 seconds if parsing fails. This pattern is more convenient than wrapping every parse call in try-catch blocks. If you need strict validation, check for undefined and throw your own error.
Q: Can I parse durations with months or years?
A: No. Months and years are not fixed durations. A month can be 28, 29, 30, or 31 days depending on the calendar month and leap years. A year can be 365 or 366 days. Any approximation would produce silently incorrect results in many cases. Use explicit day counts instead. For example, use “30d” to represent approximately one month or “365d” to represent approximately one year.
Q: How do I handle user input that might contain invalid duration strings?
A: Always check if the result is undefined before using it. Provide clear error messages or defaults. Validate user input on both the client and server. You can create a wrapper function that validates the parsed value against minimum and maximum thresholds. Log warnings when parsing fails so you can identify problematic configuration values during development or debugging.
Q: Does the library support time zones or absolute timestamps?
A: No. This library only parses relative durations such as lengths of time. It does not handle dates, timestamps, or time zones.
Q: What happens if I pass a very large duration string like “999999 weeks”?
A: The library will calculate the correct millisecond value, which may be a very large number. JavaScript can safely represent integers up to Number.MAX_SAFE_INTEGER, which is 2^53 – 1. Durations exceeding this value will lose precision.







