Jump to content

NTP C to Autoit conversvion


Recommended Posts

Hi there, I would like to convert this C source code to autoit.

I am not sure about this line though: unsigned char msg[48]={010,0,0,0,0,0,0,0,0}

What would this be in autoit?

$packet = ???

ie. the packet I would send using:

UDPSend($socket, $packet)

notes from below:

/*

* build a message. Our message is all zeros except for a one in the

* protocol version field

* msg[] in binary is 00 001 000 00000000

* it should be a total of 48 bytes long

*/

Thanks

/*

* This code will query a ntp server for the local time and display

* it. it is intended to show how to use a NTP server as a time

* source for a simple network connected device.

* This is the C version. The orignal was in Perl

*

* For better clock management see the offical NTP info at:

* http://www.eecis.udel.edu/~ntp/

*

* written by Tim Hogard (thogard@abnormal.com)

* Thu Sep 26 13:35:41 EAST 2002

* Converted to C Fri Feb 21 21:42:49 EAST 2003

* this code is in the public domain.

* it can be found here http://www.abnormal.com/~thogard/ntp/

*

*/

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

main() {

ntpdate();

}

ntpdate() {

char *hostname="203.50.77.6";

int portno=123; //NTP is port 123

int maxlen=1024; //check our buffers

int i; // misc var i

unsigned char msg[48]={010,0,0,0,0,0,0,0,0}; // the packet we send

unsigned long buf[maxlen]; // the buffer we get back

//struct in_addr ipaddr; //

struct protoent *proto; //

struct sockaddr_in server_addr;

int s; // socket

int tmit; // the time -- This is a time_t sort of

//use Socket;

//

//#we use the system call to open a UDP socket

//socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "socket: $!";

proto=getprotobyname("udp");

s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);

if(s) {

//perror("asd");

//printf("socket=%d\n",s);

}

//

//#convert hostname to ipaddress if needed

//$ipaddr = inet_aton($HOSTNAME);

memset( &server_addr, 0, sizeof( server_addr ));

server_addr.sin_family=AF_INET;

server_addr.sin_addr.s_addr = inet_addr(hostname);

//argv[1] );

//i = inet_aton(hostname,&server_addr.sin_addr);

server_addr.sin_port=htons(portno);

//printf("ipaddr (in hex): %x\n",server_addr.sin_addr);

/*

* build a message. Our message is all zeros except for a one in the

* protocol version field

* msg[] in binary is 00 001 000 00000000

* it should be a total of 48 bytes long

*/

// send the data

i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));

// get the data back

i=recv(s,buf,sizeof(buf),0);

//printf("recvfr: %d\n",i);

//perror("recvfr:");

//We get 12 long words back in Network order

/*

for(i=0;i<12;i++)

printf("%d\t%-8x\n",i,ntohl(buf));

*/

/*

* The high word of transmit time is the 10th word we get back

* tmit is the time in seconds not accounting for network delays which

* should be way less than a second if this is a local NTP server

*/

tmit=ntohl((time_t)buf[10]); //# get transmit time

//printf("tmit=%d\n",tmit);

/*

* Convert time to unix standard time NTP is number of seconds since 0000

* UT on 1 January 1900 unix time is seconds since 0000 UT on 1 January

* 1970 There has been a trend to add a 2 leap seconds every 3 years.

* Leap seconds are only an issue the last second of the month in June and

* December if you don't try to set the clock then it can be ignored but

* this is importaint to people who coordinate times with GPS clock sources.

*/

tmit-= 2208988800U;

//printf("tmit=%d\n",tmit);

/* use unix library function to show me the local time (it takes care

* of timezone issues for both north and south of the equator and places

* that do Summer time/ Daylight savings time.

*/

//#compare to system time

printf("Time: %s",ctime(&tmit));

i=time(0);

//printf("%d-%d=%d\n",i,tmit,i-tmit);

printf("System time is %d seconds off\n",i-tmit);

}

Link to comment
Share on other sites

  • 9 months later...

Ran across this post when looking for a way to simply pull the date and time from an NTP server. Couldn't find a good example so I wrote this. Seems to work ok.

#include <Date.au3>

$ntpServer="pool.ntp.org"

UDPStartup()
Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
If @error <> 0 Then
    MsgBox(0,"","Can't open connection!")
    Exit
EndIf
;$status = UDPSend($socket, MakePacket("1b0e010000000000000000004c4f434ccb1eea7b866665cb00000000000000000000000000000000cb1eea7b866665cb

"))
$status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

"))
If $status = 0 Then
    MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
    Exit
EndIf
$data=""
While $data=""
    $data = UDPRecv($socket, 100)
    sleep(100)
WEnd
UDPCloseSocket($socket)
UDPShutdown()

$unsignedHexValue=StringMid($data,83,8); Extract time from packet. Disregards the fractional second.
;MsgBox(0, "UDP DATA", $unsignedHexValue)

$value=UnsignedHexToDec($unsignedHexValue)
$TZinfo = _Date_Time_GetTimeZoneInformation()
$TZoffset=$TZinfo[1]*-1
$UTC=_DateAdd("s",$value,"1900/01/01 00:00:00")
MsgBox(0,"","Time from NTP Server UTC:  "&$UTC&@CRLF& _
                "Time from NTP Server Local Offset:  "&_DateAdd("n",$TZoffset,$UTC)&@CRLF& _
                "Time from Local Computer Clock:  "&_NowCalc())

;**************************************************************************************************
;** Fuctions **************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p=""
    While $d
        $p&=Chr(Dec(StringLeft($d,2)))
        $d=StringTrimLeft($d,2)
    WEnd
    Return $p
EndFunc
;**************************************************************************************************
Func UnsignedHexToDec($n)
    $ones=StringRight($n,1)
    $n=StringTrimRight($n,1)
    Return dec($n)*16+dec($ones)
EndFunc
;**************************************************************************************************
Link to comment
Share on other sites

  • 1 year later...

Hey All,

This is my first post to the forum but I've been around a long time and have written a couple AutoIT apps. I finally have something to contribute. Also, I realize that this is an old thread. Apologies in advanced.

I was utilizing the code above to create a simple NTP client GUI that I could use to test some of the time servers here at work. As I was playing around with the code above I found that some of the time reports were inaccurate due to it not properly taking into account Daylight Savings Time.

To correct the problem I've changed the $TZoffset=$TZinfo[1]*-1 line to:

$TZoffset= ($TZinfo[1] + $TZinfo[7]) * -1

This seems to handle the time changes. I've moved my PC in and out of Daylight Savings and it appears to adjust properly.

---

Also, on a side note. Is there a place I can help update some of the AutoIT documentation on the _Date_Time_GetTimeZoneInformation() function? I believe it is also inaccurate. It says that variables [3] and [6] give a date and time when the daylight savings starts/ends. I believe it is actually returning the month, and which Sunday the change occurs. For instance it reports that one of the changes occurs at 03/02/0000 00:02:00, which could be interpreted as March 2nd. It is actually indicating that it changes in March, on the 2nd Sunday (March 8th, 2009 this year).

Link to comment
Share on other sites

Also, on a side note. Is there a place I can help update some of the AutoIT documentation on the _Date_Time_GetTimeZoneInformation() function? I believe it is also inaccurate. It says that variables [3] and [6] give a date and time when the daylight savings starts/ends. I believe it is actually returning the month, and which Sunday the change occurs. For instance it reports that one of the changes occurs at 03/02/0000 00:02:00, which could be interpreted as March 2nd. It is actually indicating that it changes in March, on the 2nd Sunday (March 8th, 2009 this year).

Hello, yn0t. The BugTracker also deals with bugs and errors in the documentation. If you're unsure if a documentation is incorrect you can start a topic in General Help & Support first and ask for feedback.
Link to comment
Share on other sites

Bug report submitted (#1180).

Also, for those interested, I've taken the code above and created a "nice" GUI interface for it. I'm using it to test some time servers here at work with some simple NTP queries. It also fixes the Daylight Savings error I mentioned above and I've added a couple fields that could be helpful in troubleshooting the time servers.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>

$AppTitle = "NTP Client"
$AppVersion = "1.0"
$AppTitleVersion = $AppTitle & " v" & $AppVersion

#Region ### START Koda GUI section ###
$frmMain = GUICreate($AppTitleVersion, 498, 271, 239, 155)
$txtNTPServer = GUICtrlCreateInput("pool.ntp.org", 72, 8, 417, 21)
$Label1 = GUICtrlCreateLabel("NTP Server:", 8, 10, 63, 17)
$cmdQuery = GUICtrlCreateButton("Query", 416, 240, 75, 25, $WS_GROUP)
$grpNTPServer = GUICtrlCreateGroup("NTP Server", 8, 32, 481, 73)
$Label2 = GUICtrlCreateLabel("NTP Server UTC:", 48, 52, 88, 17)
$txtNTPServerUTC = GUICtrlCreateInput("", 136, 48, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtNTPServerLocalTime = GUICtrlCreateInput("", 136, 72, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$Label5 = GUICtrlCreateLabel("NTP Server Local Time:", 18, 76, 118, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$grpLocal = GUICtrlCreateGroup("Local Computer", 8, 112, 481, 121)
$Label3 = GUICtrlCreateLabel("Time Zone:", 73, 134, 58, 17)
$Label4 = GUICtrlCreateLabel("Offset (hours):", 61, 154, 70, 17)
$Label6 = GUICtrlCreateLabel("UTC Time:", 76, 177, 55, 17)
$txtTimeZone = GUICtrlCreateInput("", 136, 128, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtOffset = GUICtrlCreateInput("", 136, 152, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtLocalUTCTime = GUICtrlCreateInput("", 136, 176, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtLocalTime = GUICtrlCreateInput("", 136, 200, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$Label9 = GUICtrlCreateLabel("Local Time:", 72, 199, 59, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

;**************************************************************************************************
;** Functions *************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p=""
    While $d
        $p&=Chr(Dec(StringLeft($d,2)))
        $d=StringTrimLeft($d,2)
    WEnd
    Return $p
EndFunc

Func UnsignedHexToDec($n)
    $ones=StringRight($n,1)
    $n=StringTrimRight($n,1)
    Return dec($n)*16+dec($ones)
EndFunc

Func QueryNTP($ntpServer)
    UDPStartup()
    Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
    If @error <> 0 Then
        MsgBox(0,"","Can't open connection!")
        Return 0
    EndIf

    $status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))

    If $status = 0 Then
        MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
        Return 0
    EndIf
    $data=""
    While $data=""
        $data = UDPRecv($socket, 100)
        sleep(100)
    WEnd
    UDPCloseSocket($socket)
    UDPShutdown()

    $unsignedHexValue=StringMid($data,83,8) ; Extract time from packet. Disregards the fractional second.

    $value=UnsignedHexToDec($unsignedHexValue)
    $TZinfo = _Date_Time_GetTimeZoneInformation()
    $TZoffset= ($TZinfo[1] + $TZinfo[7]) * -1 
    $UTC=_DateAdd("s",$value,"1900/01/01 00:00:00")
    
    GUICtrlSetData($txtNTPServerUTC, $UTC)
    GUICtrlSetData($txtNTPServerLocalTime, _DateAdd("n",$TZoffset,$UTC))
    
    GUICtrlSetData($txtTimeZone, $TZinfo[5])
    GUICtrlSetData($txtOffset, $TZoffset / 60)
    GUICtrlSetData($txtLocalUTCTime, _DateAdd("n",$TZoffset * -1,_NowCalc()))
    GUICtrlSetData($txtLocalTime, _NowCalc())

EndFunc

Func CenterWindow($window_title)
    $position = WinGetPos($window_title)
    WinMove($window_title, "", (@desktopwidth / 2) - ($position[2] / 2), (@desktopheight / 2)  - ($position[3] / 2))
EndFunc

CenterWindow($AppTitleVersion)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $cmdQuery
            QueryNTP(GUICtrlRead($txtNTPServer))
        
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Edited by yn0t
Link to comment
Share on other sites

Bug report submitted (#1180).

Also, for those interested, I've taken the code above and created a "nice" GUI interface for it. I'm using it to test some time servers here at work with some simple NTP queries. It also fixes the Daylight Savings error I mentioned above and I've added a couple fields that could be helpful in troubleshooting the time servers.

After all that I found a bug in my code that didn't update the Time Zone field properly or the offset on a Daylight Savings change. This should take care of it.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>

$AppTitle = "NTP Client"
$AppVersion = "1.0"
$AppTitleVersion = $AppTitle & " v" & $AppVersion

#Region ### START Koda GUI section ###
$frmMain = GUICreate($AppTitleVersion, 498, 271, 239, 155)
$txtNTPServer = GUICtrlCreateInput("pool.ntp.org", 72, 8, 417, 21)
$Label1 = GUICtrlCreateLabel("NTP Server:", 8, 10, 63, 17)
$cmdQuery = GUICtrlCreateButton("Query", 416, 240, 75, 25, $WS_GROUP)
$grpNTPServer = GUICtrlCreateGroup("NTP Server", 8, 32, 481, 73)
$Label2 = GUICtrlCreateLabel("NTP Server UTC:", 48, 52, 88, 17)
$txtNTPServerUTC = GUICtrlCreateInput("", 136, 48, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtNTPServerLocalTime = GUICtrlCreateInput("", 136, 72, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$Label5 = GUICtrlCreateLabel("NTP Server Local Time:", 18, 76, 118, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$grpLocal = GUICtrlCreateGroup("Local Computer", 8, 112, 481, 121)
$Label3 = GUICtrlCreateLabel("Time Zone:", 73, 134, 58, 17)
$Label4 = GUICtrlCreateLabel("Offset (hours):", 61, 154, 70, 17)
$Label6 = GUICtrlCreateLabel("UTC Time:", 76, 177, 55, 17)
$txtTimeZone = GUICtrlCreateInput("", 136, 128, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtOffset = GUICtrlCreateInput("", 136, 152, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtLocalUTCTime = GUICtrlCreateInput("", 136, 176, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$txtLocalTime = GUICtrlCreateInput("", 136, 200, 345, 21, BitOR($ES_AUTOHSCROLL,$ES_READONLY))
$Label9 = GUICtrlCreateLabel("Local Time:", 72, 199, 59, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

;**************************************************************************************************
;** Functions *************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p=""
    While $d
        $p&=Chr(Dec(StringLeft($d,2)))
        $d=StringTrimLeft($d,2)
    WEnd
    Return $p
EndFunc

Func UnsignedHexToDec($n)
    $ones=StringRight($n,1)
    $n=StringTrimRight($n,1)
    Return dec($n)*16+dec($ones)
EndFunc

Func QueryNTP($ntpServer)
    UDPStartup()
    Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
    If @error <> 0 Then
        MsgBox(0,"","Can't open connection!")
        Return 0
    EndIf

    $status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))

    If $status = 0 Then
        MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
        Return 0
    EndIf
    $data=""
    While $data=""
        $data = UDPRecv($socket, 100)
        sleep(100)
    WEnd
    UDPCloseSocket($socket)
    UDPShutdown()

    $unsignedHexValue=StringMid($data,83,8) ; Extract time from packet. Disregards the fractional second.

    $value=UnsignedHexToDec($unsignedHexValue)
    $TZinfo = _Date_Time_GetTimeZoneInformation()
    ;msgbox(4096, "", $TZinfo[0])
    $UTC=_DateAdd("s",$value,"1900/01/01 00:00:00")
    
    Switch $TZinfo[0]
        Case 0  ;Daylight Savings not used in current time zone
            $TZoffset = 0
            $TimeZone = $TZinfo[2]
        Case 1 ;Standard Time
            $TZoffset = ($TZinfo[1]) * -1 
            $TimeZone = $TZinfo[2]
        Case 2 ;Daylight Savings Time
            $TZoffset = ($TZinfo[1] + $TZinfo[7]) * -1 
            $TimeZone = $TZinfo[5]
    EndSwitch
    
    GUICtrlSetData($txtNTPServerUTC, $UTC)
    GUICtrlSetData($txtNTPServerLocalTime, _DateAdd("n",$TZoffset,$UTC))
    
    GUICtrlSetData($txtTimeZone, $TimeZone)
    GUICtrlSetData($txtOffset, $TZoffset / 60)
    GUICtrlSetData($txtLocalUTCTime, _DateAdd("n",$TZoffset * -1,_NowCalc()))
    GUICtrlSetData($txtLocalTime, _NowCalc())

EndFunc

Func CenterWindow($window_title)
    $position = WinGetPos($window_title)
    WinMove($window_title, "", (@desktopwidth / 2) - ($position[2] / 2), (@desktopheight / 2)  - ($position[3] / 2))
EndFunc

CenterWindow($AppTitleVersion)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $cmdQuery
            QueryNTP(GUICtrlRead($txtNTPServer))
        
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Link to comment
Share on other sites

  • 2 months later...

Ran across this post when looking for a way to simply pull the date and time from an NTP server. Couldn't find a good example so I wrote this. Seems to work ok.

Thank you very much!

This is exactly what I was looking for. We were not able to use a batch or regular AutoIt DOS command function call to the normal ways of updating Windows time using NTP (w32tm OR net time) because we are using Windows Steady State to lock down the computer to protect it from the users. Therefore command prompts (even hidden ones) are blocked. Needless to say this is made necessary because the regular Windows time update also does not function when Steady State is on, oddly enough.

I utilized the originally posted AutoIt code and just added a small part to the end of it to make it apply the obtained NTP time to the local computer using AutoIt functions, thereby getting around our problem.

The modified code:

#include <Date.au3>

$ntpServer = "pool.ntp.org" ; NTP server

UDPStartup()
Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
If @error <> 0 Then
    MsgBox(0,"","Can't open connection!")
    Exit
EndIf
$status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
If $status = 0 Then
    MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
    Exit
EndIf
$data=""
While $data=""
    $data = UDPRecv($socket, 100)
    sleep(100)
WEnd
UDPCloseSocket($socket)
UDPShutdown()

$unsignedHexValue=StringMid($data,83,8); Extract time from packet. Disregards the fractional second.
;MsgBox(0, "UDP DATA", $unsignedHexValue)

$value=UnsignedHexToDec($unsignedHexValue)
$TZinfo = _Date_Time_GetTimeZoneInformation()
$TZoffset=$TZinfo[1]*-1
$UTC=_DateAdd("s",$value,"1900/01/01 00:00:00")

;~ Extracts the data & time into vars
;~ Date format & offsets
;~ 2009/12/31 19:26:05
;~ 1234567890123456789  [1 is start of string]

$m = StringMid ($UTC,6,2)
$d = StringMid ($UTC,9,2)
$y = StringMid ($UTC,1,4)
$h = StringMid ($UTC,12,2)
$mi = StringMid ($UTC,15,2)
$s = StringMid ($UTC,18,2)

;~ MsgBox(0,"",$m & "/" & $d & "/" & $y & " " & $h & ":" & $mi & ":" & $s) ; Visual test of obtained date

;~ Sets the new current time to the computer
$tCurr = _Date_Time_EncodeSystemTime($m,$d,$y,$h,$mi,$s)
_Date_Time_SetSystemTime(DllStructGetPtr($tCurr))


;**************************************************************************************************
;** Fuctions **************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p=""
    While $d
        $p&=Chr(Dec(StringLeft($d,2)))
        $d=StringTrimLeft($d,2)
    WEnd
    Return $p
EndFunc
;**************************************************************************************************
Func UnsignedHexToDec($n)
    $ones=StringRight($n,1)
    $n=StringTrimRight($n,1)
    Return dec($n)*16+dec($ones)
EndFunc
;**************************************************************************************************
Link to comment
Share on other sites

  • 1 month later...

yn0t mentioned a bug with daylight saving but did not fully fixed it. Here is Fz's (original) fixed script:

#include <Date.au3>

$ntpServer = "pool.ntp.org"

UDPStartup()
Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
If @error <> 0 Then
    MsgBox(0, "", "Can't open connection!")
    Exit
EndIf
$status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
If $status = 0 Then
    MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
    Exit
EndIf
$data = ""
While $data = ""
    $data = UDPRecv($socket, 100)
    Sleep(100)
WEnd
UDPCloseSocket($socket)
UDPShutdown()

;MsgBox(0, "UDP DATA RAW", $data)
$unsignedHexValue = StringMid($data, 83, 8); Extract time from packet. Disregards the fractional second.
;MsgBox(0, "UDP DATA", $unsignedHexValue)

$value = UnsignedHexToDec($unsignedHexValue)
$TZinfo = _Date_Time_GetTimeZoneInformation()
;$TZoffset = $TZinfo[1] * - 1
$UTC = _DateAdd("s", $value, "1900/01/01 00:00:00")

If $TZinfo[0] <> 2 Then ; 0 = Daylight Savings not used in current time zone / 1 = Standard Time
    $TZoffset = ($TZinfo[1]) * - 1
Else ; 2 = Daylight Savings Time
    $TZoffset = ($TZinfo[1] + $TZinfo[7]) * - 1
EndIf

MsgBox(0, "", "Time from NTP Server UTC:               " & $UTC & @CRLF & _
        "Time from NTP Server Local Offset:      " & _DateAdd("n", $TZoffset, $UTC) & @CRLF & _
        "Time from Local Computer Clock:         " & _NowCalc())

;**************************************************************************************************
;** Fuctions **************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p = ""
    While $d
        $p &= Chr(Dec(StringLeft($d, 2)))
        $d = StringTrimLeft($d, 2)
    WEnd
    Return $p
EndFunc   ;==>MakePacket
;**************************************************************************************************
Func UnsignedHexToDec($n)
    $ones = StringRight($n, 1)
    $n = StringTrimRight($n, 1)
    Return Dec($n) * 16 + Dec($ones)
EndFunc   ;==>UnsignedHexToDec
;**************************************************************************************************

yn0t's fixed script (GUI):

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>

$AppTitle = "NTP Client"
$AppVersion = "1.0"
$AppTitleVersion = $AppTitle & " v" & $AppVersion

#Region ### START Koda GUI section ###
$frmMain = GUICreate($AppTitleVersion, 498, 271, 239, 155)
$txtNTPServer = GUICtrlCreateInput("pool.ntp.org", 72, 8, 417, 21)
$Label1 = GUICtrlCreateLabel("NTP Server:", 8, 10, 63, 17)
$cmdQuery = GUICtrlCreateButton("Query", 416, 240, 75, 25, $WS_GROUP)
$grpNTPServer = GUICtrlCreateGroup("NTP Server", 8, 32, 481, 73)
$Label2 = GUICtrlCreateLabel("NTP Server UTC:", 48, 52, 88, 17)
$txtNTPServerUTC = GUICtrlCreateInput("", 136, 48, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$txtNTPServerLocalTime = GUICtrlCreateInput("", 136, 72, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Label5 = GUICtrlCreateLabel("NTP Server Local Time:", 18, 76, 118, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$grpLocal = GUICtrlCreateGroup("Local Computer", 8, 112, 481, 121)
$Label3 = GUICtrlCreateLabel("Time Zone:", 73, 134, 58, 17)
$Label4 = GUICtrlCreateLabel("Offset (hours):", 61, 154, 70, 17)
$Label6 = GUICtrlCreateLabel("UTC Time:", 76, 177, 55, 17)
$txtTimeZone = GUICtrlCreateInput("", 136, 128, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$txtOffset = GUICtrlCreateInput("", 136, 152, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$txtLocalUTCTime = GUICtrlCreateInput("", 136, 176, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$txtLocalTime = GUICtrlCreateInput("", 136, 200, 345, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Label9 = GUICtrlCreateLabel("Local Time:", 72, 199, 59, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

;**************************************************************************************************
;** Functions *************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p = ""
    While $d
        $p &= Chr(Dec(StringLeft($d, 2)))
        $d = StringTrimLeft($d, 2)
    WEnd
    Return $p
EndFunc   ;==>MakePacket

Func UnsignedHexToDec($n)
    $ones = StringRight($n, 1)
    $n = StringTrimRight($n, 1)
    Return Dec($n) * 16 + Dec($ones)
EndFunc   ;==>UnsignedHexToDec

Func QueryNTP($ntpServer)
    UDPStartup()
    Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
    If @error <> 0 Then
        MsgBox(0, "", "Can't open connection!")
        Return 0
    EndIf

    $status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))

    If $status = 0 Then
        MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
        Return 0
    EndIf
    $data = ""
    While $data = ""
        $data = UDPRecv($socket, 100)
        Sleep(100)
    WEnd
    UDPCloseSocket($socket)
    UDPShutdown()

    $unsignedHexValue = StringMid($data, 83, 8) ; Extract time from packet. Disregards the fractional second.

    $value = UnsignedHexToDec($unsignedHexValue)
    $TZinfo = _Date_Time_GetTimeZoneInformation()
    ;msgbox(4096, "", $TZinfo[0])
    $UTC = _DateAdd("s", $value, "1900/01/01 00:00:00")

    If $TZinfo[0] <> 2 Then ; 0 = Daylight Savings not used in current time zone / 1 = Standard Time
        $TZoffset = ($TZinfo[1]) * - 1
        $TimeZone = $TZinfo[2]
    Else ; 2 = Daylight Savings Time
        $TZoffset = ($TZinfo[1] + $TZinfo[7]) * - 1
        $TimeZone = $TZinfo[5]
    EndIf

    GUICtrlSetData($txtNTPServerUTC, $UTC)
    GUICtrlSetData($txtNTPServerLocalTime, _DateAdd("n", $TZoffset, $UTC))

    GUICtrlSetData($txtTimeZone, $TimeZone)
    GUICtrlSetData($txtOffset, $TZoffset / 60)
    GUICtrlSetData($txtLocalUTCTime, _DateAdd("n", $TZoffset * - 1, _NowCalc()))
    GUICtrlSetData($txtLocalTime, _NowCalc())

EndFunc   ;==>QueryNTP

Func CenterWindow($window_title)
    $position = WinGetPos($window_title)
    WinMove($window_title, "", (@DesktopWidth / 2) - ($position[2] / 2), (@DesktopHeight / 2) - ($position[3] / 2))
EndFunc   ;==>CenterWindow

CenterWindow($AppTitleVersion)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $cmdQuery
            QueryNTP(GUICtrlRead($txtNTPServer))

        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

and stealthf117jm's fixed script (Synchronizer):

#include <Date.au3>

$ntpServer = "pool.ntp.org"

UDPStartup()
Dim $socket = UDPOpen(TCPNameToIP($ntpServer), 123)
If @error <> 0 Then
    MsgBox(0, "", "Can't open connection!")
    Exit
EndIf
$status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
If $status = 0 Then
    MsgBox(0, "ERROR", "Error while sending UDP message: " & @error)
    Exit
EndIf
$data = ""
While $data = ""
    $data = UDPRecv($socket, 100)
    Sleep(100)
WEnd
UDPCloseSocket($socket)
UDPShutdown()

;MsgBox(0, "UDP DATA RAW", $data)
$unsignedHexValue = StringMid($data, 83, 8); Extract time from packet. Disregards the fractional second.
;MsgBox(0, "UDP DATA", $unsignedHexValue)

$value = UnsignedHexToDec($unsignedHexValue)
$TZinfo = _Date_Time_GetTimeZoneInformation()
;$TZoffset = $TZinfo[1] * - 1
$UTC = _DateAdd("s", $value, "1900/01/01 00:00:00")

If $TZinfo[0] <> 2 Then ; 0 = Daylight Savings not used in current time zone / 1 = Standard Time
    $TZoffset = ($TZinfo[1]) * - 1
Else ; 2 = Daylight Savings Time
    $TZoffset = ($TZinfo[1] + $TZinfo[7]) * - 1
EndIf

;~ Extracts the data & time into vars
;~ Date format & offsets
;~ 2009/12/31 19:26:05
;~ 1234567890123456789  [1 is start of string]

$m = StringMid($UTC, 6, 2)
$d = StringMid($UTC, 9, 2)
$y = StringMid($UTC, 1, 4)
$h = StringMid($UTC, 12, 2)
$mi = StringMid($UTC, 15, 2)
$s = StringMid($UTC, 18, 2)

;~ MsgBox(0,"",$m & "/" & $d & "/" & $y & " " & $h & ":" & $mi & ":" & $s) ; Visual test of obtained date

;~ Sets the new current time to the computer
$tCurr = _Date_Time_EncodeSystemTime($m, $d, $y, $h, $mi, $s)
_Date_Time_SetSystemTime(DllStructGetPtr($tCurr))


;**************************************************************************************************
;** Fuctions **************************************************************************************
;**************************************************************************************************
Func MakePacket($d)
    Local $p = ""
    While $d
        $p &= Chr(Dec(StringLeft($d, 2)))
        $d = StringTrimLeft($d, 2)
    WEnd
    Return $p
EndFunc   ;==>MakePacket
;**************************************************************************************************
Func UnsignedHexToDec($n)
    $ones = StringRight($n, 1)
    $n = StringTrimRight($n, 1)
    Return Dec($n) * 16 + Dec($ones)
EndFunc   ;==>UnsignedHexToDec
;**************************************************************************************************

Thank you very much guys!

Link to comment
Share on other sites

  • 11 months later...

Modified yours code in this way because script hangs for long time when no internet connection are present.

Also added 4 NTP servers to be checked. if one not respond, switch to next. if no response at all,just exit

without any notice. My intention are to use it as one scheduled task to run it daily.

#include <Date.au3>
#NoTrayIcon
;Variables
Dim $NTP_Server[4] = ['time.nist.gov','pool.ntp.org','ntp.amnic.net','ntp.stairweb.de'], $NTP_IP[4], $NTPIP[4]
;main program
$NTP_IP = call('check_internet_connectivity')
        If  $NTP_IP[0] <> '' Then
            $adata = call('NTP_Connect', $NTP_Server[0])
        ElseIf $NTP_IP[1] <> '' Then
            $adata = call('NTP_Connect', $NTP_Server[1])
        ElseIf $NTP_IP[2] <> '' Then
            $adata = call('NTP_Connect', $NTP_Server[2])
        ElseIf $NTP_IP[3] <> '' Then
            $adata = call('NTP_Connect', $NTP_Server[3])
            Else
        Exit
        EndIf
call('Set_Time', $adata)
Exit
;Function to check wich/if servers are available to avoid UDP hangs for long time when to connection.
Func check_internet_connectivity()
    TCPStartup()
        For $i = 0 to 3
            $NTPIP[$i] = TCPNameToIP ( $NTP_Server[$i])
            Sleep(250)
        Next
    TCPShutdown ()
    Return $NTPIP
EndFunc
;Function to read time from ntp server as unsigned hex.
Func NTP_Connect($NTP_Server)
    UDPStartup()
    Dim $socket = UDPOpen(TCPNameToIP($NTP_Server), 123)
    $status = UDPSend($socket, MakePacket("1b0e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
    $data = ""
    While $data = ""
        $data = UDPRecv($socket, 100)
        Sleep(100)
    WEnd
    UDPCloseSocket($socket)
    UDPShutdown()
    Return $data
EndFunc
;Function to decrypt the time from returned hex string and apply new time to system
Func Set_Time($bdata)
    $unsignedHexValue = StringMid($bdata, 83, 8); Extract time from packet. Disregards the fractional second.
    $value = UnsignedHexToDec($unsignedHexValue)
    $TZinfo = _Date_Time_GetTimeZoneInformation()
    $UTC = _DateAdd("s", $value, "1900/01/01 00:00:00")
    If  $TZinfo[0] <> 2 Then ; 0 = Daylight Savings not used in current time zone / 1 = Standard Time
        $TZoffset = ($TZinfo[1]) * - 1
        Else ; 2 = Daylight Savings Time
        $TZoffset = ($TZinfo[1] + $TZinfo[7]) * - 1
    EndIf
            ;~ Extracts the data & time into vars
            ;~ Date format & offsets
            ;~ 2009/12/31 19:26:05
            ;~ 1234567890123456789  [1 is start of string]
    $m = StringMid($UTC, 6, 2)
    $d = StringMid($UTC, 9, 2)
    $y = StringMid($UTC, 1, 4)
    $h = StringMid($UTC, 12, 2)
    $mi = StringMid($UTC, 15, 2)
    $s = StringMid($UTC, 18, 2)
;~ Sets the new current time to the computer
    $tCurr = _Date_Time_EncodeSystemTime($m, $d, $y, $h, $mi, $s)
    _Date_Time_SetSystemTime(DllStructGetPtr($tCurr))
EndFunc
;Function to send packet to ntp server
Func MakePacket($d)
    Local $p = ""
    While $d
        $p &= Chr(Dec(StringLeft($d, 2)))
        $d = StringTrimLeft($d, 2)
    WEnd
    Return $p
EndFunc
;Function to decript UnsignedHexToDec
Func UnsignedHexToDec($n)
    $ones = StringRight($n, 1)
    $n = StringTrimRight($n, 1)
    Return Dec($n) * 16 + Dec($ones)
EndFunc

ClockSynchronizer.au3

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...