How do I get the server time or the current time of day and change in the system via code?

0

I need to update an O.S system with the time of another micro, in case this other micro would be a server. I would like to do this via code.

Another method that would also help would be to pick the right time of the day and compare it to the one of the computer that will be running the program.

    
asked by anonymous 16.02.2015 / 18:54

2 answers

0

Code in VB.NET Source: link

 Public Shared Function GetNetworkTime() As DateTime
        'Servidor nacional para melhor latência
        Const ntpServer As String = "a.ntp.br"

        ' Tamanho da mensagem NTP - 16 bytes (RFC 2030)
        Dim ntpData = New Byte(47) {}

        'Indicador de Leap (ver RFC), Versão e Modo
        ntpData(0) = &H1B
        'LI = 0 (sem warnings), VN = 3 (IPv4 apenas), Mode = 3 (modo cliente)
        Dim addresses = Dns.GetHostEntry(ntpServer).AddressList

        '123 é a porta padrão do NTP
        Dim ipEndPoint = New IPEndPoint(addresses(0), 123)
        'NTP usa UDP
        Dim socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

        socket.Connect(ipEndPoint)

        'Caso NTP esteja bloqueado, ao menos nao trava o app
        socket.ReceiveTimeout = 3000

        socket.Send(ntpData)
        socket.Receive(ntpData)
        socket.Close()

        'Offset para chegar no campo "Transmit Timestamp" (que é
        'o do momento da saída do servidor, em formato 64-bit timestamp
        Const serverReplyTime As Byte = 40

        'Pegando os segundos
        Dim intPart As ULong = BitConverter.ToUInt32(ntpData, serverReplyTime)

        'e a fração de segundos
        Dim fractPart As ULong = BitConverter.ToUInt32(ntpData, serverReplyTime + 4)

        'Passando de big-endian pra little-endian
        intPart = SwapEndianness(intPart)
        fractPart = SwapEndianness(fractPart)

        Dim milliseconds = (intPart * 1000) + ((fractPart * 1000) / &H100000000L)

        'Tempo em **UTC**
        Dim networkDateTime = (New DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds(CLng(milliseconds))

        Return networkDateTime.ToLocalTime()
    End Function

    ' stackoverflow.com/a/3294698/162671
    Private Shared Function SwapEndianness(x As ULong) As UInteger
        Return CUInt(((x And &HFF) << 24) + ((x And &HFF00) << 8) + ((x And &HFF0000) >> 8) + ((x And &HFF000000UI) >> 24))
    End Function
    
16.02.2015 / 19:22
1
class Program
{
    //necessário privilégio administrador
    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    public extern static bool Win32SetSystemTime(ref SystemTime sysTime);

    [DllImport("kernel32.dll", EntryPoint = "GetSystemTime", SetLastError = true)]
    public extern static void Win32GetSystemTime(ref SystemTime sysTime);

    public struct SystemTime
    {
        public ushort Year;
        public ushort Month;
        public ushort DayOfWeek;
        public ushort Day;
        public ushort Hour;
        public ushort Minute;
        public ushort Second;
        public ushort Millisecond;
    }

    private static void Main()
    {
        //servidor intranet "user-PC" (local)
        //a.ntp.br (internet) 
        //var localDateTime = PegarDtHoraRedeLocal("user-PC");
        var horaAtual = PegarDtHoraAtualizada("a.ntp.br");

        //AJUSTA HORA BASEADO NO FUSO HORARIO DO COMPUTADOR LOCAL
        SetTime(horaAtual.ToUniversalTime());
        Console.ReadKey();
    }

    public static DateTime PegarDtHoraAtualizada(string ntpServer)
    {
        var ntpData = new byte[48];
        ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)

        //somente IPV4
        var addresses = Dns.GetHostEntry(ntpServer).AddressList.First(a => a.AddressFamily == AddressFamily.InterNetwork);

        var ipEndPoint = new IPEndPoint(addresses, 123);
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        socket.ReceiveTimeout = 5000; //5 segundos timeout
        socket.Connect(ipEndPoint);
        socket.Send(ntpData);
        socket.Receive(ntpData);
        socket.Close();

        ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | ntpData[43];
        ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | ntpData[47];

        var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
        var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long) milliseconds).ToLocalTime();

        //ajustando para hora brasil teste ajuste independente do fuso horario
        //networkDateTime = DateTime.ParseExact(networkDateTime.ToString(), "dd/M/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
        return networkDateTime;
    }

    private static void SetTime(DateTime dataHoraAtualizada)
    {
        // Prepare native method with the defined structure.
        var st = new SystemTime
        {
            Year = (ushort) (dataHoraAtualizada.Year),
            Month = (ushort) (dataHoraAtualizada.Month),
            Hour = (ushort) (dataHoraAtualizada.Hour),
            Day = (ushort) (dataHoraAtualizada.Day),
            Minute = (ushort) (dataHoraAtualizada.Minute),
            Second = (ushort) (dataHoraAtualizada.Second)
        };

        // Set the system date time.
        var resp = Win32SetSystemTime(ref st);
        Debug.Print(resp.ToString());
    }
}
  

I need to update an O.S system with the time of another micro, if this   another micro would be a server. I would like to do this via code.

var localDateTime = PegarDtHoraRedeLocal("user-PC"); //user-PC: nome servidor sua rede local
//AJUSTA HORA BASEADO NO FUSO HORARIO DO COMPUTADOR LOCAL
SetTime(horaAtual.ToUniversalTime());

OBS:

  • The Windows Time Service (W32Time) works as the server responsible for providing the time, so it must be started; Home
  • I tested the computer locally with WINXP SP3 and WIN7 (Professional). XPSP3 does not need additional configuration; Home
  • To configure WIN7 (as NTP server - Network Time Protocol) follow the steps below:

    3.1 Stop the service (W32Time - Windows Time), either by service manager or by net stop w32time command prompt

    3.2 Open the windows registry regedit.exe

    3.3 Navigate to the HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ W32Time \ Config \ AnnounceFlags key and change the value of 10 to 5 br> 3.4 Navigate to the HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ W32Time \ TimeProviders \ NtpServer key and change the value to 1

    3.5 Start the service (W32Time - Windows Time) net start w32time

    3.6 To verify that the NTP server is configured correctly, type in the command prompt w32tm / query / configuration and see if the image below appears is configured

  •   

    Anothermethodthatwouldalsohelpwouldbetopicktherighttimeofthedayand  comparetothatoftheComputerthatwillberunningtheprogram.

    Hereyougettherighttimeofthedayandcancomparewithyourserver@felipe-walleg

    varhoraAtual=PegarDtHoraAtualizada("a.ntp.br"); //Hora atualizada pela internet    
    //AJUSTA HORA BASEADO NO FUSO HORARIO DO COMPUTADOR LOCAL
    SetTime(horaAtual.ToUniversalTime());
    


    Sources:
    link link link

        
    18.02.2015 / 03:31