Spanish [ESP8266] Requesting time from a server

jwgf

Member

josejad

Expert
Licensed User
Longtime User
Hola:

Por lo que veo en el ejemplo que indicas, derez utiliza la función find_offset para ver según la fecha si tiene una diferencia de 2 o 3 horas. Sí tú tienes siempre 3 horas y no hay cambio de hora, entiendo que tu corrección será simplemente restar 3 a la hora que obtengas, por lo que el código de derez quedaría así:

B4X:
              ...
               hour = st2
               Dim y As Short = year - 17
               offset = -3
               If hour + offset >= 24 Then add = True Else add = False ' add =true will change the date later on in the code
...
               hour = hour + offset
If hour >= 24 Then
        hour = hour Mod 24
        day = day + 1
End If
               ....
 

jwgf

Member
Gracias José, bueno he tratado de mantener el código de Erel, modificando lo menos posible, ya que lo genial de su código es que convierte la hora leída desde el servidor a milisegundos, luego de esa forma es muy sencillo llevar el "seguimiento del tiempo", entiendo que no era tan fácil como sumar un día cuando la hora es mayor a 24, ya que en el caso de ser mas de las 24 la lectura del servidor me daría un nuevo día, mientras que en mi zona horaria faltarían 3 horas para un nuevo día, por lo que guardo los valores por separado de día, mes y año y luego cuando pido la hora veo si tengo que corregir el día
B4X:
Private Sub Connect(u As Byte)
    Log("Connecting to NIST server...")
    If socket.ConnectHost("time.nist.gov", 13) Then
        astream.Initialize(socket.Stream, "astream_NewData", "astream_Error")
    Else
        Log("Failed to connect to NIST server")
        CallSubPlus("Connect", 1000, 0)
    End If
End Sub


Private Sub AStream_NewData (Buffer() As Byte)
    'Log("El buffer es " ,Buffer)
    Dim i As Byte = 0
    
    For Each s() As Byte In bc.Split(Buffer, " ")
        Select i
            Case 1
                Dim cdor As Byte = 0               
                For Each s2() As Byte In bc.Split(s, "-")
                    If cdor = 0 Then
                        Main.anno = bc.StringFromBytes(s2)
                        cdor = cdor + 1
                    Else If cdor = 1 Then
                        Main.mes =     bc.StringFromBytes(s2)
                        cdor = cdor + 2
                    Else
                        Main.dia = bc.StringFromBytes(s2)
                    End If
                Next
                'bc.ArrayCopy(s, date)
            Case 2
                
                Dim multi As UInt = 3600
                seconds = 0
                For Each s2() As Byte In bc.Split(s, ":")
                    seconds = seconds + multi * bc.StringFromBytes(s2) 'need to convert the bytes into string before they can be parsed as a number
                    'Log("segundos",seconds)
                    multi = multi / 60
                Next
        End Select
        i = i + 1
        lastMillis = Millis
    Next
    socket.Close
    If firstTime Then
        Main.TimeIsAvailable
        firstTime = False
    End If
End Sub

Public Sub GetHours As UInt
    Dim u As UInt = Floor(GetUpdatedTotalSeconds/ 3600)
    If u < 3 Then
        u = 24 - ( 3 - u )
    Else
        u = u - 3   
    End If
    If u > 21 Then 'si la hora es mayor a 21, quiere decir que sumo un dia en UTP
        Main.dia = Main.dia - 1 'resto un dias ya que para mi hora local no paso un dia
    End If
    Return u
End Sub

Ademas necesitaba saber el día de la semana por lo que agregue esta función, luego tengo los datos que necesito
B4X:
Private Sub Clock_Tick
    Log("dia: ",dia,"mes: ",mes,"año",anno)
    'Log("Date: ", TimeNIST.GetDate)
    Log("Time (UTC): ", NumberFormat(TimeNIST.GetHours, 2, 0), ":", NumberFormat(TimeNIST.GetMinutes, 2, 0), _
        ":", NumberFormat(TimeNIST.GetSeconds, 2, 0))
    Log("Dia de la semana: ",DiaDeLaSemana(dia,mes,anno))
        
End Sub

Sub DiaDeLaSemana ( t_dia As Int, t_mes As Int, t_year As Int) As Byte 'Domingo = 0
    Private dow As Byte
    'Private t_mes As Byte 'mes temporal
    Select t_mes
        Case 1,10
            t_mes = 0
            Exit
        Case 2,3,11
            t_mes = 3
            Exit
        Case 4,7
            t_mes = 6
            Exit
        Case 5
            t_mes = 1
            Exit
        Case 6
            t_mes = 4
            Exit
        Case 8
            t_mes = 2
            Exit
        Case 9,12
            t_mes = 5
            Exit
    End Select
    dow = t_dia + t_mes + t_year + (t_year/4) + 6 'el 6 es el siglo 2000 2099
    Return dow Mod 7   
End Sub

Esto funciona bien, claro que no se si si es la mejor forma de hacerlo, espero tu comentario, gracias Jorge
 
Top