Abgleich von Datum und Zeit des Rechners
mit einem externen Zeitserver

Dieses JAVA-Programm holt die aktuelle Zeit vom Zeitserver der
Physikalisch-Technischen Bundesanstalt (PTB) in Braunschweig und
setzt die Zeit unter MS Windows (ab Version NT).

In der ersten While-Schleife wird die Zeit vom Zeitserver geholt.
(Standard: ptbtime1.ptb.de)
Bei Verwendung eines anderen Zeitservers (z.B. als Argument von main)
muss auf korrekte Schreibweise geachtet werden,
damit es nicht zu einer Endlos-Schleife kommt.

Anschließend erfolgt der Vergleich mit der aktuellen Rechnerzeit.

In der zweiten While-Schleife wird bei einer Abweichung von mehr als 10 Sekunden
200-mal (siehe Variable j) versucht,
das Datum und die Zeit des Rechners auf die vom Zeitserver geholten Werte zu setzen.
Der Abbruch nach 200-mal erfolgt auch deswegen,
damit Anwender ohne Recht, Datum und Zeit zu ändern,
nicht in einer Endlos-Schleife bleiben.
Man sollte also selbst Administrator sein oder von ihm dieses Recht erteilt bekommen haben.

Unter JAVA sind normalerweise keine Änderungen am Betriebssystem erlaubt.
Es ist allerdings möglich,
Programme auf dem Rechner mittels der Runtime-Klasse zu starten.
Allerdings geht dabei die Plattform-Unabhängigkeit von JAVA verloren.

Unter MS Windows sind die Befehle date und time keine eigenständige Programme (*.exe oder *.com),
sondern Bestandteil des Kommando-Interpreters.
Sie werden von der DOS-Konsole cmd.exe (ältere Windows-Versionen: command.com) gestartet.

Vom JAVA-Programm wird der komplette Befehl mit Wert (12.00 Uhr)
über die Runtime-Klasse an Windows gesendet:
Process p1 = Runtime.getRuntime().exec("cmd.exe /c time 12:00:00");
Deswegen ist auch keine direkte Synchronisation mit dem JAVA-Programm möglich.

Für andere Betriebssysteme muss die Befehls-Zeichenkette entsprechend angepasst werden.

Unter UNIX / LINUX bietet sich generell folgender Befehl zum Zeitsetzen an:
ntpdate ptbtime1.ptb.de
Standardmäßig geht es mit:
date MMDDhhmmJJJJ.ss
date -s "MM DD hh:mm:ss JJJJ"
date -s "Jan 1 12:00:00 2011"

Quelltext für das Java-Programm:atomzeit.java

// atomzeit.java - Applikation zum Ermitteln und Setzen der Zeit unter Windows
 
import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
 
public class atomzeit
{
public static void main( String[] args )
{
final StringTIME_SERVER = "ptbtime1.ptb.de";
final SimpleDateFormatGESAMTFORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
final SimpleDateFormatDATUMFORMAT = new SimpleDateFormat("dd-MM-yyyy");
final SimpleDateFormatZEITFORMAT = new SimpleDateFormat("HH:mm:ss");
final longSEKUNDEN_1900_1970 = 2208988800L;
Socketso = null;
InputStreamin = null;
longtime = 0;
Datedate_atom = new Date(1);
Datedate_pc = new Date();
Stringbefehl = null;
Stringzeit = null;
Stringdatum = null;
intj = 200;// Anzahl der Versuche zum Zeitsetzen
 
while ( date_atom.getTime() < 2 ) {
try
{
so = new Socket( ( args.length > 0 ) ? args[0] : TIME_SERVER, 37 );
in = so.getInputStream();
for ( int i = 3; i >= 0; i-- ) {
time ^= (long) in.read() << i * 8;
}
 
// Der Time Server gibt die Sekunden seit 1900 aus, JAVA erwartet Millisekunden seit 1970
date_atom = new Date( (time - SEKUNDEN_1900_1970) * 1000 );
date_pc = new Date();
 
} catch ( Exception ex )
{} finally {
if ( in != null ) try { in.close(); } catch ( IOException ex ) {}
if ( so != null ) try { so.close(); } catch ( IOException ex ) {}
}
}// Ende Whilebei erfolgreicher Zeit-Übergabe
 
System.out.println();
System.out.println("Atomzeit: " + GESAMTFORMAT.format(date_atom) );
System.out.println("Rechner-Zeit: " + GESAMTFORMAT.format(date_pc) );
System.out.println("Differenz (in sek) : " + (date_atom.getTime() - date_pc.getTime()) / 1000 );
System.out.println();
 
//Datum und Zeit setzen, wenn Abweichung mehr als +- 10 Sekunden
while (((date_atom.getTime() - date_pc.getTime()) < -10000) ||
((date_atom.getTime() - date_pc.getTime()) > 10000)){
 
j--;
befehl = "cmd.exe /c time ";
zeit = ZEITFORMAT.format(date_atom);
 
try
{
Process p1 = Runtime.getRuntime().exec(befehl + zeit);
} catch (Exception ex) {}
 
befehl = "cmd.exe /c date ";
datum = DATUMFORMAT.format(date_atom);
 
try
{
Process p2 = Runtime.getRuntime().exec(befehl + datum);
} catch (Exception ex) {}
 
date_pc = new Date();
 
if ( j == 0 ) {
System.out.println("Fehler: Rechnerzeit nicht gesetzt!evtl. kein Administrator");
System.out.println();
break;
}
 
}// Ende Whilebeim erfolgreichen Zeit-Setzen oder j=0
 
System.out.println("Rechner-Zeit neu : " + GESAMTFORMAT.format(date_pc));
}
}

Die Ausgabe im DOS-Fenster könnte so aussehen:


Atomzeit           : 02.11.2011 13:44:15
Rechner-Zeit       : 10.01.2011 23:12:32
Differenz (in sek) : 25540302

Rechner-Zeit  neu  : 02.11.2011 13:44:15