【JavaScript】正確な現在時刻を表示するプログラム

自動翻訳(Auto Translation)

NTPサーバーにアクセスして正確な時刻を取得し、定期的に時刻を更新して表示することで、コンピューターの時刻がずれていても正確な現在時刻を表示できるウェブページを作成しました。

また、Service Workerを使用することでオフライン環境でも、コンピューターの時刻を表示することができるため、時刻を確認することができます。


index.html
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" content-language="ja">
<html lang="ja">
<script>
  if ("serviceWorker" in navigator) {
    window.addEventListener("load", function () {
      navigator.serviceWorker
        .register("sw.js")
        .then(function (registration) {
          console.log(
            "Service Worker registration successful with scope: ",
            registration.scope
          );
        })
        .catch(function (err) {
          console.log("Service Worker registration failed: ", err);
        });
    });
  }
</script>
  <head>
    <style>
      #info {
        position: absolute;
        top: 3%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        font-size: 1vw; /* 画面幅の5%の大きさにする */
      }
      #time {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        font-size: 5vw; /* 画面幅の5%の大きさにする */
      }
    </style>
  </head>
  <body>
    <div id="info"></div>
    <div id="time"></div>
    <script>
      // NTPサーバーのURL
      const ntpUrl = "https://worldtimeapi.org/api/ip";

      // 情報を表示する要素
      const infoElement = document.getElementById("info");
      // 時刻を表示する要素
      const timeElement = document.getElementById("time");

      // 初期時刻を取得
      let timestamp = 0;
      const xhr = new XMLHttpRequest();
      xhr.open("GET", ntpUrl);
      xhr.onload = function () {
        // レスポンスから正確な時刻を抽出
        const responseJson = JSON.parse(xhr.responseText);
        timestamp = responseJson.unixtime * 1000; // ミリ秒単位に変換

        // 定期的に時刻を更新
        setInterval(updateTime, 1000);
      };
      xhr.onerror = function (error) {
        // ERNET_DISCONNECTEDエラーが発生した場合、ローカル時間を表示
        const date = new Date();
        timestamp = date.getTime();

        // メッセージを表示
        infoElement.textContent = `NTPサーバーに接続できませんでした。コンピューターの時刻を表示しています。`;
        timeElement.textContent = `${date.toLocaleString()}`;

        // 定期的に時刻を更新
        setInterval(updateTime, 1000);
      };
      xhr.send();

      // 時刻を更新する関数
      function updateTime() {
        // 現在の時刻を更新
        timestamp += 1000;

        // 時刻をページに表示
        const date = new Date(timestamp);
        timeElement.textContent = date.toLocaleString();
      }
    </script>
  </body>
</html>
sw.js
// キャッシュ名
const CACHE_NAME = "ntp-cache-v1";

// キャッシュするファイルのリスト
const urlsToCache = [
  "index.html",
  "sw.js"
];

// Service Workerのインストール時に実行される処理
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
      .then(() => self.skipWaiting())
  );
});

// Service Workerのアクティブ化時に実行される処理
self.addEventListener("activate", (event) => {
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames.map((cacheName) => {
          if (cacheName !== CACHE_NAME) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

// リクエストに対するレスポンスを取得する処理
function fetchAndCache(request) {
  return fetch(request)
    .then((response) => {
      // レスポンスをキャッシュに保存
      const responseToCache = response.clone();
      caches.open(CACHE_NAME).then((cache) => {
        cache.put(request, responseToCache);
      });
      return response;
    })
    .catch((error) => {
      console.log("Fetch failed; returning offline page instead.", error);

      // キャッシュからレスポンスを取得
      return caches.match(request).then((response) => {
        if (response) {
          return response;
        }
      });
    });
}

// リクエストに対するレスポンスを返す処理
self.addEventListener("fetch", (event) => {
  // NTPサーバーからの時刻取得リクエストに対するレスポンスをキャッシュから返す
  if (event.request.url === "https://worldtimeapi.org/api/ip") {
    event.respondWith(fetch(event.request));
    return;
  }

  // その他のリクエストに対するレスポンスを取得する
  event.respondWith(
    fetchAndCache(event.request)
  );
});

広告ブロック機能を検知しました

このウェブサイトは広告収益によって成り立っています。ご協力をお願いします。