Search code examples
javascriptarraysstringmilliseconds

How can I convert human time strings into milliseconds?


Here's what I've tried from this question's's accepted answer

const timeString = '1h 30m 1s'
const milliseconds  = timeString.match(/\d+/g)
       .reduce((acc, cur, idx) => acc + cur * (Math.pow(60, (2 - idx))) * 1000, 0)
console.log(milliseconds)
// result: 5401000
// expected result: 5401000

But, here's the problem, if I only put 1m for instance, expected output should be 60000 milliseconds

const timeString = '1m'
const milliseconds  = timeString.match(/\d+/g)
       .reduce((acc, cur, idx) => acc + cur * (Math.pow(60, (2 - idx))) * 1000, 0)
console.log(milliseconds)
// result: 3600000 
// expected result: 60000

It thinks that the first argument is an hour, then minute followed by second. No matter what I input. So when I put 1m, it thinks that it is an hour. It's a fixed h, m & s format and I am not able to interchange them.

The solution I want is that I should be able to interchange them parse h as hours, m for minutes, and s for seconds no matter what order and able to choose only h, m or s like

If I only output 1m, should output 1 minute only and so on

const timeString = '1m`
// should output 60000 
const timeString = '2h 1s`
// should output 7201000

If I interchange them, it should still output the same result since s is a second and h is an hour

const timeString = '1s 2h`
// should output 7201000
const timeString = '1s`
// should output 1000

or interchange them however I want no matter what format I use, and should still output the desired result in milliseconds

const timeString = '1s 6h 2m`
// should output 21721000 

Solution

  • If you want something more robust try this:

    const timeString = '1h 30m 1s';
    const milliseconds = timeString.match(/\d+\s?\w/g)
        .reduce((acc, cur, i) => {
            var multiplier = 1000;
             switch (cur.slice(-1)) {
                case 'h':
                    multiplier *= 60;
                case 'm':
                    multiplier *= 60;
                case 's':
                    return ((parseInt(cur)?parseInt(cur):0) * multiplier) + acc;
            }
            return acc;
        }, 0);
    console.log(milliseconds);
    

    This can handle time strings in any order like '12s 5m 1h' and will ignore extraneous elements and even handle strings like 'in 1 hour 24 minutes and 3 seconds'.