Get the current time from the NIST server in C#

example

This example, courtesy of Adam Benson, shows how you can get the current time from the NIST atomic clock server. (I’ve reformatted it slightly to make it fit better on the blog page.)

The key to the program is the following method, which does the work of getting the date and time.

//Server addresses and information from //http://tf.nist.gov/tf-cgi/servers.cgi
public const string server = "time.nist.gov"; //URL to connect to the server
public const Int32 port = 13; //port to get date time data from the server

//**************************************************************************
//NAME:      GetNISTDateTime
//PURPOSE:   Creates a TCP client to connect to the NIST server, gets the 
//data from the server, and parses that data into a string that can be used 
//for display or calculation.
//**************************************************************************
public void GetNISTDateTime()
{
    bool bGoodConnection = false;

    //Create and instance of a TCP client that will connect to the server 
    //and get the information it offers
    System.Net.Sockets.TcpClient tcpClientConnection = new System.Net.Sockets.TcpClient();

    //Attempt to connect to the NIST server. If it succeeds, the flag is set 
    //to collect the information from the server If it fails, try again
    try
    {
        tcpClientConnection.Connect(server, port);
        bGoodConnection = true;
    }
    catch
    {
        btnGetServerDateAndTime.PerformClick();
    }

    //Don't continue if you haven't got a good connection
    if (bGoodConnection == true)
    {
        //Attempt to get the data streaming from the NIST server
        try
        {
            NetworkStream netStream = tcpClientConnection.GetStream();

            //Check the flag the states if you can read the stream or not
            if (netStream.CanRead)
            {
                //Get the size of the buffer
                byte[] bytes = new byte[tcpClientConnection.ReceiveBufferSize];

                //Read in the stream to the length of the buffer
                netStream.Read(bytes, 0, tcpClientConnection.ReceiveBufferSize);

                //Read the Bytes as ASCII values and build the stream
                // of charaters that are the date and time from NIST. 
                sNISTDateTimeFull = Encoding.ASCII.GetString(bytes).Substring(0, 50);

                //Convert the string to a date time value
                try
                {
                    subStringNISTDateTimeShort = sNISTDateTimeFull.Substring(7, 17);
                    dtNISTDateTime = DateTime.Parse("20" + subStringNISTDateTimeShort);
                }
                catch
                {
                    //try running the sub again if you didn't get anything worth while
                    btnGetServerDateAndTime.PerformClick();
                }
            }
            else //If the data stream was unreadable, do the following
            {
                //Advise the user of the situation
                MessageBox.Show("You cannot read data from this stream.");
                tcpClientConnection.Close(); //close the client stream
                netStream.Close(); //close the network stream
            }

            //Uses the Close public method to close the network stream and socket.
            tcpClientConnection.Close();
        }
        //Provide the user feedback if the TCP client couldn't
        // even get the stream of data from the server.
        catch (ArgumentNullException e)
        {
            // show error messages when appropriate
            MessageBox.Show("ArgumentNullException: {0}", e.ToString());
        }
        catch (SocketException e)
        {
            // show error messages when appropriate
            MessageBox.Show("SocketException: {0}", e.ToString());
        }
    }
}

The code attempts to make a TCP client connection to the server. If it makes the connection, the code gets a stream to read data from the connection. If the stream is readable, the program reads bytes from it. It then uses the Encoding.ASCII.GetString method to convert the bytes into a string. The result is a string of the form:

\n56444 13-06-01 16:03:24 50 0 0 385.7 UTC(NIST) * 

Here the “\n” at the beginning is an embedded newline character.

The code uses this string’s Substring method to pull out the date and time information in the following format:

13-06-01 16:05:48

The rest of this method’s code is error handling.

After finding the subStringNISTDateTimeShort string, the program uses the following statement to convert it into a DateTime value.

dtNISTDateTime = DateTime.Parse("20" + subStringNISTDateTimeShort);

The program then displays the date and time in various formats.

There’s one more important piece to the program. Before it requests the date and time from the NIST server, the program starts a timer. The program won’t access the server again until the timer expires 5 seconds later. This prevents the program from hitting the NIST server very quickly. If you flood the server with requests, it will ban you and stop replying.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in miscellany, system and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

One Response to Get the current time from the NIST server in C#

  1. Charles says:

    Speaking of atomic clocks, I was just reading “How We Got to Now” by Steven Johnson and he has an entire chapter on time and how we developed the atomic clock. Then I chanced upon this excellent code. Good timing, I’d say.

Leave a Reply

Your email address will not be published. Required fields are marked *