Jump to content

Is there a way to get time online? Because the times on the computer are subject to change


Recommended Posts

Here's an example, tweaked from this source: https://www.autoitscript.com/forum/topic/144389-solved-autoit-function-to-pull-from-ntp/?do=findComment&comment=1018104

#include <Date.au3>

_GetTimeFromNTP("pool.ntp.org")

Func _GetTimeFromNTP($sNTPServer)
    Local $sData = ""
    TCPStartup()
    If TCPNameToIP($sNTPServer) = "" Then Return SetError(1)
    UDPStartup()
    $aSocket = UDPOpen(TCPNameToIP($sNTPServer), 123)
    $sStatus = UDPSend($aSocket, _MakePacket())
    While $sData = ""
        $sData = UDPRecv($aSocket, 100)
        Sleep(250)
    WEnd
    UDPCloseSocket($aSocket)
    TCPShutdown()
    $sValue = _UnsignedHexToDecimal(StringMid($sData, 83, 8))
    $aTimeZone = _Date_Time_GetTimeZoneInformation()
    $sUTC = _DateAdd("s", $sValue, "1900/01/01 00:00:00")
    If $aTimeZone[0] <> 2 Then
        $iTimeZoneOffset = ($aTimeZone[1]) * -1
    Else
        $iTimeZoneOffset = ($aTimeZone[1] + $aTimeZone[7]) * -1
    EndIf
    $sLocalTime = _DateAdd("n", $iTimeZoneOffset, $sUTC)
    ConsoleWrite($sLocalTime & @CRLF)
EndFunc

Func _MakePacket()
    Local $x, $sPacket = "1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    While $sPacket
        $x &= Chr(Dec(StringLeft($sPacket, 2)))
        $sPacket = StringTrimLeft($sPacket, 2)
    WEnd
    Return $x
EndFunc

Func _UnsignedHexToDecimal($sInput)
    $x = StringRight($sInput, 1)
    $sInput = StringTrimRight($sInput, 1)
    Return Dec($sInput) * 16 + Dec($x)
EndFunc

 

Link to post
Share on other sites

Here a simple way :

#include <Constants.au3>

Local $String = BinaryToString(InetRead ("http://worldtimeapi.org/api/timezone/America/Toronto.txt",1))
;MsgBox (0,"",$String)
;Local $String = BinaryToString(InetRead ( "http://worldtimeapi.org/api/timezone/Europe/Amsterdam",1))
Local $Time = StringRegExp ($String,'datetime: (.+?)T(\d+:\d+:\d+)', $STR_REGEXPARRAYMATCH)
MsgBox ($MB_SYSTEMMODAL,"",$Time[0] & " " & $Time[1])

 

Link to post
Share on other sites
1 hour ago, MrRow said:

it can be greater than or equal to

You could use :

If $Time[0] >= '2020-09-01' Then

But it is not the most robust approach, I would prefer using something like :

#include <Constants.au3>
#include <Date.au3>

Local $String = BinaryToString(InetRead ("http://worldtimeapi.org/api/timezone/America/Toronto.txt",1))
;MsgBox (0,"",$String)
;Local $String = BinaryToString(InetRead ( "http://worldtimeapi.org/api/timezone/Europe/Amsterdam",1))
Local $Time = StringRegExp ($String,'datetime: (.+?)T(\d+:\d+:\d+)', $STR_REGEXPARRAYMATCH)
MsgBox ($MB_SYSTEMMODAL,"",$Time[0] & " " & $Time[1])

Local $iDiff = _DateDiff ('D',"2020/09/01", StringReplace($time[0],"-","/"))
If @error Then Exit MsgBox ($MB_SYSTEMMODAL,"Error","Invalid date format")
If $iDiff >= 0 Then Exit MsgBox ($MB_SYSTEMMODAL,"Out of Date","Please renew your license")

 

Edited by Nine
Link to post
Share on other sites
On 9/1/2020 at 6:57 PM, Nine said:

Here a simple way :

#include <Constants.au3>

Local $String = BinaryToString(InetRead ("http://worldtimeapi.org/api/timezone/America/Toronto.txt",1))
;MsgBox (0,"",$String)
;Local $String = BinaryToString(InetRead ( "http://worldtimeapi.org/api/timezone/Europe/Amsterdam",1))
Local $Time = StringRegExp ($String,'datetime: (.+?)T(\d+:\d+:\d+)', $STR_REGEXPARRAYMATCH)
MsgBox ($MB_SYSTEMMODAL,"",$Time[0] & " " & $Time[1])

 

Edited by Loc
Link to post
Share on other sites

why not let os sync with time servers? then just read systemdate?

see if you can use the site below to read the time somehow. edit: they do have an api service but it costs money.

https://www.timeanddate.com/worldclock/vietnam/hanoi

 

anyway, if you can get reliable GMT time, yours is Indochina time GMT+7 hours so add 7 hours to GMT that you get back via api calls

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to post
Share on other sites

@Earthshine
Seems that both Indochina and Vietnam are not present in the list of all the timezones supported by the website.
Perhaps, since Vietnam is GMT+7, he could use a city that has a GMT+7 time too, or use the public IP to determine the time zone :)

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to post
Share on other sites

I think we need to see more code to understand how best to address this.  I imagine the time request from the internet will timeout, but how to deal with the failure in your script needs more information.  I am sure some logic can be implemented to ignore the internet time request failure.

Link to post
Share on other sites

here is my code

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>

GUICreate("Timer", 224, 152, 495, 132, $WS_POPUPWINDOW)
$Date = GUICtrlCreateLabel("", 50, 32, 120, 30)
GUICtrlSetFont(-1, 15, 800, 0, "MS Sans Serif")
$Timer = GUICtrlCreateLabel("", 60, 80, 100, 30)
GUICtrlSetFont(-1, 15, 800, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)

While 1
$Timer_Web = BinaryToString(InetRead ("http://worldtimeapi.org/api/timezone/ASIA/BANGKOK.txt",1))
$Timer_SetWeb = StringRegExp ($Timer_Web,'datetime: (.+?)T(\d+:\d+:\d+)', $STR_REGEXPARRAYMATCH)
If GUICtrlRead($Date) <> $Timer_SetWeb[0] Then GUICtrlSetData($Date,$Timer_SetWeb[0])
If GUICtrlRead($Timer) <> $Timer_SetWeb[1] Then GUICtrlSetData($timer,$Timer_SetWeb[1])
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

 

Link to post
Share on other sites
#Region - Includes and Initilization
#AutoIt3Wrapper_Change2CUI=Y
#include <Date.au3>
#EndRegion

_SyncTimeFromInternet("time1.google.com")


#Region - Command Line Parameter Execution/Logic
If @Compiled Then
    If $cmdline[0] Then ;Check for CMD Lime Parameters
        If StringInstr($cmdlineraw,"?") Then    ;Help
            ConsoleWrite(@CRLF & "Description:" & @CRLF & @TAB & "Displays system up time for local or remote machines." & @CRLF)
            ConsoleWrite(@CRLF & "Parameter List:" & @CRLF & @TAB & "/?" & @TAB & @TAB & @TAB & "Displays this help/usage." & @CRLF)
            ConsoleWrite(@CRLF & "Examples:" & @CRLF & @TAB & @ScriptName & @CRLF)
            ConsoleWrite(@TAB & @ScriptName & " hostname1 hostname2 hostname3" & @CRLF)
            Exit
        EndIf
        For $iX = 1 To $cmdline[0]  ;
            ConsoleWrite(StringUpper($cmdline[$iX]) & " " & _Uptime($cmdline[$iX])&@CRLF)
        Next
    Else
        ConsoleWrite(_Uptime() & @CRLF)
    EndIf
Else
    MsgBox(0,"Uptime:",_Uptime()&@CRLF)
EndIf
#EndRegion

#Region - Uptime Function (Main)
Func _Uptime($sComputer = @ComputerName)
    $iPing = Ping($sComputer,4000)
    If Not  $iPing Then Return "Failed to Reach"
    $oWMIService = ObjGet("winmgmts:\\" & $sComputer & "\root\cimv2")
    If Not IsObj($oWMIService) Then Return "Failed to Connect"

    $oColOperatingSystems = $oWMIService.ExecQuery("Select LastBootUpTime from Win32_OperatingSystem")
    For $oOS in $oColOperatingSystems
        Local $sBootup = $oOS.LastBootUpTime
        Local $sLastBootupTime = __WMIDateStringToDate($sBootup)
    Next

    $oColOperatingSystems = 0
    $oWMIService = 0

    Local $sUpTime = __FormatUptime($sLastBootupTime)
    Return "Last Boot: " & $sLastBootupTime & @CRLF & "Uptime: " & $sUpTime
EndFunc
#EndRegion

#Region - Internal Functions
Func __FormatUptime($sLastBootupTime)
    Local $aDateDiffs=[[0,24," day"],[0,60," hour"],[0,60," minute"],[0,1," second"]]
    Local $aDateDiff = StringSplit("D|h|n|s","|")
    Local $sNow = _NowCalc()
    For $sDiff = 1 to $aDateDiff[0]
        $aDateDiffs[$sDiff-1][0] = _DateDiff($aDateDiff[$sDiff], $sLastBootUpTime, $sNow)
    Next
    Local $iUbound = UBound($aDateDiffs)-1
    For $iX = $iUbound To 0 Step -1
        If $iX > 0 Then
            If $aDateDiffs[$iX-1][0] > 0 Then $aDateDiffs[$iX][0] = ($aDateDiffs[$iX][0]-($aDateDiffs[$iX-1][0]*$aDateDiffs[$iX-1][1]))
        EndIf
    Next
    Local $sUptime = ""
    For $iX = 0 To $iUbound
        If $aDateDiffs[$iX][0] > 0 Then
            $sUptime &= $aDateDiffs[$iX][0] & $aDateDiffs[$iX][2]
            If $aDateDiffs[$iX][0] > 1 Then $sUptime &= "s"
            If $iX < $iUbound Then $sUptime &= ", "
        EndIf
    Next
    Return $sUptime
EndFunc

Func __WMIDateStringToDate($sBootup)
    Return StringLeft($sBootup,4) & "/" & StringMid($sBootup, 5, 2) & "/" & StringMid($sBootup, 7, 2) & " " & StringMid($sBootup, 9, 2) & ":" & StringMid($sBootup, 11, 2) & ":" & StringMid($sBootup, 13, 2)
EndFunc
#EndRegion

Func _SyncTimeFromInternet($sNTPServer="time1.google.com")
    Local $sData = ""
    TCPStartup()
    If TCPNameToIP($sNTPServer) = "" Then Return SetError(1)
    UDPStartup()
    $aSocket = UDPOpen(TCPNameToIP($sNTPServer), 123)
    $sStatus = UDPSend($aSocket, _MakePacket())
    While $sData = ""
        $sData = UDPRecv($aSocket, 100)
        Sleep(250)
    WEnd
    UDPCloseSocket($aSocket)
    TCPShutdown()
    $sValue = _UnsignedHexToDecimal(StringMid($sData, 83, 8))
    $aTimeZone = _Date_Time_GetTimeZoneInformation()
    $sUTC = _DateAdd("s", $sValue, "1900/01/01 00:00:00")
    If $aTimeZone[0] <> 2 Then
        $iTimeZoneOffset = ($aTimeZone[1]) * -1
    Else
        $iTimeZoneOffset = ($aTimeZone[1] + $aTimeZone[7]) * -1
    EndIf
    Local $iMonth = StringMid($sUTC, 6, 2), $iDay = StringMid($sUTC, 9, 2), $iYear = StringMid($sUTC, 1, 4), _
    $iHour = StringMid($sUTC, 12, 2), $iMinute = StringMid($sUTC, 15, 2), $iSecond = StringMid($sUTC, 18, 2)
    ConsoleWrite("Time = " & $iMonth & " " & $iDay & " " & $iYear & " " & $iHour & " " & $iMinute & " " & $iSecond & @CR)
    $sCurrentTime = _Date_Time_EncodeSystemTime($iMonth, $iDay, $iYear, $iHour, $iMinute, $iSecond)
    _Date_Time_SetSystemTime(DllStructGetPtr($sCurrentTime))
EndFunc

Func _MakePacket()
    Local $x, $sPacket = "1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    While $sPacket
        $x &= Chr(Dec(StringLeft($sPacket, 2)))
        $sPacket = StringTrimLeft($sPacket, 2)
    WEnd
    Return $x
EndFunc

Func _UnsignedHexToDecimal($sInput)
    $x = StringRight($sInput, 1)
    $sInput = StringTrimRight($sInput, 1)
    Return Dec($sInput) * 16 + Dec($x)
EndFunc

Không biết có đúng ý bạn ko nữa

Regards,
 

Link to post
Share on other sites
55 minutes ago, VIP said:
#Region - Includes and Initilization
#AutoIt3Wrapper_Change2CUI=Y
#include <Date.au3>
#EndRegion

_SyncTimeFromInternet("time1.google.com")


#Region - Command Line Parameter Execution/Logic
If @Compiled Then
    If $cmdline[0] Then ;Check for CMD Lime Parameters
        If StringInstr($cmdlineraw,"?") Then    ;Help
            ConsoleWrite(@CRLF & "Description:" & @CRLF & @TAB & "Displays system up time for local or remote machines." & @CRLF)
            ConsoleWrite(@CRLF & "Parameter List:" & @CRLF & @TAB & "/?" & @TAB & @TAB & @TAB & "Displays this help/usage." & @CRLF)
            ConsoleWrite(@CRLF & "Examples:" & @CRLF & @TAB & @ScriptName & @CRLF)
            ConsoleWrite(@TAB & @ScriptName & " hostname1 hostname2 hostname3" & @CRLF)
            Exit
        EndIf
        For $iX = 1 To $cmdline[0]  ;
            ConsoleWrite(StringUpper($cmdline[$iX]) & " " & _Uptime($cmdline[$iX])&@CRLF)
        Next
    Else
        ConsoleWrite(_Uptime() & @CRLF)
    EndIf
Else
    MsgBox(0,"Uptime:",_Uptime()&@CRLF)
EndIf
#EndRegion

#Region - Uptime Function (Main)
Func _Uptime($sComputer = @ComputerName)
    $iPing = Ping($sComputer,4000)
    If Not  $iPing Then Return "Failed to Reach"
    $oWMIService = ObjGet("winmgmts:\\" & $sComputer & "\root\cimv2")
    If Not IsObj($oWMIService) Then Return "Failed to Connect"

    $oColOperatingSystems = $oWMIService.ExecQuery("Select LastBootUpTime from Win32_OperatingSystem")
    For $oOS in $oColOperatingSystems
        Local $sBootup = $oOS.LastBootUpTime
        Local $sLastBootupTime = __WMIDateStringToDate($sBootup)
    Next

    $oColOperatingSystems = 0
    $oWMIService = 0

    Local $sUpTime = __FormatUptime($sLastBootupTime)
    Return "Last Boot: " & $sLastBootupTime & @CRLF & "Uptime: " & $sUpTime
EndFunc
#EndRegion

#Region - Internal Functions
Func __FormatUptime($sLastBootupTime)
    Local $aDateDiffs=[[0,24," day"],[0,60," hour"],[0,60," minute"],[0,1," second"]]
    Local $aDateDiff = StringSplit("D|h|n|s","|")
    Local $sNow = _NowCalc()
    For $sDiff = 1 to $aDateDiff[0]
        $aDateDiffs[$sDiff-1][0] = _DateDiff($aDateDiff[$sDiff], $sLastBootUpTime, $sNow)
    Next
    Local $iUbound = UBound($aDateDiffs)-1
    For $iX = $iUbound To 0 Step -1
        If $iX > 0 Then
            If $aDateDiffs[$iX-1][0] > 0 Then $aDateDiffs[$iX][0] = ($aDateDiffs[$iX][0]-($aDateDiffs[$iX-1][0]*$aDateDiffs[$iX-1][1]))
        EndIf
    Next
    Local $sUptime = ""
    For $iX = 0 To $iUbound
        If $aDateDiffs[$iX][0] > 0 Then
            $sUptime &= $aDateDiffs[$iX][0] & $aDateDiffs[$iX][2]
            If $aDateDiffs[$iX][0] > 1 Then $sUptime &= "s"
            If $iX < $iUbound Then $sUptime &= ", "
        EndIf
    Next
    Return $sUptime
EndFunc

Func __WMIDateStringToDate($sBootup)
    Return StringLeft($sBootup,4) & "/" & StringMid($sBootup, 5, 2) & "/" & StringMid($sBootup, 7, 2) & " " & StringMid($sBootup, 9, 2) & ":" & StringMid($sBootup, 11, 2) & ":" & StringMid($sBootup, 13, 2)
EndFunc
#EndRegion

Func _SyncTimeFromInternet($sNTPServer="time1.google.com")
    Local $sData = ""
    TCPStartup()
    If TCPNameToIP($sNTPServer) = "" Then Return SetError(1)
    UDPStartup()
    $aSocket = UDPOpen(TCPNameToIP($sNTPServer), 123)
    $sStatus = UDPSend($aSocket, _MakePacket())
    While $sData = ""
        $sData = UDPRecv($aSocket, 100)
        Sleep(250)
    WEnd
    UDPCloseSocket($aSocket)
    TCPShutdown()
    $sValue = _UnsignedHexToDecimal(StringMid($sData, 83, 8))
    $aTimeZone = _Date_Time_GetTimeZoneInformation()
    $sUTC = _DateAdd("s", $sValue, "1900/01/01 00:00:00")
    If $aTimeZone[0] <> 2 Then
        $iTimeZoneOffset = ($aTimeZone[1]) * -1
    Else
        $iTimeZoneOffset = ($aTimeZone[1] + $aTimeZone[7]) * -1
    EndIf
    Local $iMonth = StringMid($sUTC, 6, 2), $iDay = StringMid($sUTC, 9, 2), $iYear = StringMid($sUTC, 1, 4), _
    $iHour = StringMid($sUTC, 12, 2), $iMinute = StringMid($sUTC, 15, 2), $iSecond = StringMid($sUTC, 18, 2)
    ConsoleWrite("Time = " & $iMonth & " " & $iDay & " " & $iYear & " " & $iHour & " " & $iMinute & " " & $iSecond & @CR)
    $sCurrentTime = _Date_Time_EncodeSystemTime($iMonth, $iDay, $iYear, $iHour, $iMinute, $iSecond)
    _Date_Time_SetSystemTime(DllStructGetPtr($sCurrentTime))
EndFunc

Func _MakePacket()
    Local $x, $sPacket = "1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    While $sPacket
        $x &= Chr(Dec(StringLeft($sPacket, 2)))
        $sPacket = StringTrimLeft($sPacket, 2)
    WEnd
    Return $x
EndFunc

Func _UnsignedHexToDecimal($sInput)
    $x = StringRight($sInput, 1)
    $sInput = StringTrimRight($sInput, 1)
    Return Dec($sInput) * 16 + Dec($x)
EndFunc

Không biết có đúng ý bạn ko nữa

thanks for helping me, i got the exact time from @Nine. Now I am looking to fix the no network connection error

Link to post
Share on other sites
ipconfig /release
ipconfig /renew
ipconfig /flushdns
netsh winsock reset catalog
nbtstat -R
nbtstat -RR
netsh int ip reset D:\resetlog.txt
netsh winsock reset
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet /v EnableActiveProbing  /t REG_DWORD /d 0 /f

:::pause

Chuyển đổi mã bat này sang AutoIT hoặc lưu lại dưới dạng file BAT và chạy với quyền Admin. Xong thì khởi động lại là đc :v

Regards,
 

Link to post
Share on other sites

I can say I am pretty much sensitive to the accuracy of my computer clock and I put the following program in the Windows task scheduler to run every hour. I am quite confident that my clock always keeps time that is not off by more than 20 millisecs from the NTP time. I turned off Windows default time sync function.

;~ Many thanks to @TheXman for his kind assistance in getting the NTP time.
;~ https://www.autoitscript.com/forum/topic/200643-update-system-time-based-on-ntp-server-time/page/2/?tab=comments#comment-1439629

#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Constants.au3>
#include <Date.au3>
#include <Array.au3>
#include <File.au3>
#include <Misc.au3>

Global $hTimer = TimerInit(), $hPing
While 1
    $hPing = Ping("www.google.com", 200) ; Cloudflare.com
    If $hPing > 0 Then ExitLoop
    If TimerDiff($hTimer) > 120000 Then
        WriteLog("", "System has no internet connection")
        Exit
    EndIf
    Sleep(50)
WEnd

Global $tTime, $aTime, $Sys_Time, $aInfo
Global $NTP_Time, $iSeconds, $iFractions, $iMsecs, $hRoundTrip, $sError, $success

Global $tBuffer = DllStructCreate("byte[48]")
DllStructSetData($tBuffer, 1, 0x23) ; 00 100 011 = LI(0) / VN(4-NTPv4) / Mode(3-Client)

Global $xRequest = DllStructGetData($tBuffer, 1), $xResponse

UDPStartup()
OnAutoItExitRegister("udp_shutdown")

Global $NTP_Server = "pool.ntp.org"
Global $NTP_MaxDelay = 10   ; This may vary depending on your geolocation.
For $i = 1 To 10
    Main()
    If $success Then
        ExitLoop
    EndIf
    Sleep(1000)
Next

If $success = False Then
    $NTP_Server = "time.google.com"
    $NTP_MaxDelay = 150 ; This may vary depending on your geolocation.
    For $i = 1 To 10
        Main()
        If $success Then
            ExitLoop
        EndIf
        Sleep(1000)
    Next
EndIf

#cs
If your computer clock consistently runs faster or slower than the NTP time by more than 15 or so millisecs an hour,
you may like to use _Date_Time_SetSystemTimeAdjustment() function in Date.au3 to make your clock run more precisely.
In order to prevent $iAdjustment value from reverting to default, Windows default time update service must be
disabled by one of the following methods:
1. Turn off "Settings - Time and language - Date and time - Set time automatically"
2. Click off "Control panel - Date and time - Internet time - Synchronize with an internet time server"
#ce

$aInfo = _Date_Time_GetSystemTimeAdjustment()
Global $iAdjustment = $aInfo[1] ; 156250

$iAdjustment += 0   ; 1 in $iAdustment value represents 23.04 milsecs in 1 hour, 0.55296 second a day
; You can set this value after you have understood how fast or slow your clock runs from the log file.
If $aInfo[0] <> $iAdjustment Then
    _Date_Time_SetSystemTimeAdjustment($iAdjustment, False)
EndIf

If $success = False Then
    WriteLog(0, $sError)
    Exit
EndIf

System_SetTime()
WriteLog($NTP_Time, "")
Sleep(3000)


Func Main()
    Local $NTP_IP = TCPNameToIP($NTP_Server)
    If $NTP_IP <> "" Then
        Local $aSocket = UDPOpen($NTP_IP, 123)
        If $aSocket[0] <> 0 Then
            $NTP_Time = ""
            NTP_GetTime($aSocket)
            If $hRoundTrip < $NTP_MaxDelay And $NTP_Time <> "" Then
                $sError = ""
                $success = True
            Else
                $sError = "Response delay too long"
            EndIf
        EndIf
        UDPCloseSocket($aSocket)
    EndIf
EndFunc

Func System_SetTime()
    ; 2019/10/28 23:09:52.522
    ; 12345678901234567890123
    Local $m = StringMid($NTP_Time, 6, 2)
    Local $d = StringMid($NTP_Time, 9, 2)
    Local $y = StringMid($NTP_Time, 1, 4)
    Local $h = StringMid($NTP_Time, 12, 2)
    Local $min = StringMid($NTP_Time, 15, 2)
    Local $s = StringMid($NTP_Time, 18, 2)
    Local $tCurr = _Date_Time_EncodeSystemTime($m, $d, $y, $h, $min, $s, $iMsecs)
    ; stores the current system time for calculation of $hAdjustment in WriteLog() function
    $tTime = _Date_Time_GetSystemTime()
    ; Sets the new current time to the computer
    _Date_Time_SetSystemTime(DllStructGetPtr($tCurr))
EndFunc ;==>System_SetTime

Func NTP_GetTime($aSocket)
    $hTimer = TimerInit()
    UDPSend($aSocket, $xRequest)
    If @error Then
        $sError = "UDPSend failed"
        Return
    EndIf
    Do
        $xResponse = UDPRecv($aSocket, DllStructGetSize($tBuffer), $UDP_DATA_BINARY)
        If @error Then
            $sError = "UDPRecv failed"
            Return
        EndIf
    Until $xResponse <> ""
    $hRoundTrip = TimerDiff($hTimer)

    $iSeconds = Dec(Hex(BinaryMid($xResponse, 41, 4)), $NUMBER_64BIT) ; seconds since 1900-01-01 00:00:00
    $iFractions = Dec(Hex(BinaryMid($xResponse, 45, 4)), $NUMBER_64BIT) ; the maximum value is 0xFFFFFFFF, which represents 1 second
    $iMsecs = Round($iFractions/(2^32)*1000 + $hRoundTrip/2 + 1.5)
    If $iMsecs >= 1000 Then
        $iSeconds += Int($iMsecs/1000)
        $iMsecs = Mod($iMsecs, 1000)
    EndIf
    $iMsecs = StringFormat("%03d", $iMsecs)
    $NTP_Time = _DateAdd("s", $iSeconds, "1900/01/01 00:00:00")
EndFunc   ;==>NTP_GetTime

Func udp_shutdown()
    UDPShutdown()
EndFunc   ;==>udp_shutdown

Func _DateDiffMS($sType, $sStartDate, $sEndDate)
    Local $iDiff
    If $sType = "ms" Or $sType = "s" Then
        Local $sStartMS, $sEndMS, $iDiffSec
        If StringInStr($sStartDate, ".") Then
            $sStartMS = StringMid($sStartDate, StringInStr($sStartDate, "."), 5)*1000
            $sStartDate = StringLeft($sStartDate, StringInStr($sStartDate, ".")-1)
        EndIf
        If StringInStr($sEndDate, ".") Then
            $sEndMS = StringMid($sEndDate, StringInStr($sEndDate, "."), 5)*1000
            $sEndDate = StringLeft($sEndDate, StringInStr($sEndDate, ".")-1)
        EndIf
        $iDiffSec = _DateDiff("s", $sStartDate, $sEndDate)
        If @error Then Return SetError(@error, 0, 0)
        $iDiff = $iDiffSec*1000+Round($sEndMS-$sStartMS)
        If $sType = "s" Then
            $iDiff = StringFormat("%.3f", $iDiff/1000)
        EndIf
    Else
        If StringInStr($sStartDate, ".") Then
            $sStartDate = StringLeft($sStartDate, StringInStr($sStartDate, ".")-1)
        EndIf
        If StringInStr($sEndDate, ".") Then
            $sEndDate = StringLeft($sEndDate, StringInStr($sEndDate, ".")-1)
        EndIf
        $iDiff = _DateDiff($sType, $sStartDate, $sEndDate)
    EndIf
    Return SetError(@error, 0, $iDiff)
EndFunc

Func WriteLog($pTime, $sMessage)
    If $pTime = "" Then
        Local $fn = FileOpen(@ScriptDir & "\TimeSync Failed.log", 2)
        $pTime = _NowCalc() & @CRLF
        FileWrite($fn, $pTime & $sMessage & @CRLF)
        FileClose($fn)
    Else
        Local $aLog[1]
        If FileExists(@ScriptDir & "\TimeSync.log") Then
            _FileReadToArray(@ScriptDir & "\TimeSync.log", $aLog, 1)
            For $i = 1 To $aLog[0]-24
                _ArrayDelete($aLog, 1)
            Next
        EndIf

        FileDelete(@ScriptDir & "\TimeSync Failed.log")

        $aInfo = _Date_Time_GetTimeZoneInformation()
        Local $TZ_Offset = $aInfo[1]

        $aTime = _Date_Time_SystemTimeToArray($tTime)
        $Sys_Time = StringFormat("%04d/%02d/%02d %02d:%02d:%02d", $aTime[2], $aTime[0], $aTime[1], $aTime[3], $aTime[4], $aTime[5])
        $Sys_Time = _DateAdd("n", -$TZ_Offset, $Sys_Time) & StringFormat(".%03d", $aTime[6])

        $NTP_Time = _DateAdd("n", -$TZ_Offset, $NTP_Time) & "." & $iMsecs

        Local $hAdjustment = _DateDiffMS("s", $Sys_Time, $NTP_Time)
        If $hAdjustment >= 0 Then
            $hAdjustment = "+" & $hAdjustment
        EndIf

        If StringInStr($hRoundTrip, ".") Then
            $hRoundTrip = StringMid(Round(100+$hRoundTrip, 3) & "000", 2, 6)
        Else
            $hRoundTrip = StringMid(Round(100+$hRoundTrip, 3) & ".000", 2, 6)
        EndIf

        $pTime = $NTP_Time & " Adjustment: " & $hAdjustment & " second(s), NTP Response Time: " & $hRoundTrip & " milsecs"
        _ArrayAdd($aLog, $pTime)
        _FileWriteFromArray(@ScriptDir & "\TimeSync.log", $aLog, 1)
    EndIf
EndFunc   ;==>WriteLog

 

Edited by CYCho
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...