所以我正在制作一个具有许可证检查功能的程序。这个程序只适用于受信任的有限数量的人(所以我知道他们不会试图篡改它)
我想要做的是将计算机时钟与互联网时间同步(如time.windows.com或任何可信任的东西),如果计算机时钟与互联网不匹配,请更改计算机时钟以匹配它。
我知道这是NTP但是在VB.NET中没有多少项目(我发现只有一个来源,但它已经破碎并搞砸了,尝试修复它但只浪费了时间)
我还担心的是它是否能够与用户时区相匹配。我试图看看我的程序是否可以根据他们的IP获得时区,因为我听说NTP不支持时区和夏令时。
有什么好方法可以解决这个问题吗?
答案 0 :(得分:0)
我最近遇到了低rtc电池的问题,不得不在XP中更新日期和时间。首先我发现了这个课程:
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
然后我使用带有多行文本框和2个按钮的表单,使用以下代码:
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
通过互联网将窗口日期和时间调整为当前日期和时间。由于某种原因XP不会纠正日期和时间,所以我需要这个,直到我可以改变rtc电池。你也许可以使用它。根据我使用的班级作者的评论。如果您使用UTC时间,Windows将自动调整时区的时间。