Briefing:
Hi, I have created a hook useDate() to display current time and date as follows:
interface ReturnDate { time: string; date: string; wish: string;
}
export const useDate = (): ReturnDate => { const locale = 'en'; const today = new Date(); const day = today.toLocaleDateString(locale, { weekday: 'long' }); const date = `${day}, ${today.getDate()} ${today.toLocaleDateString(locale, { month: 'long' })}\n\n`; const hour = today.getHours(); const wish = `Good ${(hour < 12 && 'Morning') || (hour < 17 && 'Afternoon') || 'Evening'}, `; const time = today.toLocaleTimeString(locale, { hour: 'numeric', hour12: true, minute: 'numeric' }); return { date, time, wish, };
};And I'm using it in my component below as follows:
const ProfileGreetings: FC = () => { const { firstName } = useUserDetails(); const { date, time, wish } = useDate(); return ( <div className="greetings-container"> <h1> {wish} <PrimaryText text={`${firstName || ''}!`} /> </h1> <div> <h3> {date} <br /> {time} </h3> </div> </div> );
};Date/Time format in app:
Sunday, 2 August
11:54 PM
Problem Statement:
Currently what's happening is that the date and time don't update until I refresh the page. Is there any way to have all of the following to be updated in real time?
I am thinking to use an interval after every 1 minute to compute the updated time and date, but don’t really know if that's good idea. Neither do I know how to start with that and how will the interval be cleared?
Thanks! :)
3 Answers
Since you can use hooks in custom hooks you can create an interval to update every minute like this:
export const useDate = () => { const locale = 'en'; const [today, setDate] = React.useState(new Date()); // Save the current date to be able to trigger an update React.useEffect(() => { const timer = setInterval(() => { // Creates an interval which will update the current data every minute // This will trigger a rerender every component that uses the useDate hook. setDate(new Date()); }, 60 * 1000); return () => { clearInterval(timer); // Return a funtion to clear the timer so that it will stop being called on unmount } }, []); const day = today.toLocaleDateString(locale, { weekday: 'long' }); const date = `${day}, ${today.getDate()} ${today.toLocaleDateString(locale, { month: 'long' })}\n\n`; const hour = today.getHours(); const wish = `Good ${(hour < 12 && 'Morning') || (hour < 17 && 'Afternoon') || 'Evening'}, `; const time = today.toLocaleTimeString(locale, { hour: 'numeric', hour12: true, minute: 'numeric' }); return { date, time, wish, };
}; 6 I have an idea for this.
I will loop on while and dynamic sleep with the difference between currentTime and rounding in seconds of currentTime + 1 second. You can refer to this script.
function getRealTime() { const currentTime = Date.now(); console.log(new Date(Math.round(currentTime / 1000) * 1000), currentTime); return (Math.floor(currentTime / 1000) + 1) * 1000 - currentTime;
}
(async function () { let reduceTime = 0; while (true) { reduceTime = getRealTime(); await sleep(reduceTime); }
})()
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms));
} import React from 'react';
import ReactDom from 'react-dom';
const date = new Date().toLocaleDateString();
const time = new Date().toLocaleTimeString();
ReactDom.render(
<>
<p>Today's date is {date}</p>
<p>Today's time is {time}</p>
</>
,
document.getElementById('root'));
Output
Today's date is 8/14/2020
Today's time is 7:42:01 PM 1