Format time interval in seconds as X hour(s) Y minute(s) Z second(s)
Asked Answered
G

4

10

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)

Good answered 26/6, 2020 at 8:1 Comment(3)
isn't momentjs an option?Retrospective
#14157841Schwarzwald
@Mody unfortunately no :(Good
G
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
Good answered 26/6, 2020 at 9:15 Comment(2)
I am using NG-Zorro UI Kit and it seems it comes with date-fns ^2.10.0Good
This is simple and elegant. It is worth mentioning though, that this does not divide in weeks (i.e. if the duration is 1 week 2 days it will convert to "9 days")Benz
C
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))
Cherimoya answered 26/6, 2020 at 8:15 Comment(4)
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 functionalityGood
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.Cherimoya
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 thisGood
@YevgenGorbunkov Great code. BTW date-fns supports tree shaking.Viol
R
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));
Rhizotomy answered 26/6, 2020 at 8:13 Comment(1)
Expected output obviously makes difference between plural and singular (pay attention to '1 minutes' and '1 hours' in your output. Also, expected output is 1, not 01.Cherimoya
R
0

As simple as:

    const time = new Date(0,0,0)
    time.setSeconds(3662)
    console.log(time.getHours(), 
               time.getMinutes(), 
               time.getSeconds())
Retrospective answered 26/6, 2020 at 8:24 Comment(5)
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.Cherimoya
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.Retrospective
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.Cherimoya
@YevgenGorbunkov He wants our help and isn't looking for someone to do it for him, no?Retrospective
Why not new Date(3662 * 1000) and save some code? Or Date(3662 * 1000).toTimeString().split(' ')[0].Matelote

© 2022 - 2025 — McMap. All rights reserved.