NTPサーバーからタイムスタンプを取得する方法

更新しました Aug 12, 2025

環境

ソフトウェア

  • LabVIEW

この記事では、Meinberg社のLANTIME M1000を例に、LabVIEWを使用してNTPサーバからタイムスタンプを取得する方法を紹介します。
LANTIME M1000は高精度なNTP/PTPタイムサーバで、UDPベースのNTPリクエストに対応しています。タイムスタンプを取得するには、標準的なNTPクライアントとしてUDPポート123にリクエストパケットを送信する必要があります。

手順は以下の4ステップです:

  1. NTPサーバのIPアドレスとポート番号を設定し、UDPソケットを作成
  2. NTPリクエストパケットを作成し、UDPで送信
  3. 応答を受信し、「Transmit Timestamp」を抽出
  4. NTP時刻をUNIX時刻、さらにLabVIEWのTimestampに変換

ユニキャスト UDP を使用して NTP サーバーからタイムスタンプを取得するには、次の手順に従います。

1. NTPサーバのIPアドレスとポート番号を設定し、UDPソケットを作成

標準的なNTP通信では、UDPポート123を使用します。ここでは、NTPサーバのIPアドレスを 10.152.4.60 とします。

2. NTPリクエストパケットを作成し、UDPで送信

NTPリクエストは48バイトのパケットで、以下のように構成されます:

  • 1バイト目:LI(うるう秒)、VN(バージョン)、Mode(通信モード)
    例:0x1B(LI=0, VN=3, Mode=3)
  • 2〜48バイト目:通常はゼロで埋める

この結果、1バイト目は10進数で 27 となり、残りはすべて 0 の48バイトのリクエストパケットになります。

3. 応答を受信し、「Transmit Timestamp」を抽出

NTP応答も48バイトで、最後の8バイトに Transmit Timestamp が格納されています:

  • 最初の4バイト:整数部
  • 後半の4バイト:小数部(2の32乗で割ることで小数に変換)

4. NTP時刻をLabVIEW Timestampに変換

NTP時刻をLabVIEWのTimestampに変換するには、以下の式を使用します:

  • UNIX秒 = NTP秒 − 2208988800
  • LabVIEW Timestamp = UNIX秒 + 2082844800
  • よって:LabVIEW Timestamp = NTP秒 − 126144000

スニペットのVIを使用することで、標準的なNTPサーバからタイムスタンプを取得できます。

Python で同じ操作を実行する場合のサンプルコードは次のとおりです。

import socket
import struct
import datetime

def get_ntp_time(ntp_server="10.152.4.60"):
    port = 123
    address = (ntp_server, port)
    msg = b'\x1b' + 47 * b'\0'

    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    client.settimeout(5)

    try:
        print(f"NTPリクエスト送信中 → {ntp_server}:{port}")
        client.sendto(msg, address)
        msg, _ = client.recvfrom(1024)
        print("応答受信")

        # NTP時刻を抽出
        t = struct.unpack("!12I", msg)[10]
        t -= 2208988800
        ntp_time = datetime.datetime.fromtimestamp(t).astimezone()
        print("NTP時刻(ローカル):", ntp_time)

        # ホスト名を逆引き
        try:
            hostname = socket.gethostbyaddr(ntp_server)[0]
            print("サーバー名(ホスト名):", hostname)
        except socket.herror:
            print("ホスト名が見つかりません(逆引き失敗)")

    except socket.timeout:
        print("タイムアウト:NTPサーバーから応答がありません")
    except Exception as e:
        print(f"エラー発生: {e}")
    finally:
        client.close()

get_ntp_time()