Getting the Internet Time
How do you synchronise your computer clock to the latest time?
Alter it every year following a quick glance at your wristwatch? Occasionally dial 1-2-3 and attentively listen to the 'Time Sponsored By Accurist'? Or do you only bother when management reports for September start cropping up in August?
Well, whatever your method there's a better way.
Very few know it, but you can connect to the clocks of amazingly powerful computers from all around the world with just the Winsock control and a little crafty code.
It's worth noting that so few Visual Basic programmers actually know about the neat methods we'll be discovering today, one control company actually sells this functionality.
I'm not going to mention the company name it wouldn't be fair on Mabry (www.mabry.com) but a ten-user version of Time/X with source code would cost you well over a grand.
So read on to find out how you can synchronise your computer clock and perhaps save yourself a few quid in the process.
Believe it or not, there was a time when the Net didn't exist. Back then, technical boffins sat around dreaming up the likes of HTTP and FTP 'protocols', acronyms currently running the real core of the Internet.
It was back in those golden days when a special little baby called NTP was born.
NTP stands for Network Time Protocol and is a method of retrieving the date and time from other computers. It was originally conjured up to allow supercool networked computers to synchronise the current time amongst one another.
And this protocol still exists. A large number of huge Internet computers all of which maintain incredibly accurate 'atomic' times allow you to simply connect to them, grab the date and time, then say goodbye.
It's supposed to be simple. In fact, it is simple. But few programmers actually know about it.
Let's perform a little experiment with the Network Time Protocol:
- Click 'Start', 'Run'
- Type in 'Telnet' then click 'OK'
- Select 'Connect', 'Remote System'
This Telnet program allows you to connect to other computers. In the host name, we need to type in the computer that will allow us to access the NTP information.
- Under 'Host Name', type in: "pogostick.net"
Top Tip: Lists of public NTP computers or 'servers' can be found all over the Internet. Others include tick.usno.navy.mil, ntp0.strath.ac.uk, ntp.univ-lyon1.fr, chime1.surfnet.nl and bernina.ethz.ch
And now for the important bit. The 'Port' is like the channel on your television. You need to tune into the right channel to get the right information. And it's the same here - for the NTP service, you need to tune into port 13. Let's do that now:
- Under 'Port', type in: "13"
- Ensure you're connected to the Internet, then click 'Connect'
Now you should be presented with a little message box saying the connection is closed or some such. Let me explain what's happened here.
When you connected, Telnet found the pogostick.net computer and connected to port 13. The pogostick.net computer knows what to do on port 13 it instantly throws back the current date and time, which you should be able to see in the white Telnet window. As soon as that has occurred, it disconnects and Telnet displays the message box on your screen right now.
Top Tip: A lot of people think Internet traffic might alter the accuracy of the time coming back. But in reality, it rarely takes more than a half-second for the information to arrive back at your computer and most time servers make an allowance for this.
So, we know it is possible to retrieve the current date and time from accurate, beast-like computers. But how can you do it in Visual Basic?
You can simulate use of Telnet in Visual Basic by using the Winsock control.
All you need to do is perform a Winsock1.Connect, wait for the data to arrive, then Winsock1.Close. Simple as that. Let's knock together a sample project:
- Launch Visual Basic
- Create a new Standard EXE
- Click 'Project', 'Components'
- Check 'Microsoft Winsock Control 6.0', then click OK
- Draw out the new Winsock control onto Form1
The Winsock control is sort of like a programmable Telnet. It lets you connect to other computers and see how they respond.
- Add a Command Button to Form1
- Insert the following code behind the button:
Winsock1.RemoteHost = "pogostick.net"Winsock1.RemotePort = 13Winsock1.Connect
This code sets the properties of the Winsock control as we did in Telnet then attempts to connect. After we've connected, you might remember that the computer at the other end instantly sends back the current date and time, then terminates the connection. Let's code for that now:
- In the 'Object' drop-down list, select Winsock1
- In the adjacent 'Procedure' drop-down, select the 'DataArrival' event
The DataArrival event fires up whenever information is sent to your machine from the computer you're connected to. Let's add code to handle this now:
- Insert the following code behind the DataArrival event of your Winsock1 control:
Dim strData As StringWinsock1.GetData strData, vbStringMsgBox strDataWinsock1.Close
This is nothing special. First off, the information sent back from the server is stored in the strData variable then displayed in a message box. Finally, the computer connection is closed with the Winsock Close method. Let's test it all so far:
- Hit F5 to run your application
- Press your Command Button
You should be presented with a message box displaying something like, "Tue Sep 05 19:08:54".
If this isn't the exact time in your part of the world, you need to increase or decrease an hour or two depending on your time zone. You can handle this later.
Our most obvious problem is the stuff returned by this mega computer is just a piece of text. It's not a real "date", it can't fit into a variable of the Date data type.
Or can it?
We can turn the string returned by the Winsock control into a regular date with the help of a little function I made earlier:
- Add the following function to your project:
Public Function FormatDateTime(NetTime As String) As Date ' Takes the standard DDD MMM DD HH:MM:SS YYYY ' format and changes it into a regular date! Dim strDate As String Dim strTime As String ' Extract the date strDate = Trim(Mid(NetTime, 4, 7)) & " " & _ Trim(Mid(NetTime, 21)) ' Extract the time strTime = Trim(Mid(NetTime, 12, 9)) ' Check the extracts are suitable date ' and times - then convert using CDate If IsDate(strDate) And IsDate(strTime) Then FormatDateTime = CDate(strDate & " " & strTime) Else ' If unsuitable, set FormatDateTime to system ' clock date and time FormatDateTime = Now End IfEnd Function
Now let's alter the old code to use this new function:
- Alter the code behind the DataArrival event to:
Dim strData As StringDim datDate As DateWinsock1.GetData strData, vbStringdatDate = FormatDateTime(strData)MsgBox ("The current date and time is:" & _Format(datDate, "dddd mmmm dd yyyy hh:mm:ss"))Winsock1.Close
This code uses the new FormatDateTime function to extract a real date and time from the returned string. This is then displayed in a message box, after being neatly formatted by the Format command.
- Press F5 and test your application
And that's about it! You've learned virtually all there is to know about extracting the most up-to-date time from some of the world's most powerful computers.
But what can you do with this newfound knowledge? Well, some need the current date and time from an authenticated source to validate time-critical information, such as medical data or record accurate order times.
However by far and away the most common use is to ensure both yours and your users computer clocks are kept from losing those extra few seconds each and every day. In fact, one guy even built a freeware program that automatically does this every couple o' hours.
Yet that leads us to one final question. We know how to retrieve the most accurate date and time. But how do you set the computer clock?
We recently ran this little-known piece of code as a tip here on VB-World but here it is again in full Technicolor glory two functions allowing you to set your computer clock in code.
Public Sub SetDate(NewDate As Variant) On Error Resume Next DateTime.Date = NewDateEnd SubPublic Sub SetTime(NewTime As Variant) On Error Resume Next DateTime.Time = NewTimeEnd Sub
And that really is all. You know how to grab the data from time servers, you know how to change it into a real date and you now know how to set the computer clock. Und das ist alles, mon ami!
In this article, we discovered how you can use the Winsock control and knowledge of the Network Time Protocol (NTP) to grab the most accurate 'atomic' time from the Internet.
We went on to use a function that changed the returned NTP information into a real date, then found out how to set the computer clock.
And to say Mabry sell this jazz for big bucks... Hah! I laugh at Mabry. Erm, however I'd like to add that any monetary donations made in response to this article would be gratefully received. Anyone? Anyone??
Oh well, maybe next time... so until then, this is your host Karl Moore signing off for tonight. Goodnight!