Reputation: 119
I'm using Reactjs to make a countdown timer that can separate to day, hours, minutes, and seconds between 2 dates. It works fine, but It can only count to a date that is larger than the current date (21/08/2022 < 17/10/2022), but It cannot count to (21/08/2022 to 21/08/2023). I have a function to pass down props:
const timeLeft = useCountdown(new Date(2022, Data.date.month , Data.date.day));
It should look like this when console.log:
{days: 87, hours: 20, minutes: 58, seconds: 40}
I'm using a useCountDown hook to count the time between 2 dates:
import { useState, useEffect } from "react";
const useCountdown = (deadline) => {
const [days, setDays] = useState(0);
const [hours, setHours] = useState(0);
const [minutes, setMinutes] = useState(0);
const [seconds, setSeconds] = useState(0);
const leading0 = (num) => {
return num < 10 ? "0" + num : num;
};
const getTimeUntil = (deadline) => {
const time = Date.parse(deadline) - Date.parse(new Date());
if (time < 0) {
setDays(0);
setHours(0);
setMinutes(0);
setSeconds(0);
} else {
setDays(Math.floor(time / (1000 * 60 * 60 * 24)));
setHours(Math.floor((time / (1000 * 60 * 60)) % 24));
setMinutes(Math.floor((time / 1000 / 60) % 60));
setSeconds(Math.floor((time / 1000) % 60));
}
};
useEffect(() => {
setInterval(() => getTimeUntil(deadline), 1000);
return () => getTimeUntil(deadline);
}, [deadline]);
return {
days: leading0(days),
hours: leading0(hours),
minutes: leading0(minutes),
seconds: leading0(seconds)
};
};
export default useCountdown;
I haven't figured out how to fix this. Sorry for the bad English, but I'm trying my best :( Thank you for helping me!
Upvotes: 1
Views: 1048
Reputation: 10994
Here's a much simpler version:
const useCountdown = (deadline: Date) => {
// Time is in seconds
const [time, setTime] = useState(
Math.max(0, Math.floor((deadline.getTime() - Date.now()) / 1000))
);
const decrement = () =>
setTime((prevTime) => {
return prevTime === 0 ? 0 : prevTime - 1;
});
useEffect(() => {
const id = setInterval(decrement, 1000);
return () => clearInterval(id);
}, []);
const format = (num: number): string => {
return num < 10 ? '0' + num : num.toString();
};
return {
days: format(Math.floor(time / (3600 * 24))),
hours: format(Math.floor((time / 3600) % 24)),
minutes: format(Math.floor((time / 60) % 60)),
seconds: format(time % 60),
};
};
Stackblitz: https://stackblitz.com/edit/react-ts-bnhvxp?file=App.tsx
Upvotes: 3