DEV Community

loading...

Discussion on: Get Real Time Date and Time using JavaScript

Collapse
lukeshiru profile image
LUKE知る

You can implement this in a way simpler manner:

  1. Date provides a method called toLocaleString which you can use to get all the data you need.
  2. You can use HTML templates instead of changing the content of the HTML directly.
  3. You can split the logic to get the date and time data from the one that updates the DOM.

It can look something like this (I added JSDocs to make it clearer and used Tailwind so we can focus on the JS portion of the code):

<!DOCTYPE html>
<html>
  <head>
    <title>Time and Date</title>
  </head>
  <style>
    @import url("https://fonts.googleapis.com/css2?family=Fredoka+One&display=swap");
    @import url("https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css");
    .font-fredoka { font-family: "Fredoka One", cursive; }
  </style>
  <body class="font-fredoka m-0">
    <script>
      /**
       * Get date information of given date (new Date by default).
       *
       * @param {Date} [date]
       * @returns {[weekday: string, dayAndMonth: string, year: string, time: string]} Tuple of 4 elements with date information.
       */
      const getDateTimeTuple = (date = new Date()) =>
        date
          .toLocaleString("en-US", {
            day: "2-digit",
            hour12: true,
            month: "long",
            weekday: "short",
            year: "numeric",
            hour: "2-digit",
            minute: "2-digit"
          })
          .split(", ");

      /**
       * Updates given target element with the current time.
       * @param {HTMLElement} target Target element to be updated with template.
       */
      const render = target => {
        const [weekday, dayAndMonth, year, time] = getDateTimeTuple();
        const template = document.createElement("template");
        template.innerHTML = `
          <main class="flex h-screen items-center justify-center w-screen">
            <span class="m-2 text-blue-700 text-7xl">${time}</span>
            <span class="m-2 text-red-400 text-5xl uppercase">${weekday}</span>
            <span class="m-2 text-red-400 text-2xl uppercase">${dayAndMonth}, ${year}</span>
          </main>
        `;
        // We avoid updating the DOM every time this function is called
        if (template.innerHTML !== target.innerHTML) {
          target.innerHTML = template.innerHTML;
        }
      };

      // We use `document.body` as a target, but we can put it anywhere
      render(document.body);
      setInterval(() => render(document.body), 500);
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode
Collapse
lukeshiru profile image
LUKE知る

You can also take it one step further, and use tools like htm to have reactive components:

<!DOCTYPE html>
<html>
  <head>
    <title>Time and Date</title>
  </head>
  <style>
    @import url("https://fonts.googleapis.com/css2?family=Fredoka+One&display=swap");
    @import url("https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css");
    .font-fredoka { font-family: "Fredoka One", cursive; }
  </style>
  <body class="font-fredoka m-0">
    <script type="module">
      import {
        html,
        render,
        useEffect,
        useState
      } from "https://unpkg.com/htm/preact/standalone.module.js";

      const getDateLocaleString = (date = new Date()) =>
        date.toLocaleString("en-US", {
          day: "2-digit",
          hour12: true,
          month: "long",
          weekday: "short",
          year: "numeric",
          hour: "2-digit",
          minute: "2-digit",
          second: "2-digit"
        });

      /**
       * Hook to get date and time information.
       *
       * @returns {[weekday: string, dayAndMonth: string, year: string, time: string]} Tuple of 4 elements with date information.
       */
      const useDateTimeTuple = () => {
        const [dateLocaleString, setDateLocaleString] = useState(
          getDateLocaleString(new Date())
        );

        useEffect(() => {
          const interval = setInterval(() => {
            setDateLocaleString(getDateLocaleString(new Date()));
          }, 500);
          return () => clearInterval(interval);
        }, []);

        return dateLocaleString.split(", ");
      };

      /**
       * DateTime component.
       */
      const DateTime = () => {
        const [weekday, dayAndMonth, year, time] = useDateTimeTuple();

        return html`
          <main class="flex h-screen items-center justify-center w-screen">
            <span class="m-2 text-blue-700 text-7xl">${time}</span>
            <span class="m-2 text-red-400 text-5xl uppercase">${weekday}</span>
            <span class="m-2 text-red-400 text-2xl uppercase">
              ${dayAndMonth}, ${year}
            </span>
          </main>
        `;
      };

      render(html`<${DateTime} />`, document.body);
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode