Convert Human-readable Duration Strings to 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.
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
); 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'); 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.
The post Convert Human-readable Duration Strings to Milliseconds appeared first on CSS Script.