Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse a duration string into seconds with Javascript?

I'm trying to parse a user input string for duration (into seconds) with Javascript.

Here are some example inputs that I'd like to be able to deal with:

  • "1 hour, 2 minutes"
  • "1 day, 2 hours, 3 minutes"
  • "1d 2h 37m"
  • "1 day 2min"
  • "3days 20hours"

The key components are 1) days, 2) hours 3) minutes, but some components may not always be included.

My plan of attack is to use .match and regex. As long as I can get the first letter of the word, I'll know what the preceding number is for and be able to handle all the different formats of the words (e.g. hours, hour, hr, h). However, since I'm learning regex for this, it's turned out to be much more complicated than I thought.

Any help or suggestions would be greatly appreciated!

like image 295
Andrew Cross Avatar asked Aug 10 '12 21:08

Andrew Cross


2 Answers

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;
}
like image 105
Tim Goodman Avatar answered Nov 19 '22 09:11

Tim Goodman


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.

like image 2
jfriend00 Avatar answered Nov 19 '22 11:11

jfriend00