Hi
Has anybody realized a function to get the time from an NTP time server?
Walter
Has anybody realized a function to get the time from an NTP time server?
Walter
#COMPILE EXE '#Win 8.04# #DIM ALL #INCLUDE "Win32Api.inc" $TimeServer = "time-a.timefreq.bldrdoc.gov" '$TimeServer = "time-a.nist.gov" '129.6.15.28 NIST, Gaithersburg, Maryland '$TimeServer = "time-b.nist.gov" '129.6.15.29 NIST, Gaithersburg, Maryland '$TimeServer = "time-a.timefreq.bldrdoc.gov" '132.163.4.101 NIST, Boulder, Colorado '$TimeServer = "time-b.timefreq.bldrdoc.gov" '132.163.4.102 NIST, Boulder, Colorado '$TimeServer = "time-c.timefreq.bldrdoc.gov" '132.163.4.103 NIST, Boulder, Colorado '$TimeServer = "utcnist.colorado.edu" '128.138.140.44 University of Colorado, Boulder '$TimeServer = "time.nist.gov" '192.43.244.18 NCAR, Boulder, Colorado '$TimeServer = "time-nw.nist.gov" '131.107.1.10 Microsoft, Redmond, Washington '$TimeServer = "nist1.datum.com" '66.243.43.21 Datum, San Jose, California '$TimeServer = "nist1.aol-ca.truetime.com" '207.200.81.113 TrueTime, AOL facility, Sunnyvale, California TYPE RFC867 'Example: "54488 08-01-23 03:55:27 00 0 0 0.0 UTC(NIST) *" Julian AS STRING * 5 Space1 AS STRING * 1 Year AS STRING * 2 Hyphen1 AS STRING * 1 Month AS STRING * 2 Hyphen2 AS STRING * 1 Day AS STRING * 2 Space2 AS STRING * 1 Hour AS STRING * 2 Column1 AS STRING * 1 Minute AS STRING * 2 Column2 AS STRING * 1 Second AS STRING * 2 Space3 AS STRING * 1 DST AS STRING * 2 Space4 AS STRING * 1 LeapSec AS STRING * 1 Space5 AS STRING * 1 Health AS STRING * 1 Space6 AS STRING * 1 Delay AS STRING * 5 Space7 AS STRING * 1 Label AS STRING * 9 Space8 AS STRING * 1 OTM AS STRING * 1 END TYPE '_____________________________________________________________________________ FUNCTION PBMAIN AS LONG LOCAL SysTimeUTC AS SYSTEMTIME LOCAL SysTimeLocal AS SYSTEMTIME LOCAL ServerTime AS RFC867 LOCAL hFile AS DWORD LOCAL sTime AS STRING LOCAL sMessage AS STRING hFile = FREEFILE TCP OPEN PORT 13 AT $TimeServer AS hFile TIMEOUT 2000 IF ERR THEN sMessage = "Error opening " & $TimeServer ELSE TCP LINE INPUT #hFile, sTime TCP LINE INPUT #hFile, sTime TCP CLOSE hFile TYPE SET ServerTime = sTime sMessage = "Server" & $TAB & $TimeServer & $CRLF & _ "sTime" & $TAB & sTime & $CRLF & $CRLF & _ "Year" & $TAB & ServerTime.Year & $CRLF & _ "Month" & $TAB & ServerTime.Month & $CRLF & _ "Day" & $TAB & ServerTime.Day & $CRLF & _ "Hour" & $TAB & ServerTime.Hour & $CRLF & _ "Minute" & $TAB & ServerTime.Minute & $CRLF & _ "Second" & $TAB & ServerTime.Second & $CRLF & _ "DST" & $TAB & ServerTime.DST & $CRLF & _ "LeapSec" & $TAB & ServerTime.LeapSec & $CRLF & _ "Health" & $TAB & ServerTime.Health & $CRLF & _ "Delay" & $TAB & ServerTime.Delay & $CRLF & _ "Label" & $TAB & ServerTime.Label & $CRLF & _ "OTM" & $TAB & ServerTime.OTM & $CRLF & $CRLF SysTimeUTC.wYear = VAL(ServerTime.Year) + 2000 SysTimeUTC.wMonth = VAL(ServerTime.Month) SysTimeUTC.wDay = VAL(ServerTime.Day) SysTimeUTC.wHour = VAL(ServerTime.Hour) SysTimeUTC.wMinute = VAL(ServerTime.Minute) SysTimeUTC.wSecond = VAL(ServerTime.Second) SystemTimeToTzSpecificLocalTime(BYVAL 0, SysTimeUTC, SysTimeLocal) sMessage = sMessage & "Local time conversion" & $TAB & _ FORMAT$(SysTimeLocal.wYear, "0000") & "-" & FORMAT$(SysTimeLocal.wMonth, "00") & "-" & _ FORMAT$(SysTimeLocal.wDay, "00") & " " & FORMAT$(SysTimeLocal.wHour, "00") & ":" & _ FORMAT$(SysTimeLocal.wMinute, "00") & ":" & FORMAT$(SysTimeLocal.wSecond, "00") END IF MessageBox(%HWND_DESKTOP, BYVAL STRPTR(sMessage), "Time server", %MB_ICONINFORMATION OR %MB_OK) END FUNCTION '_____________________________________________________________________________ ' ' Daytime Protocol (RFC-867) ' 'This protocol is widely used by small computers running MS-DOS and similar operating systems. 'The server listens on port 13, and responds to requests in either tcp/ip or udp/ip formats. 'The standard does not specify an exact format for the Daytime Protocol, 'but requires that the time is sent using standard ASCII characters. 'NIST chose a time code format similar to the one used by its dial-up 'Automated Computer Time Service (ACTS), as shown below: ' ' JJJJJ YR-MO-DA HH:MM:SS TT L H msADV UTC(NIST) OTM ' 'JJJJJ is the Modified Julian Date (MJD). The MJD has a starting point of midnight ' on November 17, 1858. You can obtain the MJD by subtracting exactly 2 400 000.5 days ' from the Julian Date, which is an integer day number obtained by counting days ' from the starting point of noon on 1 January 4713 B.C. (Julian Day zero). ' 'YR-MO-DA is the date. It shows the last two digits of the year, the month, ' and the current day of month. ' 'HH:MM:SS is the time in hours, minutes, and seconds. The time is always sent as ' Coordinated Universal Time (UTC). An offset needs to be applied to UTC to ' obtain local time. For example, Mountain Time in the U. S. is 7 hours behind ' UTC during Standard Time, and 6 hours behind UTC during Daylight Saving Time. ' 'TT is a two digit code (00 to 99) that indicates whether the United States is ' on Standard Time (ST) or Daylight Saving Time (DST). It also indicates when ST or DST ' is approaching. This code is set to 00 when ST is in effect, or to 50 when DST ' is in effect. During the month in which the time change actually occurs, ' this number will decrement every day until the change occurs. For example, ' during the month of November, the U.S. changes from DST to ST. On November 1, ' the number will change from 50 to the actual number of days until the time change. ' It will decrement by 1 every day until the change occurs at 2 a.m. local time ' when the value is 1. Likewise, the spring change is at 2 a.m. local time when ' the value reaches 51. ' 'L is a one-digit code that indicates whether a leap second will be added or subtracted ' at midnight on the last day of the current month. If the code is 0, no leap second ' will occur this month. If the code is 1, a positive leap second will be added at ' the end of the month. This means that the last minute of the month will contain ' 61 seconds instead of 60. If the code is 2, a second will be deleted on the last ' day of the month. Leap seconds occur at a rate of about one per year. ' They are used to correct for irregularity in the earth's rotation. ' The correction is made just before midnight UTC (not local time). ' 'H is a health digit that indicates the health of the server. If H = 0, ' the server is healthly. If H = 1, then the server is operating properly but ' its time may be in error by up to 5 seconds. This state should change to fully ' healthy within 10 minutes. If H = 2, then the server is operating properly but its ' time is known to be wrong by more than 5 seconds. If H = 3, then a hardware or ' software failure has occurred and the amount of the time error is unknown. ' If H = 4 the system is operating in a special maintenance mode and both its accuracy ' and its response time may be degraded. This value is not used for production servers ' except in special circumstances. The transmitted time will still be correct ' to within ±1 second in this mode. ' 'msADV displays the number of milliseconds that NIST advances the time code to partially ' compensate for network delays. The advance is currently set to 50.0 milliseconds. ' 'label UTC(NIST) is contained in every time code. It indicates that you are receiving ' Coordinated Universal Time (UTC) from the National Institute of Standards ' and Technology (NIST). ' 'OTM (on-time marker) is an asterisk (*). The time values sent by the time code refer ' to the arrival time of the OTM. In other words, if the time code says ' it is 12:45:45, this means it is 12:45:45 when the OTM arrives. '_____________________________________________________________________________ '
#COMPILE EXE #DIM ALL #REGISTER NONE #TOOLS OFF %NOMMIDS = 1 %NOGDI = 1 #INCLUDE "WIN32API.INC" '#INCLUDE "NIST-Time.inc" TYPE InputBuffer JJJJJ AS ASCIIZ * 6 ' Modified Julian Date year AS ASCIIZ * 3 month AS ASCIIZ * 3 day AS ASCIIZ * 3 hour AS ASCIIZ * 3 minute AS ASCIIZ * 3 second AS ASCIIZ * 3 TT AS ASCIIZ * 3 ' Regards US Standard or Daylight Saving Time L AS ASCIIZ * 2 ' To leap or not to leap, that is the question Health AS ASCIIZ * 2 ' = 0 for healthy, = 1 for < 5 secs error & should be OK within 10 minutes ' = 2 for > 5 secs error & = 4 for unknown error ' msADV AS ASCIIZ * 6 ' millisecond advance for ACTS but not RFC-867 sLabel AS STRING * 9 ' Should be UTC(NIST) dummy AS STRING * 1 otm AS STRING * 1 ' On-time marker (*) - no cr/lf pair sent END TYPE UNION BufferUnion wholeStr AS STRING * 48 section AS InputBuffer END UNION DECLARE FUNCTION FillArray( MyArray1( ) AS STRING, MyArray2( ) AS STRING ) AS LONG FUNCTION PBMAIN AS LONG LOCAL hSocket, NumberOfTimeServers, Count, dummy, success, Start, Finish AS LONG LOCAL wNistMilliseconds AS WORD DIM DataBuffer AS BufferUnion LOCAL qvTime AS QUAD DIM udtvTime AS SYSTEMTIME LOCAL mode AS STRING mode = COMMAND$ ' If anything found then run silent REDIM Site( 0 ) AS STRING REDIM SiteName( 0 ) AS STRING NumberOfTimeServers = FillArray( Site(), SiteName() ) RANDOMIZE ' Shuffle the time servers to use FOR Count = 1 TO NumberOfTimeServers - 1 dummy = RND( Count, NumberOfTimeServers ) SWAP Site( Count ), Site( dummy ) SWAP SiteName( Count ), SiteName( dummy ) NEXT FOR Count = 1 TO NumberOfTimeServers ERRCLEAR hSocket = FREEFILE TCP OPEN PORT 13 AT Site( Count ) AS hSocket TIMEOUT 2000 IF ERR = 0 THEN Start = TIMEGETTIME() ' ................................................................. [1] TCP LINE INPUT hSocket, DataBuffer.wholeStr TCP LINE INPUT hSocket, DataBuffer.wholeStr Finish = TIMEGETTIME() '................................................................. [2] TCP CLOSE hSocket IF VAL( DataBuffer.section.Health ) > 0 THEN EXIT IF ' We should have got the on-time marker - try another server IF DataBuffer.section.otm <> "*" THEN EXIT IF udtvTime.wYear = VAL( DataBuffer.section.year ) + 2000 udtvTime.wMonth = VAL( DataBuffer.section.month ) udtvTime.wDay = VAL( DataBuffer.section.day ) udtvTime.wHour = VAL( DataBuffer.section.hour ) udtvTime.wMinute = VAL( DataBuffer.section.minute ) udtvTime.wSecond = VAL( DataBuffer.section.second ) 'wNistMilliseconds is the ms value to the next whole second wNistMilliseconds = VAL( DataBuffer.section.msADV ) ' Suggested by Bob Scott SYSTEMTIMETOFILETIME udtvTime, BYVAL VARPTR( qvTime ) ' ' FILETIME routines used as opposed to VARIANTTIME routines as suggested by Clay Clear ' We are going to add latency which is the time estimated by ( [2] - [1] )/2 ' and subtract 45ms which is the 'correction' for US users. qvTime = qvTime + ( (Finish - Start)/2 - wNistMilliseconds - 45 ) * 10000 FILETIMETOSYSTEMTIME BYVAL VARPTR( qvTime ), udtvTime SETSYSTEMTIME udtvTime POSTMESSAGE %HWND_TOPMOST, %WM_TIMECHANGE, 0&, 0& ' POSTMESSAGE, another suggestion by Clay Clear success = %TRUE IF mode = "" THEN MSGBOX "Time set by " & SiteName( Count ) & " (# of servers tried:" & _ STR$(Count) & ")" & $CRLF & $CRLF & "Estimated Latency:" & STR$((Finish - Start)\2) & "ms",,"NIST-Time" EXIT FOR END IF NEXT IF ISFALSE success THEN IF mode = "" THEN MSGBOX "Failed to get time" & $CRLF & $CRLF & "Error:" & STR$( ERR ),, "NIST-Time" END IF END FUNCTION FUNCTION FillArray( MyArray1( ) AS STRING, MyArray2( ) AS STRING ) AS LONG LOCAL x AS LONG REDIM MyArray1( 1 TO DATACOUNT/2 ) AS STRING REDIM MyArray2( 1 TO DATACOUNT/2 ) AS STRING FOR x = 1 TO DATACOUNT/2 MyArray1( x ) = READ$( 2 * x - 1 ) ' giving 1, 3, 5, ..., DATACOUNT - 1 MyArray2( x ) = READ$( 2 * x ) ' giving 2, 4, 6, ..., DATACOUNT NEXT FUNCTION = DATACOUNT/2 DATA time-a.timefreq.bldrdoc.gov DATA "NIST, Boulder A, Colorado" DATA time-b.timefreq.bldrdoc.gov DATA "NIST, Boulder B, Colorado" DATA time-c.timefreq.bldrdoc.gov DATA "NIST, Boulder C, Colorado" DATA utcnist.colorado.edu DATA "University of Colorado, Boulder" DATA time.nist.gov DATA "NCAR, Boulder, Colorado" DATA time-nw.nist.gov DATA "Microsoft, Redmond, Washington" DATA nist1.symmetricom.com DATA "Symmetricom, San Jose, California" DATA nist1-dc.WiTime.net DATA "WiTime, Virginia" DATA nist1-ny.WiTime.net DATA "WiTime, New York City" DATA nist1-sj.WiTime.net DATA "WiTime, San Jose, California" DATA nist1.aol-ca.symmetricom.com DATA "Symmetricom, AOL facility, Sunnyvale, California" DATA nist1.aol-va.symmetricom.com DATA "Symmetricom, AOL facility, Virginia" DATA nist1.columbiacountyga.gov DATA "Columbia County, Georgia" DATA nist.expertsmi.com DATA "Monroe, Michigan" END FUNCTION
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment