<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: 22752 -->
<sect1 id="zend.locale.date.datesandtimes">
    <title>Arbeiten mit Daten und Zeiten</title>

    <para>
        <classname>Zend_Locale_Format</classname> bietet verschiedene Methoden für das Arbeiten mit
        Daten und Zeiten und hilft bei der Konvertierung und Normalisierung zwischen verschiedenen
        Formaten und verschiedenen Gebietsschemata. Benutzen Sie Zend_Date für die Manipulation
        von Datumszeichenketten, die
        bereits übereinstimmen mit <link linkend="zend.date.constants">einem der vielen
        international anerkannten Standardformate, oder einem lokalisierten Datumsformat, welche
        von <classname>Zend_Date</classname> verwendet werden</link>. Die Verwendung von
        vordefinierten Formaten bietet Vorteile, wie die Benutzung von gut getestetem Code, und die
        Sicherheit von Übertragbarkeit und Interoperabilität (abhängig vom benutzten Standard). Das
        unten angeführte Beispiel folgt nicht dieser Empfehlung, da die Benutzung von nicht
        standardmäßigen Datumsformaten die Verständlichkeit der Beispiele unnötig vermindern würde.
    </para>

    <sect2 id="zend.locale.date.normalize">
        <title>Daten und Zeiten normalisieren</title>

        <para>
            Die Methode <methodname>getDate()</methodname> analysiert Zeichenketten, welche Daten in
            einem lokalisierten Format enthalten. Das Ergebnis wird als strukturiertes Array zurück
            gegeben, mit gut definierten Schlüsseln für jeden Teil des Datums. Zusätzlich enthält
            das Array den Schlüssel 'date_format', der den Format-String enthält, der benutzt wurde um
            die Zeichenkette mit dem Eingabedatum zu analysieren. Da ein lokalisiertes Datum nicht
            alle Teile eines Datums oder einer Zeit enthalten muss, sind alle Schlüsselpaare des
            Arrays optional. Wenn zum Beispiel nur Jahr, Monat und Tag gegeben sind, dann werden
            alle Zeitwerte beim zurückgegebenen Array unterdrückt und umgekehrt, wenn nur Stunde,
            Minute und Sekunde als Eingabe angegeben werden. Wenn weder ein Datum noch eine Zeit in
            der Eingabe gefunden werden, dann wird eine Ausnahme geworfen.
        </para>

        <para>
            Wenn <methodname>setOption(array('fix_date' => true))</methodname> gesetzt wird, enthält
            die Methode <methodname>getDate()</methodname> einen Schlüssel 'fixed', der eine Zahl
            enthält, welche anzeigt ob die eingegebene Zeichenkette korrigiert wurde indem Tag, Monat
            oder Jahr getauscht wurden um in das Format zu passen das angegeben wurde.
        </para>

        <table id="zend.locale.date.normalize.table-1">
            <title>Schlüsselwerte für getDate() mit der Option 'fix_date'</title>

            <tgroup cols='2'>
                <thead>
                    <row>
                        <entry>Wert</entry>
                        <entry>Bedeutung</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>0</entry>
                        <entry>Nichts korrigiert</entry>
                    </row>

                    <row>
                        <entry>1</entry>
                        <entry>Falscher Monat wurde korrigiert</entry>
                    </row>

                    <row>
                        <entry>2</entry>
                        <entry>Tag und Jahr wurden getauscht</entry>
                    </row>

                    <row>
                        <entry>3</entry>
                        <entry>Monat und Jahr wurden getauscht</entry>
                    </row>

                    <row>
                        <entry>4</entry>
                        <entry>Monat und Tag wurden getauscht</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            Für jene die ein spezielles Format für Datumseingaben definieren müssen, werden die
            nachfolgend angegebenen Formatzeichen unterstützt. Wenn ein ungültiges Formatzeichen
            verwendet wird, so wie <acronym>PHP</acronym>s 'i'-Zeichen in einem
            <acronym>ISO</acronym>-Format, dann wird ein Fehler von den Methoden geworfen, die
            benutzerdefinierte Formate in <classname>Zend_Locale_Format</classname> unterstützen.
        </para>

        <para>
            Die unten angegebenen Zeichen sind nur ein kleiner Teil des kompletten "ISO"-Sets,
            welches von <classname>Zend_Date</classname>s <methodname>toString()</methodname>
            unterstützt werden. Wenn <acronym>PHP</acronym> <methodname>date()</methodname>
            kompatible Formatzeichen benutzt werden müssen, dann muss zuerst
            <methodname>setOptions(array('format_type' => 'php'))</methodname> aufgerufen werden.
            Und wenn eine spezielle Formatzeichenkette vom <acronym>PHP</acronym>
            <methodname>date()</methodname> kompatiblen Format in ein "ISO"-Format konvertiert
            werden muss, kann <methodname>convertPhpToIsoFormat()</methodname> benutzt werden. Aktuell
            besteht die einzige praktische Differenz darin, dass das Zeichen für Minuten
            unterschiedlich ist ('m' wird im <acronym>ISO</acronym>-Format und 'i' im
            date-Format von <acronym>PHP</acronym> verwendet).
        </para>

        <table id="zend.locale.date.normalize.table-2">
            <title>Rückgabewerte</title>

            <tgroup cols='5'>
                <thead>
                    <row>
                        <entry>getDate() Formatzeichen</entry>
                        <entry>Array-Schlüssel</entry>
                        <entry>Rückgabewert</entry>
                        <entry>Minimum</entry>
                        <entry>Maximum</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>d</entry>
                        <entry>day</entry>
                        <entry>Integer</entry>
                        <entry>1</entry>
                        <entry>31</entry>
                    </row>

                    <row>
                        <entry>M</entry>
                        <entry>month</entry>
                        <entry>Integer</entry>
                        <entry>1</entry>
                        <entry>12</entry>
                    </row>

                    <row>
                        <entry>y</entry>
                        <entry>year</entry>
                        <entry>Integer</entry>
                        <entry>kein Limit</entry>
                        <entry>PHPs Maximum für Integer</entry>
                    </row>

                    <row>
                        <entry>h</entry>
                        <entry>hour</entry>
                        <entry>Integer</entry>
                        <entry>0</entry>
                        <entry>PHPs Maximum für Integer</entry>
                    </row>

                    <row>
                        <entry>m</entry>
                        <entry>minute</entry>
                        <entry>Integer</entry>
                        <entry>0</entry>
                        <entry>PHPs Maximum für Integer</entry>
                    </row>

                    <row>
                        <entry>s</entry>
                        <entry>second</entry>
                        <entry>Integer</entry>
                        <entry>0</entry>
                        <entry>PHPs Maximum für Integer</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <example id="zend.locale.date.normalize.example-1">
            <title>Normalisieren von Daten</title>

            <programlisting language="php"><![CDATA[
$dateString = Zend_Locale_Format::getDate(
    '13.04.2006',
    array(
        'date_format' => 'dd.MM.yyyy',
    )
);

print_r($dateString); // Ausgabe:

Array
(
    [date_format] => dd.MM.yyyy
    [locale] => de_DE
    [day] => 13
    [month] => 04
    [year] => 2006
)

// Erstellt ein Zend_Date Objekt für dieses Datum
$dateObject = new Zend_Date('13.04.2006', 'dd.MM.yyyy');

print_r($dateObject); // Ausgabe

Zend_Date Object
(
    [_locale:Zend_Date:private] => de_DE
    [_fractional:Zend_Date:private] => 0
    [_precision:Zend_Date:private] => 3
    [_unixTimestamp:Zend_Date_DateObject:private] => 1144879200
    [_timezone:Zend_Date_DateObject:private] => Europe/Berlin
    [_offset:Zend_Date_DateObject:private] => -3600
    [_syncronised:Zend_Date_DateObject:private] => 0
    [_dst:protected] => 1
)

// Alternativ können einige Arten von Problemen mit
// den Eingabedaten automatisch korrigiert werden
$date = Zend_Locale_Format::getDate(
    '04.13.2006',
    array(
        'date_format' => 'dd.MM.yyyy',
        'fix_date'    => true,
    )
);

print_r($date); // Ausgabe

Array
(
    [date_format] => dd.MM.yyyy
    [locale] => de_DE
    [day] => 13
    [month] => 04
    [year] => 2006
    [fixed] => 4
)
]]></programlisting>
        </example>

        <para>
            Da <methodname>getDate()</methodname> "lokalisierbar" ist, ist die Angabe von
            <varname>$locale</varname> ausreichend um Datumseingaben einem Gebietsschemaformat
            zuzuordnen. Die Option '<property>fix_date</property>' verwendet einfache Tests um
            herauszufinden ob Tag oder Monat ungültig sind, um dann eine Heuristik anzuwenden, die
            versucht alle gefundenen Probleme zu korrigieren. Anzumerken ist auch die Verwendung von
            '<constant>Zend_Locale_Format::STANDARD</constant>' als Wert für
            '<property>date_format</property>' bei der Funktion
            <methodname>setOptions()</methodname> um zu verhindern, dass das klassenweit gesetzte
            standardmäßige Datumsformat verwendet wird. Das zwingt getDate dazu, das standardmäßige
            Datumsformat dieser <varname>$locale</varname> zu verwenden.
        </para>

        <example id="zend.locale.date.normalize.example-2">
            <title>Normalisieren eines Datums durch ein Gebietsschema</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2006',
                                    array('date_format' =>
                                              Zend_Locale_Format::STANDARD,
                                          'locale' => $locale)
                                   );

print_r ($date);
]]></programlisting>
        </example>

        <para>
            Ein komplettes Datum mit Uhrzeit wird zurückgegeben, wenn die Eingabe beides, ein Datum
            und eine Uhrzeit, im erwarteten Format enthält.
        </para>

        <example id="zend.locale.date.normalize.example-3">
            <title>Normalisieren eines Datums mit Uhrzeit</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2005 22:14:55',
                                    array('date_format' =>
                                                Zend_Locale_Format::STANDARD,
                                          'locale' => $locale
                                    );

print_r ($date);
]]></programlisting>
        </example>

        <para>
            Wenn ein spezielles Format gewünscht ist, muss das <varname>$format</varname> Argument
            definiert werden, ohne der Angabe von <varname>$locale</varname>. Nur die einzelnen
            Zeichen (H, m, s, y, M, d), und MMMM und EEEE werden bei <varname>$format</varname>
            unterstützt.
        </para>

        <example id="zend.locale.date.normalize.example-4">
            <title>Normalisieren eines Benutzerdefinierten Datums</title>

            <programlisting language="php"><![CDATA[
$date = Zend_Locale_Format::getDate('13200504T551422',
                                    array('date_format' =>
                                              'ddyyyyMM ssmmHH')
                                   );

print_r ($date);
]]></programlisting>
        </example>

        <para>
            Ein Format kann die folgenden Zeichen enthalten:
        </para>

        <table id="zend.locale.date.normalize.table-3">
            <title>Formatdefinition</title>

            <tgroup cols='2'>
                <thead>
                    <row>
                        <entry>Formatbuchstabe</entry>
                        <entry>Beschreibung</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>d oder dd</entry>
                        <entry>Tag mit 1 oder 2 Ziffern</entry>
                    </row>

                    <row>
                        <entry>M oder MM</entry>
                        <entry>Monat mit 1 oder 2 Ziffern</entry>
                    </row>

                    <row>
                        <entry>y oder yy</entry>
                        <entry>Jahr mit 1 or 2 Ziffern</entry>
                    </row>

                    <row>
                        <entry>yyyy</entry>
                        <entry>Jahr mit 4 Ziffern</entry>
                    </row>

                    <row>
                        <entry>h</entry>
                        <entry>Stunde mit 1 oder 2 Ziffern</entry>
                    </row>

                    <row>
                        <entry>m</entry>
                        <entry>Minute mit 1 oder 2 Ziffern</entry>
                    </row>

                    <row>
                        <entry>s</entry>
                        <entry>Sekunde mit 1 oder 2 Ziffern</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            Beispiele für gültige Formate sind
        </para>

        <table id="zend.locale.date.normalize.table-4">
            <title>Beispielformate</title>

            <tgroup cols='3'>
                <thead>
                    <row>
                        <entry>Formate</entry>
                        <entry>Eingabe</entry>
                        <entry>Ausgabe</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>dd.MM.yy</entry>
                        <entry>1.4.6</entry>
                        <entry>['day'] => 1, ['month'] => 4, ['year'] => 6</entry>
                    </row>

                    <row>
                        <entry>dd.MM.yy</entry>
                        <entry>01.04.2006</entry>
                        <entry>['day'] => 1, ['month'] => 4, ['year'] => 2006</entry>
                    </row>

                    <row>
                        <entry>yyyyMMdd</entry>
                        <entry>1.4.6</entry>
                        <entry>['day'] => 6, ['month'] => 4, ['year'] => 1</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <note>
            <title>Datumsformate für Datenbanken</title>
            <para>
                Um einen Datumswert einer Datenbank zu analysieren (zum Beispiel MySql oder MsSql)
                sollte <classname>Zend_Date</classname>s ISO_8601-Format statt
                getDate() benutzt werden.
            </para>
        </note>

        <para>
            Die Option '<property>fix_date</property>' benutzt einfache Tests um herauszufinden, ob
            der Tag oder das Monat ungültig sind, und wendet dann eine Heuristik an, die versucht, die
            erkannten Probleme zu beheben. <methodname>getDate()</methodname> erkennt und behebt
            automatisch einige Problem mit falschen Eingaben, wie zum Beispiel ein falsch plaziertes
            Jahr:
        </para>

        <example id="zend.locale.date.normalize.example-5">
            <title>Automatische Korrektur von Datumsangaben</title>

            <programlisting language="php"><![CDATA[
$date = Zend_Locale_Format::getDate('41.10.20',
                                    array('date_format' => 'ddMMyy',
                                          'fix_date' => true)
                                   );

// Statt 41 für den Tag wird die 41 als Wert für das Jahr zurück gegeben
print_r ($date);
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.date.test">
        <title>Testen von Daten</title>

        <para>
            <methodname>checkDateFormat($inputString, array('date_format' => $format,
                $locale))</methodname> kann benutzt werden um zu prüfen, ob eine Zeichenkette alle
            erwarteten Datumsteile enthält. Die Methode <methodname>checkDateFormat()</methodname>
            benutzt <methodname>getDate()</methodname> aber ohne die Verwendung der Option
            '<property>fixdate</property>' um zu verhindern, dass <constant>TRUE</constant> zurück
            gegeben wird, wenn die Eingabe nicht dem Datumsformat entspricht. Wenn Fehler in der
            Eingabe gefunden werden, wie zum Beispiel getauschte Werte für Monat oder Jahr, wendet
            die Option '<property>fixdate</property>' eine Heuristik an, um das "richtige" Datum zu
            eruieren, bevor dieses auf Gültigkeit geprüft wird.
        </para>

        <example id="zend.locale.date.test.example-1">
            <title>Testen von Daten</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
// Standarddatumsformate für 'de_AT' benutzen... ist es ein gültiges Datum ?
if (Zend_Locale_Format::checkDateFormat('13.Apr.2006',
                                        array('date_format' =>
                                                  Zend_Locale_Format::STANDARD,
                                              $locale)
                                       ) {
    print "Datum";
} else {
    print "kein Datum";
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.time.normalizing">
        <title>Normalisieren von Zeiten</title>

        <para>
            Normalerweise werden Zeiten zusammen mit einem Datum zurückgegeben, wenn die Eingabe
            beide Werte enthält. Wenn das richtige Format nicht bekannt ist, aber das Gebietsschema
            für die Eingabe des Benutzers bekannt ist, sollte <methodname>getTime()</methodname>
            verwendet werden, weil es das standardmäßige Zeitformat für das ausgewählte
            Gebietsschema benutzt.
        </para>

        <example id="zend.locale.time.normalizing.example-1">
            <title>Normalisieren einer unbekannten Zeit</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::getTime('13:44:42',
                                array('date_format' =>
                                          Zend_Locale_Format::STANDARD,
                                      'locale' => $locale)
                               ) {
    print "Zeit";
} else {
    print "keine Zeit";
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.time.test">
        <title>Testen von Zeiten</title>

        <para>
            <methodname>checkDateFormat()</methodname> kann verwendet werden um zu prüfen, ob eine
            Zeichenkette eine gültige Zeit enthält. Die Verwendung ist genau die gleiche wie beim
            Prüfen von Daten und <property>date_format</property> sollte die Teile enthalten,
            die man erwartet.
        </para>

        <example id="zend.locale.time.test.example-1">
            <title>Testen einer Zeit</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::checkDateFormat('13:44:42',
                                        array('date_format' => 'HH:mm:ss',
                                              'locale' => $locale)) {
    print "Zeit";
} else {
    print "keine Zeit";
}
]]></programlisting>
        </example>
    </sect2>
</sect1>
