none
Obtener la fecha de internet y ponerla a mi sistema (windows) RRS feed

  • Pregunta

  • Buenos días a todos, hoy tengo una inquietud, me he estado documentando al respecto, pero no he conseguido mucho avance, espero puedan ayudarme, lo que necesito es obtener la fecha de un servidor de internet para actualizar la fecha de mi sistema y tenerla sincronizada, esto lo quiero hacer mediante vb. De antemano por su ayuda, gracias!
    martes, 12 de julio de 2016 15:39

Respuestas

  • Claro que sí, en la función GetTime() de la clase ahí revisa, si tienes un servidor específico no habría problema a que lo hagas ahí mismo. 
    Public Shared Function GetTime() 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
            ' LastSysTime contains the system time of the call
            ' If LastSysTime 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
    
            LastHost = ""
            For Each host In Servers
                result = GetNISTTime("Aqui tu servidor")
                If result > DateTime.MinValue Then
                    LastHost = host
                    Exit For
                End If
            Next
    
            If LastHost = "" Then
                'No server in list was successful so use system time
                result = DateTime.UtcNow()
            End If
    
            Return result
        End Function
    Saludos

    Javier

    • Marcado como respuesta danielneria martes, 12 de julio de 2016 19:00
    martes, 12 de julio de 2016 18:22

Todas las respuestas

  • Hola danielneria

    Revisa este Post que te puede ayudar:

    DateTime Internet

    Suerte

     

    Javier

    martes, 12 de julio de 2016 15:41
  • Javier, gracias por tu ayuda, ya he revisado la información y me parece excelente, acabo de intentar sincronizar la fecha con el código proporcionado como ejemplo...

    If Daytime.WindowsClockIncorrect() Then
        Daytime.SetWindowsClock(Daytime.GetTime())
    End If

    sin embargo, me muestra un error mi programa diciendome que no se ha declarado el nombre 'Daytime' lo eh declarado como boolean porque en la página indica que es de ese tipo

    Daytime.WindowsClockIncorrect() As Boolean - Returns True if NIST time is not close to system time

    Después me marca otros errores  'WindowsClockIncorrect' no pertenece a boolean, '

    GetTime' no pertenece a boolean.

    alguna sugerencia para corregir el error?


    • Editado danielneria martes, 12 de julio de 2016 15:54
    martes, 12 de julio de 2016 15:54
  • Creaste la clase DayTime en tu proyecto?

    Ya que WindowsClockIncorrect() pertenece a esa clase.


    Javier

    martes, 12 de julio de 2016 16:43
  • No, solo intenté declararla como variable, tengo una clase que se llama formulario principal y ahpi es en donde quiero obtener la fecha para posteriormente usarla, tendría que crear otra clase llamada DayTime en otro formulario o ahí mismo la creo?

    martes, 12 de julio de 2016 17:35
  • Esta es la clase que tienes que crear en tu proyecto:

    Imports System.Runtime.InteropServices
    Imports System.IO
    Imports System.Net.Sockets
    
    Public Class Daytime
        'Internet Time Server class by Alastair Dallas 01/27/04
    
        Private Const THRESHOLD_SECONDS As Integer = 15 'Number of seconds
        ' that Windows clock can deviate from NIST and still be okay
    
        'Server IP addresses from 
        'http://www.boulder.nist.gov/timefreq/service/time-servers.html
        Private Shared Servers() As String = { _
              "129.6.15.28" _
            , "129.6.15.29" _
            , "132.163.4.101" _
            , "132.163.4.102" _
            , "132.163.4.103" _
            , "128.138.140.44" _
            , "192.43.244.18" _
            , "131.107.1.10" _
            , "66.243.43.21" _
            , "216.200.93.8" _
            , "208.184.49.9" _
            , "207.126.98.204" _
            , "205.188.185.33" _
        }
    
        Public Shared LastHost As String = ""
        Public Shared LastSysTime As DateTime
    
        Public Shared Function GetTime() 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
            ' LastSysTime contains the system time of the call
            ' If LastSysTime 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
    
            LastHost = ""
            For Each host In Servers
                result = GetNISTTime(host)
                If result > DateTime.MinValue Then
                    LastHost = host
                    Exit For
                End If
            Next
    
            If LastHost = "" Then
                'No server in list was successful so use system time
                result = DateTime.UtcNow()
            End If
    
            Return result
        End Function
    
        Public Shared Function SecondsDifference(ByVal dt1 As DateTime, ByVal dt2 As DateTime) As Integer
            Dim span As TimeSpan = dt1.Subtract(dt2)
            Return span.Seconds + (span.Minutes * 60) + (span.Hours * 360)
        End Function
    
        Public Shared Function WindowsClockIncorrect() As Boolean
            Dim nist As DateTime = GetTime()
            If (Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS) Then
                Return True
            End If
            Return False
        End Function
    
        Private Shared Function GetNISTTime(ByVal host As String) As DateTime
            'Returns DateTime.MinValue if host unreachable or does not produce time
            Dim result As DateTime
            Dim timeStr As String
    
            Try
                Dim reader As New StreamReader(New TcpClient(host, 13).GetStream)
                LastSysTime = DateTime.UtcNow()
                timeStr = reader.ReadToEnd()
                reader.Close()
            Catch ex As SocketException
                'Couldn't connect to server, transmission error
                Debug.WriteLine("Socket Exception [" & host & "]")
                Return DateTime.MinValue
            Catch ex As Exception
                'Some other error, such as Stream under/overflow
                Return DateTime.MinValue
            End Try
    
            'Parse timeStr
            If (timeStr.Substring(38, 9) <> "UTC(NIST)") Then
                'This signature should be there
                Return DateTime.MinValue
            End If
            If (timeStr.Substring(30, 1) <> "0") Then
                'Server reports non-optimum status, time off by as much as 5 seconds
                Return DateTime.MinValue    'Try a different server
            End If
    
            Dim jd As Integer = Integer.Parse(timeStr.Substring(1, 5))
            Dim yr As Integer = Integer.Parse(timeStr.Substring(7, 2))
            Dim mo As Integer = Integer.Parse(timeStr.Substring(10, 2))
            Dim dy As Integer = Integer.Parse(timeStr.Substring(13, 2))
            Dim hr As Integer = Integer.Parse(timeStr.Substring(16, 2))
            Dim mm As Integer = Integer.Parse(timeStr.Substring(19, 2))
            Dim sc As Integer = Integer.Parse(timeStr.Substring(22, 2))
    
            If (jd < 15020) Then
                'Date is before 1900
                Return DateTime.MinValue
            End If
            If (jd > 51544) Then yr += 2000 Else yr += 1900
    
            Return New DateTime(yr, mo, dy, hr, mm, sc)
    
        End Function
    
        <StructLayout(LayoutKind.Sequential)> _
        Public 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
    
        Private Declare Function GetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32
        Private Declare Function SetSystemTime Lib "kernel32.dll" (ByRef stru As SYSTEMTIME) As Int32
    
        Public Shared Sub SetWindowsClock(ByVal dt As DateTime)
            'Sets system time. Note: Use UTC time; Windows will apply time zone
    
            Dim timeStru As SYSTEMTIME
            Dim result As Int32
    
            timeStru.wYear = CType(dt.Year, Int16)
            timeStru.wMonth = CType(dt.Month, Int16)
            timeStru.wDay = CType(dt.Day, Int16)
            timeStru.wDayOfWeek = CType(dt.DayOfWeek, Int16)
            timeStru.wHour = CType(dt.Hour, Int16)
            timeStru.wMinute = CType(dt.Minute, Int16)
            timeStru.wSecond = CType(dt.Second, Int16)
            timeStru.wMilliseconds = CType(dt.Millisecond, Int16)
    
            result = SetSystemTime(timeStru)
    
        End Sub
    End Class
    

    Incluso ahí podrías agregar otros servidores para obtener la fecha de internet


    Javier

    martes, 12 de julio de 2016 17:45
  • Acabo de crearla así como me dices, sin embargo, al ejecutar mi programa me muestra un mensaje diciendome 'Intento de leer o escribir en la memoria protegida. A menudo, esto indica que hay otra memoria dañada' Sabes el por qué del mensaje? Agradecería tu ayuda, ya que esto se me está complicando un poco
    martes, 12 de julio de 2016 17:57
  • Intenta hacer clean a tu proyecto y luego Rebuild, click derecho en tu solución y prmero selecciona CLEAN y luego REBUILD.

    Suerte


    Javier

    martes, 12 de julio de 2016 18:02
  • Revisando rápidamente el código, vi que posiblemente podría estar aquí una falla que no permitía hacer las cosas para que no me generara error

    Public Shared Function WindowsClockIncorrect() As Boolean
            Dim nist As DateTime = GetTime()
            If (Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS) Then
                Return True
            End If
            Return False
        End Function

    Solo agregué un else dejando así la función

    Public Shared Function WindowsClockIncorrect() As Boolean Dim nist As DateTime = GetTime() If (Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS) Then Return True

    else

    Return False End If End Function

    Ahora no me marca error, pero no cambia la hora al sistema, podría solamente obtener la fecha de un servidor y ocuparla en alguna parte de mi programa si fuera necesario?

    martes, 12 de julio de 2016 18:15
  • Claro que sí, en la función GetTime() de la clase ahí revisa, si tienes un servidor específico no habría problema a que lo hagas ahí mismo. 
    Public Shared Function GetTime() 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
            ' LastSysTime contains the system time of the call
            ' If LastSysTime 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
    
            LastHost = ""
            For Each host In Servers
                result = GetNISTTime("Aqui tu servidor")
                If result > DateTime.MinValue Then
                    LastHost = host
                    Exit For
                End If
            Next
    
            If LastHost = "" Then
                'No server in list was successful so use system time
                result = DateTime.UtcNow()
            End If
    
            Return result
        End Function
    Saludos

    Javier

    • Marcado como respuesta danielneria martes, 12 de julio de 2016 19:00
    martes, 12 de julio de 2016 18:22
  • Dicho sea de paso, windows sincroniza contra un servidor ntp, si la conexión a internet está disponible.

    Si haces doble clic en la hora de la barra de tareas, clic en cambiar la configuración de fecha y hora, clic en la pestaña Hora de internet, clic en cambiar configuración, mira si el checkbox Sincronizar con un servidor horario de internet está marcada.

    Incluso creo recordar que existe un api para que el sistema corra tu propia rutina contra el servidor.

    martes, 12 de julio de 2016 18:38
  • Ok, lo checo, la verdad es que me cuesta un poco entenderle a esto de obtener la fecha, pero con más práctica lo entenderé. Gracias por la ayuda, me sirvió de mucho. Saludos
    martes, 12 de julio de 2016 19:34
  • La casilla de verificacipon está marcada, la hora de mi sistema está dada por internet, sin embargo, necesito obtener la fecha de internet para poder usarla y de ser posible, aplicarla al sistema. gracias por tu ayuda también. Saludos
    martes, 12 de julio de 2016 19:37
  • Hola ! Me sale este error : startIndex no puede ser mayor que la longitud de la cadena.

    Que sera?

    miércoles, 10 de octubre de 2018 16:40