Get time from time.nist.gov...

Posted on 2006-05-03
Medium Priority
Last Modified: 2012-06-27

How can I get the exact time from time.nist.gov in VB.NET so I can change the system time?

Thanks a lot

Question by:Ruttensoft
  • 3
  • 2

Author Comment

ID: 16599374
I have now coded this:

        Dim uri As String = "http://nist.time.gov/timezone.cgi?UTC/s/0"
        Dim myHttpWebRequest As HttpWebRequest = WebRequest.Create(uri)
        Dim myHttpWebResponse As HttpWebResponse = myHttpWebRequest.GetResponse()
        Dim sr As Stream = myHttpWebResponse.GetResponseStream()
        Dim reader As StreamReader = New StreamReader(sr, System.Text.Encoding.ASCII)
        Dim srdata As String = reader.ReadToEnd
        Dim g() As String = Split(srdata, "<td align=""center""><font size=""7"" color=""white""><b>")
        Dim d() As String = Split(g(1), "<br>")
        Dim a() As String = Split(srdata, "</b></font><font size=""5"" color=""white"">")
        Dim s() As String = Split(a(1), "<br>")
        MsgBox("The time is: " & d(0) & " " & s(0))

Is there an easier method?
LVL 96

Accepted Solution

Bob Learned earned 2000 total points
ID: 16607857
I don't have an easier one, just a more complex one:

Imports System.Runtime

Public Class InternetTimeServer

  ' Number of seconds that Windows clock can deviate from
  ' NIST and still be okay
  Private Const THRESHOLD_SECONDS As Integer = 15

  'Server IP addresses from
  Private Shared Servers() As String = { _
   "", "", "", "", _
   "", "", "", "", _
   "", "", "", "", _

  Private Shared m_lastHost As String = String.Empty
  Private Shared m_lastSysTime As DateTime

  Public Shared ReadOnly Property LastHost() As String
      Return m_lastHost
    End Get
  End Property     'LastHost

  Public Shared ReadOnly Property LastSystemTime() As String
      Return m_lastSysTime
    End Get
  End Property     'LastSystemTime

  Public Shared Function GetTimeFromServer() As DateTime

    ' Returns UTC/GMT using an NIST server if possible,
    ' degrading to simply returning the system clock.

    ' If we are successful in getting NIST time, then
    '   LastHost indicates which server was used and
    '   LastSystemTime contains the system time of the call.
    ' If LastSystemTime is not within 15 seconds of NIST time,
    '  the system clock may need to be reset.
    ' If LastHost is "", time is equal to system clock.

    Dim host As String
    Dim result As DateTime

    m_lastHost = String.Empty

    ' Scan through all the servers in the list to get
    ' the first server that returns a valid date/time.
    For Each host In Servers

      result = GetNISTTime(host)

      If result > DateTime.MinValue Then
        m_lastHost = host
        Exit For
      End If

    Next host

    If LastHost.Length = 0 Then
      ' No server in list was successful so use system time
      result = DateTime.UtcNow()
    End If

    Return result

  End Function     'GetTimeFromServer

  Public Shared Function SecondsDifference(ByVal dt1 As DateTime, ByVal dt2 As DateTime) As Integer

    Dim span As TimeSpan = dt1.Subtract(dt2)

    Return span.TotalSeconds

  End Function     'SecondsDifference

  Public Shared Function IsWindowsClockIncorrect() As Boolean

    Dim nist As DateTime = GetTimeFromServer()

    If (Math.Abs(SecondsDifference(nist, LastSystemTime)) > THRESHOLD_SECONDS) Then
      Return True
      Return False
    End If

  End Function     'IsWindowsClockIncorrect

  Private Shared Function GetNISTTime(ByVal host As String) As DateTime

    ' Returns DateTime.MinValue if host unreachable or does not
    ' produce a date/time value.

    Dim result As DateTime = DateTime.MinValue
    Dim timeStr As String = String.Empty


      Dim reader As New IO.StreamReader(New Net.Sockets.TcpClient(host, 13).GetStream)

      m_lastSysTime = DateTime.UtcNow()

      timeStr = reader.ReadToEnd()


      ' Couldn't connect to server, transmission error.
      Trace.WriteLine("Socket Exception [" & host & "]")

    Catch ex As Exception
      Trace.WriteLine("Exception [" & ex.Message & "]")
    End Try

    If timeStr.Length > 0 Then

      ' Look server signature and optimum status (time not off by  
      ' more than 5 seconds).
      If timeStr.Substring(38, 9) = "UTC(NIST)" AndAlso _
       timeStr.Substring(30, 1) = "0" Then

        Dim jd As Integer = Val(timeStr.Substring(1, 5))
        Dim yr As Integer = Val(timeStr.Substring(7, 2))
        Dim mo As Integer = Val(timeStr.Substring(10, 2))
        Dim dy As Integer = Val(timeStr.Substring(13, 2))
        Dim hr As Integer = Val(timeStr.Substring(16, 2))
        Dim mm As Integer = Val(timeStr.Substring(19, 2))
        Dim sc As Integer = Val(timeStr.Substring(22, 2))

        ' Date is before 1900.
        If (jd < 15020) Then

          If (jd > 51544) Then
            yr += 2000
            yr += 1900
          End If

          result = New DateTime(yr, mo, dy, hr, mm, sc)

        End If

      End If

    End If

    Return result

  End Function     'GetNISTTime

  <InteropServices.StructLayout(InteropServices.LayoutKind.Sequential)> _
  Private Structure SYSTEMTIME
    Public wYear As Int16
    Public wMonth As Int16
    Public wDayOfWeek As Int16
    Public wDay As Int16
    Public wHour As Int16
    Public wMinute As Int16
    Public wSecond As Int16
    Public wMilliseconds As Int16
  End Structure     'SYSTEMTIME

  Private Declare Function SetSystemTime Lib "kernel32.dll" _
    (ByRef time As SYSTEMTIME) As Int32

  Public Shared Function SetWindowsClock(ByVal time As DateTime) As Int32

    ' Sets system time, using UTC time. Windows will apply the
    ' time zone.

    Dim timeStru As New SYSTEMTIME

    timeStru.wYear = CType(time.Year, Int16)
    timeStru.wMonth = CType(time.Month, Int16)
    timeStru.wDay = CType(time.Day, Int16)
    timeStru.wDayOfWeek = CType(time.DayOfWeek, Int16)
    timeStru.wHour = CType(time.Hour, Int16)
    timeStru.wMinute = CType(time.Minute, Int16)
    timeStru.wSecond = CType(time.Second, Int16)
    timeStru.wMilliseconds = CType(time.Millisecond, Int16)

    Dim result As Int32 = SetSystemTime(timeStru)

    Return result

  End Function     'SetWindowsClock

End Class


Author Comment

ID: 16608046
Thanks a lot, a small fault is in the code but otherwise it's perfect!

(jd < 15020) must be (jd > 15020)

Author Comment

ID: 16608062
Btw. how does the code know that I am UTC +2? Its working perfectly but I dont know how the code knows it?
LVL 96

Expert Comment

by:Bob Learned
ID: 16608109
Thanks, I have a lot of code that sits without much debugging until I need it.


Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Integration Management Part 2
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

580 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question