vb.net time sync ntp

vb.net - Sincronizar el tiempo de Internet con la computadora



time sync (1)

Así que estoy haciendo un programa que tiene una función de verificación de licencia. Este programa solo se aplica a una cantidad limitada de personas de confianza (por lo que sé que no tratarán de alterarlo)

Lo que quiero hacer es sincronizar el reloj de las computadoras con un horario de Internet (como time.windows.com o lo que sea de confianza) y si el reloj de las computadoras no coincide con las redes internas, cambie el reloj de las computadoras para que coincida.

Sé que hay NTP pero no hay muchos proyectos en VB.NET (solo encontré una fuente pero está rota y mal, intenté arreglarla pero solo perdí tiempo)

Lo que también me preocupa es si puede coincidir con la zona horaria de los usuarios. Estoy tratando de ver si mi programa puede obtener la zona horaria dependiendo de su IP ya que escuché que NTP no es compatible con la Zona Horaria y el horario de verano.

¿Alguna buena forma de encontrar esto?


Recientemente tuve un problema con una batería de rtc baja y tuve que actualizar la fecha y la hora en XP. Primero encontré esta clase:

Imports System.IO Imports System.Net Imports System.Net.Sockets Imports System.Runtime.InteropServices Public Class Daytime ''Internet Time Server class by Alastair Dallas 01/27/04 ''Added a ''ping'' trap to query each server before trying to open the stream. ''This led to greatly improved speed. '' From: To: '' For Each host In Servers For Each host In Servers '' result = GetNISTTime(host) If My.Computer.Network.Ping(host) Then '' If result > DateTime.MinValue Then LastHost = host '' LastHost = host result = GetNISTTime(host) '' Exit For End If '' End If '' Next Next ''Since the ping says the server is active I removed the conditional statement ''and assigned host to lasthost after a successful ping ''I also adjusted the ''THRESHOLD_SECONDS'' to 3 ''In ''GetNISTTime'' I kept getting argument exceptions if ''timestr'' was still null after the Try loop ''so I added this after the Try loop: '' If timeStr = "" Then '' Return DateTime.MinValue '' End If ''Also updated server url. ''Lloyd Folden 01/16/12 Private Const THRESHOLD_SECONDS As Integer = 3 ''Number of seconds '' that Windows clock can deviate from NIST and still be okay ''Server IP addresses from ''http://tf.nist.gov/tf-cgi/servers.cgi - current as of 04/16/12 Private Shared Servers() As String = { _ "129.6.15.28" _ , "129.6.15.29" _ , "132.163.4.101" _ , "132.163.4.102" _ , "132.163.4.103" _ , "128.138.140.44" _ , "192.43.244.18" _ , "131.107.1.10" _ , "66.243.43.21" _ , "216.200.93.8" _ , "208.184.49.9" _ , "207.126.98.204" _ , "205.188.185.33" _ } Public Shared LastHost As String = "" Public Shared LastSysTime As DateTime Public Shared Function GetTime() As DateTime ''Returns UTC/GMT using an NIST server if possible, '' degrading to simply returning the system clock ''If we are successful in getting NIST time, then '' LastHost indicates which server was used and '' LastSysTime contains the system time of the call '' If LastSysTime is not within 15 seconds of NIST time, '' the system clock may need to be reset '' If LastHost is "", time is equal to system clock Dim host As String Dim result As DateTime LastHost = "" For Each host In Servers If My.Computer.Network.Ping(host) Then LastHost = host result = GetNISTTime(host) End If Next If LastHost = "" Then ''No server in list was successful so use system time result = DateTime.UtcNow() End If Return result End Function Public Shared Function SecondsDifference(ByVal dt1 As DateTime, ByVal dt2 As DateTime) As Integer Dim span As TimeSpan = dt1.Subtract(dt2) Return span.Seconds + (span.Minutes * 60) + (span.Hours * 360) End Function Public Shared Function WindowsClockIncorrect() As Boolean Dim nist As DateTime = GetTime() If (Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS) Then Return True End If Return False End Function Private Shared Function GetNISTTime(ByVal host As String) As DateTime ''Returns DateTime.MinValue if host unreachable or does not produce time Dim timeStr As String Try Dim reader As New StreamReader(New TcpClient(host, 13).GetStream) LastSysTime = DateTime.UtcNow() timeStr = reader.ReadToEnd reader.Close() Catch ex As SocketException ''Couldn''t connect to server, transmission error Debug.WriteLine("Socket Exception [" & host & "]") Return DateTime.MinValue Catch ex As Exception ''Some other error, such as Stream under/overflow Return DateTime.MinValue End Try If timeStr = "" Then Return DateTime.MinValue End If ''Parse timeStr If (timeStr.Substring(38, 9) <> "UTC(NIST)") Then ''This signature should be there Return DateTime.MinValue End If If (timeStr.Substring(30, 1) <> "0") Then ''Server reports non-optimum status, time off by as much as 5 seconds Return DateTime.MinValue ''Try a different server End If Dim jd As Integer = Integer.Parse(timeStr.Substring(1, 5)) Dim yr As Integer = Integer.Parse(timeStr.Substring(7, 2)) Dim mo As Integer = Integer.Parse(timeStr.Substring(10, 2)) Dim dy As Integer = Integer.Parse(timeStr.Substring(13, 2)) Dim hr As Integer = Integer.Parse(timeStr.Substring(16, 2)) Dim mm As Integer = Integer.Parse(timeStr.Substring(19, 2)) Dim sc As Integer = Integer.Parse(timeStr.Substring(22, 2)) If (jd < 15020) Then ''Date is before 1900 Return DateTime.MinValue End If If (jd > 51544) Then yr += 2000 Else yr += 1900 Return New DateTime(yr, mo, dy, hr, mm, sc) End Function <StructLayout(LayoutKind.Sequential)> _ Public Structure SYSTEMTIME Public wYear As Int16 Public wMonth As Int16 Public wDayOfWeek As Int16 Public wDay As Int16 Public wHour As Int16 Public wMinute As Int16 Public wSecond As Int16 Public wMilliseconds As Int16 End Structure Private Declare Function GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Private Declare Function SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32 Public Shared Sub SetWindowsClock(ByVal dt As DateTime) ''Sets system time. Note: Use UTC time; Windows will apply time zone Dim timeStru As SYSTEMTIME Dim result As Int32 timeStru.wYear = CType(dt.Year, Int16) timeStru.wMonth = CType(dt.Month, Int16) timeStru.wDay = CType(dt.Day, Int16) timeStru.wDayOfWeek = CType(dt.DayOfWeek, Int16) timeStru.wHour = CType(dt.Hour, Int16) timeStru.wMinute = CType(dt.Minute, Int16) timeStru.wSecond = CType(dt.Second, Int16) timeStru.wMilliseconds = CType(dt.Millisecond, Int16) result = SetSystemTime(timeStru) End Sub End Class

Luego usé un formulario con un cuadro de texto multilínea y 2 botones, con este código:

Public Class Form1 Dim DateTimeNow As DateTime Dim Args(1) As String Private Sub btnGetDateTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetDateTime.Click DateTimeNow = Daytime.GetTime + DateTimeOffset.Now.Offset txtDisplayInfo.AppendText(DateTimeNow.ToString + vbNewLine) End Sub Private Sub btnSetDateTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetDateTime.Click Daytime.SetWindowsClock(Daytime.GetTime) txtDisplayInfo.AppendText(DateTime.Now.ToString + vbNewLine) End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Args = Environment.GetCommandLineArgs If Args.Last = "-settime" Then DateTimeNow = Daytime.GetTime If DateTimeNow.ToShortDateString <> DateString Then Daytime.SetWindowsClock(Daytime.GetTime) End If Me.Close() End If End Sub End Class

Para ajustar la fecha y la hora de Windows a la actual a través de Internet. Por algún motivo, XP no corregía la fecha y la hora, así que lo necesitaba hasta que pudiera cambiar la batería de rtc. Es posible que puedas usar esto. De acuerdo con los comentarios del autor de la clase que utilicé. Windows ajustará automáticamente la hora de la zona horaria si usa la hora UTC.