与计算机同步互联网时间 [英] Sync Internet Time with Computer

查看:40
本文介绍了与计算机同步互联网时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在制作一个具有许可证检查功能的程序.这个程序只适用于有限数量的受信任的人(所以我知道他们不会试图篡改它)

我想要做的是将计算机时钟与互联网时间(例如 time.windows.com 或任何可信任的)同步,如果计算机时钟与互联网不匹配,请更改计算机时钟以匹配它.

我知道有 NTP,但 VB.NET 中的项目并不多(我只找到了一个源,但它已损坏且混乱,尝试修复它但只是浪费时间)

我还担心的是它是否可以匹配用户的时区.我想看看我的程序是否可以根据他们的 IP 获取时区,因为我听说 NTP 不支持时区和夏令时.

遇到这种情况有什么好方法吗?

解决方案

我最近遇到了 rtc 电池电量不足的问题,不得不在 XP 中更新日期和时间.首先我找到了这个类:

导入 System.IO进口 System.Net导入 System.Net.Sockets导入 System.Runtime.InteropServices公开课白天'互联网时间服务器课程由阿拉斯泰尔达拉斯 01/27/04'在尝试打开流之前添加了'ping'陷阱以查询每个服务器.'这大大提高了速度.'  从到:' 对于服务器中的每个主机 对于服务器中的每个主机' result = GetNISTTime(host) If My.Computer.Network.Ping(host) Then' 如果结果 >DateTime.MinValue 然后 LastHost = 主机' LastHost = 主机结果 = GetNISTTime(host)' 退出结束如果'            万一' 下一个 下一个'由于 ping 表示服务器处于活动状态,因此我删除了条件语句'并在成功 ping 后将主机分配给 lasthost'我还将'THRESHOLD_SECONDS'调整为3'在'GetNISTTime'中,如果'timestr'在Try循环后仍然为空,我会不断收到参数异常'所以我在 Try 循环之后添加了这个:' 如果 timeStr = "" 那么' 返回日期时间.MinValue'               万一'还更新了服务器网址.'劳埃德·福尔登 01/16/12Private Const THRESHOLD_SECONDS As Integer = 3 '秒数' Windows 时钟可以偏离 NIST 并且仍然可以'服务器IP地址来自'http://tf.nist.gov/tf-cgi/servers.cgi - 截止 12 年 4 月 16 日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" _}公共共享 LastHost As String = ""公共共享 LastSysTime 作为日期时间公共共享函数 GetTime() As DateTime'如果可能,使用 NIST 服务器返回 UTC/GMT,' 降级为简单地返回系统时钟'如果我们成功获得 NIST 时间,那么' LastHost 指示使用的服务器和' LastSysTime 包含调用的系统时间' 如果 LastSysTime 不在 NIST 时间的 15 秒内,' 系统时钟可能需要重置' 如果 LastHost 为 "",则时间等于系统时钟Dim 主机作为字符串将结果调暗为日期时间LastHost = ""对于服务器中的每个主机如果 My.Computer.Network.Ping(host) 那么LastHost = 主机结果 = GetNISTTime(host)万一下一个如果 LastHost = "" 那么'列表中没有服务器成功所以使用系统时间结果 = DateTime.UtcNow()万一返回结果结束函数公共共享函数 SecondsDifference(ByVal dt1 As DateTime, ByVal dt2 As DateTime) As IntegerDim span As TimeSpan = dt1.Subtract(dt2)返回span.Seconds + (span.Minutes * 60) + (span.Hours * 360)结束函数公共共享函数 WindowsClockIncorrect() As BooleanDim nist As DateTime = GetTime()如果 (Math.Abs​​(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS) 那么返回真万一返回错误结束函数私有共享函数 GetNISTTime(ByVal host As String) As DateTime'如果主机无法访问或不产生时间,则返回 DateTime.MinValueDim timeStr As String尝试Dim reader As New StreamReader(New TcpClient(host, 13).GetStream)LastSysTime = DateTime.UtcNow()timeStr = reader.ReadToEnd读者.关闭()将 ex 作为 SocketException 捕获'无法连接到服务器,传输错误Debug.WriteLine("Socket Exception [" & host & "]")返回日期时间.MinValueCatch ex 作为例外'其他一些错误,例如流下/溢出返回日期时间.MinValue结束尝试如果 timeStr = "" 那么返回日期时间.MinValue万一'解析时间Str如果 (timeStr.Substring(38, 9) <> "UTC(NIST)") 然后'这个签名应该在那里返回日期时间.MinValue万一如果 (timeStr.Substring(30, 1) <> "0") 然后'服务器报告非最佳状态,暂停时间多达 5 秒Return DateTime.MinValue '尝试不同的服务器万一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))如果 (jd <15020) 那么'日期在 1900 年之前返回日期时间.MinValue万一如果 (jd > 51544) 那么 yr += 2000 否则 yr += 1900返回新的日期时间(yr, mo, dy, hr, mm, sc)结束函数<StructLayout(LayoutKind.Sequential)>_公共结构 SYSTEMTIME公共年度作为 Int16公共 wMonth As Int16公共 wDayOfWeek 作为 Int16公共 wDay 作为 Int16公共工作时间作为 Int16公共 wMinute 作为 Int16公共 wSecon 作为 Int16公共 wMilliseconds As Int16端部结构私有声明函数 GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32私有声明函数 SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32Public Shared Sub SetWindowsClock(ByVal dt As DateTime)'设置系统时间.注意:使用UTC时间;Windows 将应用时区Dim timeStru As SYSTEMTIMEDim 结果为 Int32timeStru.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)结果 = SetSystemTime(timeStru)结束子结束类

然后我使用了一个带有多行文本框和 2 个按钮的表单,代码如下:

公共类Form1将 DateTimeNow 调暗为 DateTimeDim Args(1) 作为字符串Private Sub btnGetDateTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 处理 btnGetDateTime.ClickDateTimeNow = Daytime.GetTime + DateTimeOffset.Now.OffsettxtDisplayInfo.AppendText(DateTimeNow.ToString + vbNewLine)结束子Private Sub btnSetDateTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 处理 btnSetDateTime.ClickDaytime.SetWindowsClock(Daytime.GetTime)txtDisplayInfo.AppendText(DateTime.Now.ToString + vbNewLine)结束子Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) 处理 Me.LoadArgs = Environment.GetCommandLineArgs如果 Args.Last = "-settime" 然后DateTimeNow = Daytime.GetTime如果 DateTimeNow.ToShortDateString <>日期字符串然后Daytime.SetWindowsClock(Daytime.GetTime)万一我.Close()万一结束子结束类

通过 Internet 将 Windows 日期和时间调整为当前的日期和时间.出于某种原因,XP 不会更正日期和时间,所以我需要这个,直到我可以更换 rtc 电池.你也许可以使用这个.根据我使用的课程作者的评论.如果您使用 UTC 时间,Windows 将自动调整时区时间.

So im making a program that does have a license checking feature. This program only goes to a limited amount of people that are trusted (so I know they wont try to tamper with it)

What I want to do is sync the computers clock with a internet time (like time.windows.com or whatever is trusted) and if the computers clock does not match the internets, change the computers clock to match it.

I know theres NTP but theres not much projects that are in VB.NET (only one source i found but its broken and messed up, tried fixing it but only wasted time)

What im also worried about is if it can match the users Time Zone. Im trying to see if my program can get the time zone depending on their IP since I heard NTP does not support Time Zone and daylight savings.

Any good way to come across this?

解决方案

I recently had a problem with a low rtc battery and had to update the date and time in XP. First I found this class:

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

Then I used a form with a multiline textbox and 2 buttons, with this code:

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

To adjust windows date and time to the current one over the internet. For some reason XP wouldn't correct date and time, so I needed this until I could change the rtc battery. You might be able to use this. According to the comments from author of the class I used. Windows will automatically adjust the time for time zone if you use UTC time.

这篇关于与计算机同步互联网时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆