How to parse a duration string into seconds with Javascript?
You can use optional substrings in the regex to match any combination as you describe:
/(\d+)\s*d(ays?)?\s*(\d+)\s*h(ours?)?\s*(\d+)\s*m(in(utes?)?)?/
This requires at least a d
, h
, and m
but accepts common shortenings.
You can use this code to break your string into a number, followed by a unit string:
function getPieces(str) {
var pieces = [];
var re = /(\d+)[\s,]*([a-zA-Z]+)/g, matches;
while (matches = re.exec(str)) {
pieces.push(+matches[1]);
pieces.push(matches[2]);
}
return(pieces);
}
Then function returns an array such as ["1","day","2","hours","3","minutes"]
where alternating items in the array are the value and then the unit for that value.
So, for the string:
"1 day, 2 hours, 3 minutes"
the function returns:
[1, "day", 2, "hours", 3, "minutes"]
Then, you can just examine the units for each value to decide how to handle it.
Working demo and test cases here: http://jsfiddle.net/jfriend00/kT9qn/. The function is tolerant of variable amounts of whitespace and will take a comma, a space or neither between the digit and the unit label. It expects either a space or a comma (at least one) after the unit.
var str = "1 day, 2 hours, 3 minutes";
var seconds = 0;
str.replace (/\s*,?(\d+)\s*(?:(d)(?:ays?)?|(h)(?:ours?)?|(m)(?:in(?:utes?)?)?)/g, function (m0, n, d, h, m) {
seconds += +n * (d ? 24 * 60 * 60 : h ? 60 * 60 : 60);
return m0;
});
Here I use replace not to change the string but to process the matches one by one. Note days, hours aminutes can be in any order.
Is the order of days/hours/minutes in your string guaranteed? If not, it may be easier to just do a separate RegEx for each. Something like this?
function getSeconds(str) {
var seconds = 0;
var days = str.match(/(\d+)\s*d/);
var hours = str.match(/(\d+)\s*h/);
var minutes = str.match(/(\d+)\s*m/);
if (days) { seconds += parseInt(days[1])*86400; }
if (hours) { seconds += parseInt(hours[1])*3600; }
if (minutes) { seconds += parseInt(minutes[1])*60; }
return seconds;
}