17

I'm trying to display a count-down timer using date-fns library and doing things the below way, unable to find the solution in react.

Expected output: 60 days : 8 hours : 9 minutes : 5 seconds remaining

    const finishTime = new Date("01/01/2020");
    const currentTime = new Date();

Adding results to array to traverse later:

    results.push(differenceInMonths(finishTime, currentTime));
    results.push(differenceInDays(finishTime, currentTime));
    results.push(differenceInHours(finishTime, currentTime));
    results.push(differenceInMinutes(finishTime, currentTime));
    results.push(differenceInSeconds(finishTime, currentTime));

Adding manual logic to get the time from seconds. There should obviously be a better logic wiht / without using the library, which I'm missing:

    const monthsRemaining = results[4] / (30 * 24 * 3600); // this will anyways fail as 30 days is not common for every month
    const daysRemaining = (monthsRemaining % 1) * 30;
    const hoursRemaining = (daysRemaining % 1) * 24;
    const minutesRemaining = (hoursRemaining % 1) * 60;
    const secondsRemaining = (minutesRemaining % 1) * 60;

return (
        <div>
            {Math.round(monthsRemaining)} Months : {Math.round(daysRemaining)}{" "}
            days : {Math.round(hoursRemaining)} hours :{" "}
            {Math.round(minutesRemaining)} minutes :{" "}
            {Math.round(secondsRemaining)} seconds
        </div>
    );

Any suggestions or pointers to the right methods, as I don't see such direct implementation, I could only see formatDistance method which only one unit

beta programmers
  • 513
  • 2
  • 8
  • 23

2 Answers2

28

intervalToDuration is what you are looking for.

// Get the duration between January 15, 1929 and April 4, 1968.
intervalToDuration({
  start: new Date(1929, 0, 15, 12, 0, 0),
   end: new Date(1968, 3, 4, 19, 5, 0)
})
// => { years: 39, months: 2, days: 20, hours: 7, minutes: 5, seconds: 0 }

https://date-fns.org/v2.16.1/docs/intervalToDuration

phenicie
  • 637
  • 8
  • 14
2

In this case you need to use formatDistance.

  1. Import formatDistance from date-fns:

    import { formatDistance } from 'date-fns'
    
  2. Use the property with something like this:

    formatDistance(firstDate, secondDate, [options])
    

As options, you can include, for example, the language "locale: es".

vimuth
  • 5,064
  • 33
  • 79
  • 116
Rodrigo Ibarra
  • 147
  • 1
  • 1
  • 8
  • The problem with this is it returns a string of text, rather than a breakdown of duration. For example, if you wanted the number of days for a date span that is over many months – ckhatton Jul 10 '23 at 14:42