<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 17133 -->
<!-- Reviewed: no -->
<sect1 id="zend.timesync.working">

    <title>Arbeiten mit Zend_TimeSync</title>

    <para>
        <classname>Zend_TimeSync</classname> kann die aktuelle Zeit von jedem angegebenen
        <emphasis>NTP</emphasis> oder <emphasis>SNTP</emphasis>
        Zeitserver zurückgeben. Es kann automatisch mehrere Server handhaben und bietet ein
        einfaches Interface.
    </para>

    <note>
        <para>
            Alle Beispiele in diesem Kapitel verwenden einen öfentlichen, generellen
            Zeitserver: <emphasis>0.europe.pool.ntp.org</emphasis>.
            Man sollte einen öffentlichen, generellen Zeitserver verwenden der in der Nähe
            des eigenen Anwendungsservers steht. Siehe
            <ulink url="http://www.pool.ntp.org">http://www.pool.ntp.org</ulink> für Informationen.
        </para>
    </note>

    <sect2 id="zend.timesync.working.generic">

        <title>Generelle Anfragen von Zeitserver</title>

        <para>
            Die Anfrage der Zeit von einem Zeitserver ist einfach. Zuerst gibt man den Zeitserver an
            von dem man die Zeit anfragen will.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync('0.pool.ntp.org');

print $server->getDate()->getIso();
]]></programlisting>

        <para>
            Was passiert also im Hintergrund von <classname>Zend_TimeSync</classname>? Zuerst wird
            der Syntax des Timeservers geprüft. In unserem Beispiel wird also
            '<code>0.pool.ntp.org</code>' geprüft und als möglicherweise richtige Adresse für einen
            Zeitserver erkannt. Wenn jetzt <methodname>getDate()</methodname> aufgerufen wird, wird
            der aktuell gesetzte Zeitserver angefragt und er gibt seine eigene Zeit zurück.
            <classname>Zend_TimeSync</classname> berechnet darauf die Differenz zur aktuellen Zeit
            des Servers auf dem das Skript läuft und gibt ein <classname>Zend_Date</classname>
            Objekt mit der korrigierten Zeit zurück.
        </para>

        <para>
            Für Details über <classname>Zend_Date</classname> und dessen Methoden siehe unter der
            Dokumentation von <link
                linkend="zend.date.introduction"><classname>Zend_Date</classname></link> nach.
        </para>

    </sect2>

    <sect2 id="zend.timesync.working.multiple">

        <title>Mehrere Zeitserver</title>

        <para>
            Nicht alle Zeitserver sind immer erreichbar und geben Ihr Zeit zurück. Server können
            wärend Ihrer Wartung nicht erreichbar sein. Senn die Zeit nicht vom Zeitserver angefragt
            werden kann, erhält man eine Ausnahme.
        </para>

        <para>
            <classname>Zend_TimeSync</classname> ist eine einfache Lösung die mehrere Zeitserver
            behandeln kann und einen automatischen Fallback Mechanismus bietet. Es gibt zwei
            unterstützte Wege; man kann entweder ein Array von Zeitserver angeben wenn die Instanz
            erstellt wird, oder zusätzliche Zeitserver zur Instanz durch Verwendung der
            <methodname>addServer()</methodname> Methode hinzufügen.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('0.pool.ntp.org',
                                  '1.pool.ntp.org',
                                  '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org');

print $server->getDate()->getIso();
]]></programlisting>

        <para>
            Es gibt keine Begrenzung in der Anzahl an Zeitservern die hinzugefügt werden können.
            Wenn ein Zeitserver nicht erreicht werden kann, dann fällt
            <classname>Zend_TimeSync</classname> zurück und versucht den nächsten Zeitserver zu
            erreichen.
        </para>

        <para>
            Wenn man mehr als einen Zeitserver angibt - was die beste Praxis für
            <classname>Zend_TimeSync</classname> ist - sollte man jeden Server benennen. Man kann
            die Server mit dem Arrayschlüssel, mit dem zweiten Parameter wärend der Initiierung oder
            mit dem zweiten Parameter beim Hinzufügen von anderen Zeitservern, benennen.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('generic'  => '0.pool.ntp.org',
                                  'fallback' => '1.pool.ntp.org',
                                  'reserve'  => '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org', 'additional');

print $server->getDate()->getIso();
]]></programlisting>

        <para>
            Die Benennung der Zeitserver gibt die Möglichkeit das ein spezieller Zeitserver
            angefragt werden kann wie man später in diesem Kapitel sieht.
        </para>

    </sect2>

    <sect2 id="zend.timesync.working.protocol">

        <title>Protokolle von Zeitservern</title>

        <para>
            Es gibt verschiedene Typen von Zeitservern. Die meisten öffentlichen Zeitserver
            verwenden <emphasis>NTP</emphasis> als Protokoll. Es sind auch
            andere Zeit Synchronisations Prtokolle vorhanden.
        </para>

        <para>
            Man kann das richtige Prokoll mit der Adresse des Zeitservers setzen. Aktuell gibt
            es zwei Prokolle die von <classname>Zend_TimeSync</classname> unterstützt werden:
            <emphasis>NTP</emphasis> und <emphasis>SNTP</emphasis>. Das
            Standardprotokoll ist <emphasis>NTP</emphasis>. Wenn man nur <emphasis>NTP</emphasis>
            verwendet kann das Protkoll in der Adresse, wie im vorherigen Beispiel gezeigt,
            unterdrücken.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org',
                                  'reserve'  => 'ntp:\\2.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();
]]></programlisting>

        <para>
            <classname>Zend_TimeSync</classname> kann gemischte Zeitserver verwenden. Man ist also
            nicht auf ein einzelnes Prokoll beschränkt, aber man kann jeden Zeitserver unabhängig
            von seinem Protokoll hinzufügen.
        </para>

    </sect2>

    <sect2 id="zend.timesync.working.ports">

        <title>Ports für Zeitserver verwenden</title>

        <para>
            Wie bei jedes Protkoll im World Wide Web, verwenden das
            <emphasis>NTP</emphasis> und <emphasis>SNTP</emphasis>
            Protokoll Standardports. NTP verwendet den Port <emphasis>123</emphasis>,
            und SNTP den Port <emphasis>37</emphasis>.
        </para>

        <para>
            Aber manchmal differiert der Port den das Protokoll verwendet von Standard. Der zu
            verwendende Port kann mit der Adresse für jeden Server definiert werden. Es muß nur
            die Nummer des Ports nach der Adresse hinzugefügt werden. Wenn kein Port definiert
            wurde, dann verwendet <classname>Zend_TimeSync</classname> den Standardport.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org:200',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com:399', 'additional');

print $server->getDate()->getIso();
]]></programlisting>

    </sect2>

    <sect2 id="zend.timesync.working.options">

        <title>Optionen für Zeitserver</title>

        <para>
            Es gibt nur eine Option in <classname>Zend_TimeSync</classname> die intern verwendet
            wird: <emphasis>timeout</emphasis>. Man kann aber beliebige selbstdefinierte
            Optionen verwenden wenn man will und diese auch Abfragen.
        </para>

        <para>
            Die Option <emphasis>timeout</emphasis> definiert die Anzahl an Sekunden
            nach der eine Verbindung als Abgebrochen erkannt wird wenn keine Antwort kommt. Der
            Standardwert ist <emphasis>1</emphasis>, was bedeutet das
            <classname>Zend_TimeSync</classname> auf den nächsten Zeitserver zurückfällt wenn der
            angefragte Server nicht in einer Sekunde antwortet.
        </para>

        <para>
            Mit der <methodname>setOptions()</methodname> Methode kann jede Option gesetzt werden.
            Diese Funktion akzeptiert ein Array wobei die Schlüssel die zu setzende Option sind und
            der Wert der Wert dieser Option. Jede vorher gesetzte Option wird mit dem neuen Wert
            überschrieben. Wenn man wissen will welche Optionen gesetzt sind, kann die
            <methodname>getOptions()</methodname> Methode verwendet werden. Sie akzeptiert entweder
            einen Schlüssel welcher die gegebene Option zurückgibt wenn diese gesetzt ist, oder,
            wenn kein Schlüssel angegeben wird, gibt Sie alle gesetzten Optionen zurück.
        </para>

        <programlisting language="php"><![CDATA[
Zend_TimeSync::setOptions(array('timeout' => 3, 'myoption' => 'timesync'));
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();
print_r(Zend_TimeSync::getOptions();
print "Timeout = " . Zend_TimeSync::getOptions('timeout');
]]></programlisting>

        <para>
            Wie man sieht sind die Optionen für <classname>Zend_TimeSync</classname> statisch. Jede
            Instanz von <classname>Zend_TimeSync</classname> verwendet die gleichen Optionen.
        </para>

    </sect2>

    <sect2 id="zend.timesync.working.different">

        <title>Verschiedene Zeitserver verwenden</title>

        <para>
            <classname>Zend_TimeSync</classname>'s Standardverhalten für die Anfrage einer Zeit ist
            diese vom ersten gegebenen Server anzufragen. Manchmal ist es aber sinnvoll einen
            anderen Zeitserver zu setzen von dem die Zeit abgefragt werden soll. Das kann mit der
            <methodname>setServer()</methodname> Methode getan werden. Um den zu verwendenden
            Zeitserver zu definieren muß einfach der Alias als Parameter in dieser Methode gesetzt
            werden. Und um den aktuell verwendeten Zeitserver zu erhalten kann die
            <methodname>getServer()</methodname> Methode aufgerufen werden. Wenn kein Parameter
            angegeben wird, wird der aktuelle Zeitserver zurückgegeben.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

$actual = $server->getServer();
$server = $server->setServer('additional');
]]></programlisting>

    </sect2>

    <sect2 id="zend.timesync.working.informations">

        <title>Informationen von Zeitservern</title>

        <para>
            Zeitserver bieten nicht nur die Zeit selbst sondern auch zusätzliche Informationen.
            Man kann diese Informationen mit der <methodname>getInfo()</methodname> Methode
            erhalten.
        </para>

        <programlisting language="php"><![CDATA[
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));

print_r ($server->getInfo());
]]></programlisting>

        <para>
            Die zurückgegebenen Informationen unterscheiden sich im verwendeten Protokoll und sie
            unterscheiden sich auch im verwendeten Server.
        </para>

    </sect2>

    <sect2 id="zend.timesync.working.exceptions">

        <title>Behandeln von Ausnahmen</title>

        <para>
            Ausnahmen werden für alle Zeitserver gesammelt und werden als Array zurückgegeben. Es
            ist also möglich durch alle geworfenen Ausnahmen zu laufen wie im folgenden Beispiel
            gezeigt:
        </para>

        <programlisting language="php"><![CDATA[
$serverlist = array(
        // invalid servers
        'invalid_a'  => 'ntp://a.foo.bar.org',
        'invalid_b'  => 'sntp://b.foo.bar.org',
);

$server = new Zend_TimeSync($serverlist);

try {
    $result = $server->getDate();
    echo $result->getIso();
} catch (Zend_TimeSync_Exception $e) {

    $exceptions = $e->get();

    foreach ($exceptions as $key => $myException) {
        echo $myException->getMessage();
        echo '<br />';
    }
}
]]></programlisting>
    </sect2>
</sect1>