Il modo migliore per impostare data e ora sulla macchina Windows dall'applicazione java


Sto lavorando con un'applicazione java agent ed è installata su diverse macchine Windows in diversi luoghi del mondo. Vorrei sincronizzare periodicamente l'orologio di Windows (data e ora). Ho già trovato il comando nativo per impostare l'ora in Windows in base al codice java:

Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss

O eseguire

Runtime.getRuntime().exec("cmd /C date " + strDateToSet + "& time " + strTimeToSet);

Ma il problema principale è focalizzato sulla data impostata, perché è possibile che il formato della data sulle macchine Windows non sia lo stesso per tutte le macchine. Ad esempio potrei avere gg-MM-aaper la macchina italiana e aa-MM-gg per la macchina statunitense. Quindi se la mia applicazione imposta la data con il formato gg-MM-aa wuold essere sbagliato per noi macchina.

Sapendo che non posso usare NTP (macchine in LAN con Firewall senza regole solo protocollo HTTPS port 443) come posso impostare correttamente la data dall'applicazione java per tutte le macchine Windows ? Qual è la soluzione migliore sia per semplicità che per manutenibilità ?

Nota: Agente java l'applicazione ha già il timestamp da impostare sul computer Windows passato dalla risposta del servizio Web, quindi è necessario solo eseguire setDateAndTime

TEST comando data exec con formato data aaaa-MM-gg su Windows (impostare data errata): inserisci qui la descrizione dell'immagine

Author: Stefano, 2017-04-25

1 answers

Ho provato ad implementare la soluzione con JNA importando kernel32.dll ha eseguito il test sulla macchina Windows 7 con fuso orario UTC + 1 (Italia paese).

Descrivo i passaggi:

1, Ho importato il mio progetto maven le dipendenze seguite:

<dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>4.4.0</version>
</dependency>
<dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>4.3.0</version>
</dependency>

2) Ho implementato la classe seguita:

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinBase.SYSTEMTIME;
import com.sun.jna.win32.StdCallLibrary;


@Component
@Qualifier("windowsSetSystemTime")
public class WindowsSetSystemTime {

    /**
     * Kernel32 DLL Interface. kernel32.dll uses the __stdcall calling
     * convention (check the function declaration for "WINAPI" or "PASCAL"), so
     * extend StdCallLibrary Most C libraries will just extend
     * com.sun.jna.Library,
     */
    public interface Kernel32 extends StdCallLibrary {

        boolean SetLocalTime(SYSTEMTIME st);

        Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32.dll", Kernel32.class);

    }

    public boolean SetLocalTime(SYSTEMTIME st) {
        return Kernel32.instance.SetLocalTime(st);
    }

    public boolean SetLocalTime(short wYear, short wMonth, short wDay, short wHour, short wMinute, short wSecond) {
        SYSTEMTIME st = new SYSTEMTIME();
        st.wYear = wYear;
        st.wMonth = wMonth;
        st.wDay = wDay;
        st.wHour = wHour;
        st.wMinute = wMinute;
        st.wSecond = wSecond;
        return SetLocalTime(st);
    }
}

3) Dalla classe di test ho provato a impostare la data e l'ora seguite

public void setTime(){
        System.out.println("START SYNC " + windowsSetSystemTime);

        windowsSetSystemTime.SetLocalTime((short)2017, (short)10,(short) 29,(short) 11,(short) 35,(short) 0);
    }

RISULTATO DEL TEST: Come risultato in questo caso ho ottenuto la data e l'ora corrette perché il funzione considerata daylight risparmio di tempo invernale che entrano a 29 Ottobre 2017 3:00.

Prima del test, l'orologio è stato impostato:

inserisci qui la descrizione dell'immagine

Dopo l'orologio di prova impostato:

inserisci qui la descrizione dell'immagine

Ho scoperto il metodo logic SetLocalTime in Kernel32.dll per la documentazione del centro sviluppo di Windows al link: Documentazione SetLocalTime

Centro sviluppo di Windows OSSERVAZIONI SetLocalTime:

Il sistema utilizza UTC internamente. Quindi, quando si chiama SetLocalTime, il sistema utilizza le informazioni sul fuso orario corrente per eseguire la conversione, inclusa l'impostazione dell'ora legale. Si noti che il sistema utilizza l'impostazione dell'ora legale dell'ora corrente, non la nuova ora impostata. Pertanto, per garantire il risultato corretto, chiamare SetLocalTime una seconda volta, ora che la prima chiamata ha aggiornato l'impostazione dell'ora legale.

 2
Author: Stefano, 2017-05-03 07:20:02