NonSoft

NTPサーバの現在日時をシステム時計に
設定するサンプル(VB.NET)


 サンプル(ソース/コード)
NTPサーバから受信した正確な現在日時をシステム時計に設定するサンプル(VB.NET)です。

パソコンの時計が狂っていると色々な問題が発生するので常に正確な日時を設定すべきです。

このサンプルは、スタートアップやタイマスケジューラで起動する現在日時設定ツールを
作る際の参考になると思います。

このサンプルは、NTPサーバとしてtime.windows.com(ポート番号:123)を使用しています。

C#.NETのサンプルはこちらです。
NTPサーバの現在日時をシステム時計に設定するサンプル(C#.NET)

その他のサンプルソースはこちらです。
サンプルソース

★フォームモジュール(Form1.vb)
Public Class Form1
    ' システム時計の日時設定APIの引数
    <System.Runtime.InteropServices.StructLayout( _
     System.Runtime.InteropServices.LayoutKind.Sequential)> _
    Public Structure SystemTime
        Public wYear As Short
        Public wMonth As Short
        Public wDayOfWeek As Short
        Public wDay As Short
        Public wHour As Short
        Public wMinute As Short
        Public wSecond As Short
        Public wMiliseconds As Short
    End Structure

    ' システム時計の日時設定APIの定義
    <System.Runtime.InteropServices.DllImport("kernel32.dll")> _
    Public Shared Function SetLocalTime(ByRef sysTime As SystemTime) As Boolean
    End Function

    Private Sub Button1_Click( _
        ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ' NTPサーバへの接続用UDP生成
        Dim objSck As System.Net.Sockets.UdpClient
        Dim ipAny As System.Net.IPEndPoint = _
            New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
        objSck = New System.Net.Sockets.UdpClient(ipAny)

        ' NTPサーバへのリクエスト送信
        Dim sdat As Byte() = New Byte(47) {}
        sdat(0) = &HB
        objSck.Send(sdat, sdat.GetLength(0), "time.windows.com", 123)

        ' NTPサーバから日時データ受信
        Dim rdat As Byte() = objSck.Receive(ipAny)

        ' 1900年1月1日からの経過時間(日時分秒)
        Dim lngAllS As Long ' 1900年1月1日からの経過秒数
        Dim lngD As Long    ' 日
        Dim lngH As Long    ' 時
        Dim lngM As Long    ' 分
        Dim lngS As Long    ' 秒

        ' 1900年1月1日からの経過秒数計算
        lngAllS = CLng( _
                  rdat(40) * Math.Pow(2, (8 * 3)) + _
                  rdat(41) * Math.Pow(2, (8 * 2)) + _
                  rdat(42) * Math.Pow(2, (8 * 1)) + _
                  rdat(43))

        ' 1900年1月1日からの経過(日時分秒)計算
        lngD = lngAllS \ (24 * 60 * 60)   ' 日
        lngS = lngAllS Mod (24 * 60 * 60) ' 残りの秒数
        lngH = lngS \ (60 * 60)           ' 時
        lngS = lngS Mod (60 * 60)         ' 残りの秒数
        lngM = lngS \ 60                  ' 分
        lngS = lngS Mod 60                ' 秒

        ' 現在の日時(DateTime)計算
        Dim dtTime As DateTime = "1900/01/01"
        dtTime = dtTime.AddDays(lngD)
        dtTime = dtTime.AddHours(lngH)
        dtTime = dtTime.AddMinutes(lngM)
        dtTime = dtTime.AddSeconds(lngS)

        ' グリニッジ標準時から日本時間への変更
        dtTime = dtTime.AddHours(9)

        ' 現在の日時表示
        System.Diagnostics.Trace.WriteLine(dtTime)

        ' システム時計の日時設定
        SetSysTime(dtTime)
    End Sub

    ' システム時計の日時設定
    Private Sub SetSysTime(ByVal dtm As DateTime)
        Dim sTime As New SystemTime
        sTime.wYear = dtm.Year
        sTime.wMonth = dtm.Month
        sTime.wDay = dtm.Day
        sTime.wHour = dtm.Hour
        sTime.wMinute = dtm.Minute
        sTime.wSecond = dtm.Second
        sTime.wMiliseconds = dtm.Millisecond
        SetLocalTime(sTime)
    End Sub
End Class