<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 22755 -->
<!-- Reviewed: 22755 -->
<sect1 id="zend.locale.parsing">
    <title>Normalisierung und Lokalisierung</title>

    <para>
        <classname>Zend_Locale_Format</classname> ist eine interne Komponente, welche von
        <classname>Zend_Locale</classname> verwendet wird. Alle lokalisierbaren Klassen benutzen
        <classname>Zend_Locale_Format</classname> für Normalisierung und Lokalisierung von Nummern
        und Daten. Normalisierung beinhaltet das Analysieren von Eingaben von einer Vielfalt von
        Werten wie Datumswerten in eine standardisierte, strukturieren Art wie zum Beispiel ein
        <acronym>PHP</acronym> Array mit Jahr, Monat und Tages Elementen.
    </para>

    <para>
        Genau die gleiche Zeichenkette, die eine Zahl oder ein Datum enthält, kann verschiedenes
        bedeuten für Leute mit unterschiedlichen Gebräuchen und Konventionen.
        Das Auflösen von Mehrdeutigkeiten von Nummern und Daten benötigt
        Regeln darüber, wie diese Zeichenketten zu interpretieren sind um diese Werte in eine
        standardisierte Form zu bringen. Deswegen benötigen alle Methoden in
        <classname>Zend_Locale_Format</classname> ein Gebietsschema, um Eingabedaten analysieren zu
        können.

        <note>
            <title>Standard "root" Gebietsschema</title>

            <para>
                Wenn kein Gebietsschema spezifiziert wurde, wird die Normalisierung und
                Lokalisierung das Standard "root" Gebietsschema verwenden, was zu unerwarteten
                Ergebnissen führen kann, wenn die Eingabe in einem anderen Gebietsschema angegeben
                oder die Ausgabe für ein anderes Gebietsschema erwartet wurde.
            </para>
        </note>
    </para>

    <sect2 id="zend.locale.number.normalize">
        <title>Normalisierung von Zahlen: getNumber($input, Array $options)</title>

        <para>
            Es gibt viele
            <ulink url="http://en.wikipedia.org/wiki/Numeral">Ziffernsysteme</ulink>,
            welche sich vom üblichen
            <ulink url="http://en.wikipedia.org/wiki/Decimal">Dezimalsystem</ulink>
            unterscheiden (z.B. "3.14"). Zahlen können mit der Funktion
            <methodname>getNumber()</methodname> normalisiert werden, um ein gleichwertiges Ergebnis
            in einer Schreibweise des Standarddezimalsystems zu erhalten. Für alle
            Ziffern-relevanten Diskussionen in diesem Handbuch werden die
            <ulink url="http://en.wikipedia.org/wiki/Arabic_numerals">Arabisch/Europäischen Ziffern
                 (0,1,2,3,4,5,6,7,8,9)</ulink> verwendet, ausser es ist anders definiert. Das
            Options-Array kann ein 'locale'.Gebietsschema enthalten, um eine Gruppierung und
            Kommazeichen zu definieren. Das Array kann auch eine Genauigkeit 'precision' enthalten,
            um überschüssige Ziffern vom Ergebnis abzuschneiden.
        </para>

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

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::getNumber('13.524,678',
                                        array('locale' => $locale,
                                              'precision' => 3)
                                       );

print $number; // wird 13524.678 zurückgeben
]]></programlisting>
        </example>

        <sect3 id="zend.locale.number.normalize.precision">
            <title>Genauigkeit und Berechnungen</title>

            <para>
                Da <methodname>getNumber($value, array $options = array())</methodname> extrem große
                Zahlen lokalisieren kann, sollte das Ergebnis sorgfältig geprüft werden, bevor
                endlich genaue Berechnungen wie normale mathematische <acronym>PHP</acronym>
                Operationen gemacht werden. Zum Beispiel
                <command>if ((string)int_val($number) != $number) { </command> benutze <ulink
                    url="http://www.php.net/bc">BCMath</ulink> oder
                    <ulink url="http://www.php.net/gmp">GMP</ulink>. Die meisten PHP
                Installationen unterstützen die BCMath Erweiterung.
            </para>

            <para>
                Auch die Genauigkeit des dezimalen Ergebnisses bei
                <methodname>getNumber()</methodname> kann mit der Option'<property>precision</property>'
                '<property>precision</property>' zu einer gewünschten Länge abgerundet
                werden. Wenn keine Genauigkeit angegeben wurde, wird nicht abgerundet.
                Für die Angabe der Genauigkeit dürfen nur <acronym>PHP</acronym> Integer
                Zahlen verwendet werden. Das Ergebnis wird nicht gerundet. Deswegen wird "1.6" auch
                "1" und nicht "2" zurückgeben, wenn als Genauigkeit null angegeben wurde.
            </para>

            <para>
                Wenn das dezimale Ergebnis zu einer gewünschten Länge abgeschnitten statt gerundet
                werden soll kann stattdessen die Option '<property>number_format</property>'
                verwendet werden. Die Länge des gewünschten dezimalen Ergebnisses kann mit der
                gewünschten Länge von Nullen bestimmt werden. Das Ergebnis wird dann nicht gerundet.
                Wenn also die definierte Genauigkeit innerhalb von
                <property>number_format</property> Null ist wird "1.6" den Wert "1" und nicht "2"
                zurückgeben. Siehe das folgende Beispiel:
            </para>

            <example id="zend.locale.number.normalize.precision.example-1">
                <title>Normalisierung von Zahlen mit Genauigkeit</title>

                <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::getNumber('13.524,678',
                                        array('precision' => 1,
                                              'locale' => $locale)
                                       );
print $number; // will 13524.7 zurückgeben

$number = Zend_Locale_Format::getNumber('13.524,678',
                                        array('number_format' => '#.00',
                                              'locale' => $locale)
                                       );
print $number; // will 13524.67 zurückgeben
]]></programlisting>
            </example>
        </sect3>
    </sect2>

    <sect2 id="zend.locale.number.localize">
        <title>Lokalisieren von Zahlen</title>

        <para>
            <methodname>toNumber($value, array $options = array())</methodname> kann mit Hilfe der
            folgenden <link linkend="zend.locale.appendix">unterstützten Gebietsschemata</link>,
            Zahlen lokalisieren. Diese Funktion gibt eine lokalisierte Zeichenkette der angegebenen
            Zahl in dem konventionellen Format für ein definiertes Gebietsschema aus. Die Option
            'number_format' definiert ein explizit angegebenes, nicht standardmäßiges Zahlenformat
            für die Verwendung mit <methodname>toNumber()</methodname>.
        </para>

        <example id="zend.locale.number.localize.example-1">
            <title>Lokalisieren von Zahlen</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::toNumber(13547.36,
                                       array('locale' => $locale));

// gibt 13.547,36 zurück
print $number;
]]></programlisting>
        </example>

        <para>
            <note>
                <title>Unlimitierte Länge</title>

                <para>
                    <methodname>toNumber()</methodname> kann Zahlen mit unendlicher Länge
                    lokalisieren. Hierbei gibt es keine Abhängigkeiten mit Integer oder Float
                    Limits.
                </para>
            </note>
        </para>

        <para>
            Genauso wie <methodname>getNumber()</methodname> verwendet
            <methodname>toNumber()</methodname> die Genauigkeit. Wenn keine Genauigkeit angegeben
            wurde, wird die komplette lokalisierte Zahl zurückgegeben.
        </para>

        <example id="zend.locale.number.localize.example-2">
            <title>Zahlen mit bestimmter Genauigkeit lokalisieren</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::toNumber(13547.3678,
                                       array('precision' => 2,
                                             'locale' => $locale));

// gibt 13.547,37 zurück
print $number;
]]></programlisting>
        </example>

        <para>
            Wird die Option 'number_format' benutzt, kann ein selbst definiertes Format für das
            erstellen der Zahl definiert werden. Das Format selbst muß im <acronym>CLDR</acronym>
            Format wie anbei beschrieben angegeben werden. Das Gebietsschema wird hierbei benutzt um
            das Trennzeichen, die Genauigkeit und andere Formatierungszeichen für Zahlen zu
            erhalten. Deutsch definiert zum Beispiel ',' als Kommazeichen und im Englischen wird das
            '.' Zeichen benutzt.
        </para>

        <table id="zend.locale.number.localize.table-1">
            <title>Definitionen für selbst erzeugte Zahlenformate</title>

            <tgroup cols="4">
                <thead>
                    <row>
                        <entry>Definition</entry>
                        <entry>Beschreibung</entry>
                        <entry>Beispiel Format</entry>
                        <entry>Erzeugte Ausgabe</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>#0</entry>
                        <entry>Erzeugt eine Zahl ohne Genauigkeit und ohne Trennung</entry>
                        <entry>#0</entry>
                        <entry>1234567</entry>
                    </row>

                    <row>
                        <entry>,</entry>

                        <entry>
                            Erzeugt eine Trennung mit der Länge von einem Trennzeichen zum nächsten
                            oder zur 0
                        </entry>

                        <entry>#,##0</entry>
                        <entry>1,234,567</entry>
                    </row>

                    <row>
                        <entry>#,##,##0</entry>

                        <entry>
                            Erzeugt eine Standardtrennung von 3 und alle weiteren Trennungen mit 2
                        </entry>

                        <entry>#,##,##0</entry>
                        <entry>12,34,567</entry>
                    </row>

                    <row>
                        <entry>.</entry>
                        <entry>Erzeugt eine Kommazahl</entry>
                        <entry>#0.#</entry>
                        <entry>1234567.1234</entry>
                    </row>

                    <row>
                        <entry>0</entry>
                        <entry>Erzeugt eine Kommazahl mit definierter Länge</entry>
                        <entry>#0.00</entry>
                        <entry>1234567.12</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <example id="zend.locale.number.localize.example-3">
            <title>Ein selbst definiertes Zahlenformat verwenden</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::toNumber(13547.3678,
                                       array('number_format' => '#,#0.00',
                                             'locale' => 'de')
                                      );

// gibt 1.35.47,36 zurück
print $number;

$number = Zend_Locale_Format::toNumber(13547.3,
                                       array('number_format' => '#,##0.00',
                                             'locale' => 'de')
                                      );

// gibt 13.547,30 zurück
print $number;
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.number.test">
        <title>Testen von Zahlen</title>

        <para>
            <methodname>isNumber($value, array $options = array())</methodname> prüft, ob eine
            gegebene Zeichenkette eine Zahl enthält und gibt <constant>TRUE</constant> oder
            <constant>FALSE</constant> zurück.
        </para>

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

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale();
if (Zend_Locale_Format::isNumber('13.445,36', array('locale' => 'de_AT')) {
    print "Zahl";
} else {
    print "keine Zahl";
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.float.normalize">
        <title>Gleitkommazahlen normalisieren</title>

        <para>
            Lokalisierte Gleitkommazahlen können mit <code>getFloat($value, array $options =
                array())</code> analysiert werden. Es wird eine Gleitkommazahl zurückgegeben.
        </para>

        <example id="zend.locale.float.normalize.example-1">
            <title>Gleitkommazahlen normalisieren</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::getFloat('13.524,678',
                                       array('precision' => 2,
                                             'locale' => $locale));

// gibt 13524.68 zurück
print $number;
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.float.localize">
        <title>Lokalisieren von Gleitkommazahlen</title>

        <para>
            <methodname>toFloat()</methodname> kann Gleitkommazahlen lokalisieren. Diese Funktion
            gibt eine lokalisierte Zeichenkette mit der gegebenen Zahl zurück.
        </para>

        <example id="zend.locale.float.localize.example-1">
            <title>Lokalisieren von Gleitkommazahlen</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::toFloat(13547.3655,
                                      array('precision' => 1,
                                            'locale' => $locale));

// gibt 13.547,4 zurück
print $number;
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.float.test">
        <title>Testen von Gleitkommazahlen</title>

        <para>
            <methodname>isFloat($value, array $options = array())</methodname> prüft, ob eine
            gegebene Zeichenkette eine Gleitkommazahl enthält und gibt <constant>TRUE</constant>
            oder <constant>FALSE</constant> zurück.
        </para>

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

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::isFloat('13.445,36', array('locale' => $locale)) {
    print "Gleitkommazahl";
} else {
    print "keine Gleitkommazahl";
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.integer.normalize">
        <title>Integer-Zahlen normalisieren</title>

        <para>
            Ganzzahlen können mit der Funktion <methodname>getInteger()</methodname> analysiert
            werden. Es wird ein Ganzzahlwert (Integer) zurückgegeben.
        </para>

        <example id="zend.locale.integer.normalize.example-1">
            <title>Normalisieren von Integer-Zahlen</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::getInteger('13.524,678',
                                         array('locale' => $locale));

// gibt 13524 zurück
print $number;
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.integer.localize">
        <title>Lokalisieren von Ganzzahlen</title>

        <para>
            <methodname>toInteger($value, array $options = array())</methodname> kann Integer-Zahlen
            lokalisieren. Diese Funktion gibt eine lokalisierte Zeichenkette anhand der gegebenen
            Nummer zurück.
        </para>

        <example id="zend.locale.integer.localize.example-1">
            <title>Lokalisieren von Integer-Zahlen</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
$number = Zend_Locale_Format::toInteger(13547.3655,
                                        array('locale' => $locale));

// gibt 13.547 zurück
print $number;
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.integer.test">
        <title>Testen von Integer-Zahlen</title>

        <para>
            <methodname>isInteger($value, array $options = array())</methodname> prüft ob eine
            gegebene Zeichenkette eine Ganzzahl enthält und gibt <constant>TRUE</constant> oder
            <constant>FALSE</constant> zurück.
        </para>

        <example id="zend.locale.integer.test.example-1">
            <title>Testen von Integer-Zahlen</title>

            <programlisting language="php"><![CDATA[
$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::isInteger('13.445', array('locale' => $locale)) {
    print "Integerzahl";
} else {
    print "keine Integerzahl";
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.locale.numbersystems">
        <title>Konvertieren von Zahlensystemen</title>

        <para>
            <methodname>Zend_Locale_Format::convertNumerals()</methodname> kann die Ziffern zwischen
            den unterschiedlichen <ulink
                url="http://en.wikipedia.org/wiki/Arabic_numerals">Zahlensystemen</ulink> umwandeln.
            Das inkludiert auch das Standard Arabisch/Europäisch/Lateinische Zahlensystem
            (0,1,2,3,4,5,6,7,8,9). Nicht zu verwechseln mit dem
            <ulink url="http://en.wikipedia.org/wiki/Eastern_Arabic_numerals">Ost-arabischen
                Zahlensystem</ulink>, welches in der Arabischen Sprache benutzt wird, um Zahlen zu
            schreiben. Der Versuch, ein nicht unterstütztes Zahlensystem zu benutzen, führt zu einer
            Ausnahme, um eine irrtümliche falsche Konvertierung wegen eines Schreibfehlers zu
            verhindern. Alle Zeichen der Eingabe, welche keine Ziffern des angegebenen
            Zahlenformates sind, werden in den Ausgabestring kopiert ohne dass sie verändert werden.
            Das beinhaltet auch die Trennzeichen der Zahlen. <classname>Zend_Locale</classname>*
            Komponenten sind abhängig von den Daten, welche durch <acronym>CLDR</acronym> zur
            Verfügung gestellt werden (hier ist eine <ulink
                url="http://unicode.org/cldr/data/diff/supplemental/languages_and_scripts.html?sortby=date">Liste
                von Schreibweisen gruppiert nach Sprachen</ulink>).
        </para>

        <para>
            Im <acronym>CLDR</acronym> und auch hier, werden die Europäisch/Lateinischen Zahlen als
            "Latin" oder mit dem zugeordneten 4-Zeichen-Code "Latn" bezeichnet. Im
            <acronym>CLDR</acronym> werden Zahlensysteme auch als "Schreibweisen" (Scripts)
            bezeichnet.
        </para>

        <para>
            Nehmen wir an eine Web-Form erhält eine numerische Eingabe, welche Ost-Arabische
            Ziffern enthält "١‎٠٠". Die meisten Programme und <acronym>PHP</acronym>-Funktionen
            erwarten Eingaben aber als Lateinische Ziffern. Glücklicherweise ist die
            Konvertierung dieser Eingabe in gleichwertige Lateinische Ziffern "100" sehr wenig
            Aufwand. Es muss nur <code>convertNumerals($inputNumeralString, $sourceNumeralSystem,
                 $destNumeralSystem)</code> benutzt werden, welches <varname>$input</varname>
            zurückgibt und hierbei die Ziffern der Schreibweise
            <varname>$sourceNumeralSystem</varname> in die Schreibweise
            <varname>$destNumeralSystem</varname> konvertiert.
        </para>

        <example id="zend.locale.numbersystems.example-1">
            <title>Konvertieren von Ost-Arabischen Ziffern in Europäisch-Lateinische Ziffern</title>

            <programlisting language="php"><![CDATA[
$arabicScript = "١‎٠٠";   // Arabisch für "100" (ein Hundert)
$latinScript = Zend_Locale_Format::convertNumerals($arabicScript,
                                                   'Arab',
                                                   'Latn');

print "\nOriginal:   " . $arabicScript;
print "\nNormalisiert: " . $latinScript;
]]></programlisting>
        </example>

        <para>
            Genauso kann jedes unterstützte Zahlensystem in jedes andere unterstützte Zahlensystem
            konvertiert werden.
        </para>

        <example id="zend.locale.numbersystems.example-2">
            <title>Konvertieren von Lateinischen Ziffern in Ost-Arabische Ziffern</title>

            <programlisting language="php"><![CDATA[
$latinScript = '123';
$arabicScript = Zend_Locale_Format::convertNumerals($latinScript,
                                                    'Latn',
                                                    'Arab');

print "\nOriginal:  " . $latinScript;
print "\nLokalisiert: " . $arabicScript;
]]></programlisting>
        </example>

        <example id="zend.locale.numbersystems.example-3">
            <title>
                Auslesen des 4 Zeichen CLDR Codes durch Benutzen des Namens in der Muttersprache
            </title>

            <programlisting language="php"><![CDATA[
function getScriptCode($scriptName, $locale)
{
    $scripts2names = Zend_Locale_Data::getList($locale, 'scriptlist');
    $names2scripts = array_flip($scripts2names);
    return $names2scripts[$scriptName];
}
echo getScriptCode('Latin', 'en'); // Ausgabe "Latn"
echo getScriptCode('Tamil', 'en'); // Ausgabe "Taml"
echo getScriptCode('tamoul', 'fr'); // Ausgabe "Taml"
]]></programlisting>
        </example>

        <para>
            Für eine Liste der unterstützten Zahlensysteme kann man
            <methodname>Zend_Locale::getTranslationList('numberingsystem', 'en')</methodname>
            aufrufen.
        </para>
    </sect2>
</sect1>
