9

Is it possible to format seconds in a countdown style? For example, if I have var seconds = 3662, how can I show: 1 hour 1 minute 2 seconds.

I tried using formatDistanceStrict(3662) but this is only printing the hour: 1 hour.

Is there a built-in method to show the minutes and seconds too? I don't want to write 100 lines of code to get this working (like other examples from internet)

Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
Ionel Lupu
  • 2,695
  • 6
  • 29
  • 53

4 Answers4

11

The simplest solution I could find, using the date-fns library, is this:

import { formatDuration, intervalToDuration } from 'date-fns';

function humanDuration(time: number) {
    return formatDuration(intervalToDuration({start: 0, end: time * 1000}));
};
humanDuration(463441); // 5 days 8 hours 44 minutes 1 second
Ionel Lupu
  • 2,695
  • 6
  • 29
  • 53
2

Is that, what you mean?

const seconds = 3662,

      formatCounter = s => {
        let _s = s        
        const units = {day: 864e2, hour: 3600, minute: 60, second: 1},
              str = Object
                .entries(units)
                .reduce((r, [unit, multiplier]) => {            
                  if(_s >= multiplier){
                    const count = _s/multiplier|0,
                          tail = count > 1 ? 's' : ''
                    r.push([count, unit+tail])              
                    _s = _s%multiplier
                  }
                  return r
                }, [])
        return str.flat().join(' ')               
      } 
      
console.log(formatCounter(seconds))
console.log(formatCounter(416920))
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
  • Yes. But I have found a ton of solutions like this one on the internet. I would like to solve this using the date-fns with one function call. Date-fns does this half way and I thought I was missing something from their docs. Can't believe these big libraries don't have this functionality – Ionel Lupu Jun 26 '20 at 08:59
  • 1
    If that is the sole purpose of using date-fns in your project, I don't really think that 15 lines of code (giving you flexibility of customizing nearly anything) is that much of a headache compared to loading 70kB library and maintaining its compatibility with the rest of your environment in the future. – Yevhen Horbunkov Jun 26 '20 at 09:08
  • Of course it's not a headache. Wanted to know if there is a really fast way of getting this functionality without to many lines of code. I see there is an issue of their repo about this. It seems there is no simple way of doing this – Ionel Lupu Jun 26 '20 at 09:13
  • @YevgenGorbunkov Great code. BTW date-fns supports tree shaking. – rofrol Jan 20 '21 at 01:08
0

Are you looking for this.

Here I have converted seconds to minutes and hours

and returned the string.

function format(time) {   
    // Hours, minutes and seconds
    var hrs = ~~(time / 3600);
    var mins = ~~((time % 3600) / 60);
    var secs = ~~time % 60;

    // Output like "1:01" or "4:03:59" or "123:03:59"
    var ret = "";
    if (hrs > 0) {
        ret += "" + hrs + " hour " + (mins < 10 ? "0" : "");
    }
    ret += "" + mins + " minutes " + (secs < 10 ? "0" : "");
    ret += "" + secs + " seconds";
    return ret;
}

console.log(format(3662));
xMayank
  • 1,875
  • 2
  • 5
  • 19
  • Expected output obviously makes difference between plural and singular (pay attention to *'1 minute**s**'* and *'1 hour**s**'* in your output. Also, expected output is `1`, not `01`. – Yevhen Horbunkov Jun 26 '20 at 08:25
0

As simple as:

    const time = new Date(0,0,0)
    time.setSeconds(3662)
    console.log(time.getHours(), 
               time.getMinutes(), 
               time.getSeconds())
Ahmad
  • 1,913
  • 13
  • 21
  • 1
    This won't work for seconds count beyond 86400 (1 day) and there's a slight difference in format between your result and expected output. – Yevhen Horbunkov Jun 26 '20 at 08:29
  • If OP confirms that it needs to handle day+, I can modify it a bit. I think the OP is willing to get do some work :) With little change if can support any number of seconds. – Ahmad Jun 26 '20 at 08:35
  • I don't have that much of a mental connection with OP to tell what is the case and what is not. However, it doesn't change the fact that above code does not provide the expected output and it does not scale beyond 1 day span. – Yevhen Horbunkov Jun 26 '20 at 08:42
  • @YevgenGorbunkov He wants our help and isn't looking for someone to do it for him, no? – Ahmad Jun 26 '20 at 08:43
  • Why not `new Date(3662 * 1000)` and save some code? Or `Date(3662 * 1000).toTimeString().split(' ')[0]`. – RobG Jun 26 '20 at 08:43