| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.locale.parsing">
- <title>Normalization and Localization</title>
- <para>
- <classname>Zend_Locale_Format</classname> is an internal component used by
- <classname>Zend_Locale</classname>. All locale aware classes use
- <classname>Zend_Locale_Format</classname> for normalization and localization of numbers and
- dates. Normalization involves parsing input from a variety of data representations, like
- dates, into a standardized, structured representation, such as a <acronym>PHP</acronym>
- array with year, month, and day elements.
- </para>
- <para>
- The exact same string containing a number or a date might mean different things to people
- with different customs and conventions. Disambiguation of numbers and dates requires rules
- about how to interpret these strings and normalize the values into a standardized data
- structure. Thus, all methods in <classname>Zend_Locale_Format</classname> require a locale
- in order to parse the input data.
- <note>
- <title>Default "root" Locale</title>
- <para>
- If no locale is specified, then normalization and localization will use the standard
- "root" locale, which might yield unexpected behavior, if the input originated in a
- different locale, or output for a specific locale was expected.
- </para>
- </note>
- </para>
- <sect2 id="zend.locale.number.normalize">
- <title>Number normalization: getNumber($input, Array $options)</title>
- <para>
- There are many <ulink url="http://en.wikipedia.org/wiki/Numeral">number systems</ulink>
- different from the common <ulink
- url="http://en.wikipedia.org/wiki/Decimal">decimal system</ulink> (e.g. "3.14").
- Numbers can be normalized with the <methodname>getNumber()</methodname> function to
- obtain the standard decimal representation. for all number-related discussions in this
- manual, <ulink
- url="http://en.wikipedia.org/wiki/Arabic_numerals">Arabic/European numerals
- (0,1,2,3,4,5,6,7,8,9)</ulink> are implied, unless explicitly stated otherwise. The
- options array may contain a 'locale' to define grouping and decimal characters. The
- array may also have a 'precision' to truncate excess digits from the result.
- </para>
- <example id="zend.locale.number.normalize.example-1">
- <title>Number normalization</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; // will return 13524.678
- ]]></programlisting>
- </example>
- <sect3 id="zend.locale.number.normalize.precision">
- <title>Precision and Calculations</title>
- <para>
- Since <methodname>getNumber($value, array $options = array())</methodname> can
- normalize extremely large numbers, check the result carefully before using finite
- precision calculations, such as ordinary <acronym>PHP</acronym> math operations. For
- example, <command>if ((string)int_val($number) != $number) {</command> use <ulink
- url="http://www.php.net/bc">BCMath</ulink> or <ulink
- url="http://www.php.net/gmp">GMP</ulink>. Most <acronym>PHP</acronym>
- installations support the BCMath extension.
- </para>
- <para>
- Also, the precision of the resulting decimal representation can be rounded to a
- desired length with <methodname>getNumber()</methodname> with the option
- '<property>precision</property>'. If no precision is given, no rounding occurs. Use
- only <acronym>PHP</acronym> integers to specify the precision.
- </para>
- <para>
- If the resulting decimal representation should be truncated to a desired length
- instead of rounded the option '<property>number_format</property>' can be used
- instead. Define the length of the decimal representation with the desired length
- of zeros. The result will then not be rounded. So if the defined precision within
- <property>number_format</property> is zero the value "1.6" will return "1", not "2.
- See the example nearby:
- </para>
- <example id="zend.locale.number.normalize.precision.example-1">
- <title>Number normalization with precision</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 return 13524.7
- $number = Zend_Locale_Format::getNumber('13.524,678',
- array('number_format' => '#.00',
- 'locale' => $locale)
- );
- print $number; // will return 13524.67
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.locale.number.localize">
- <title>Number localization</title>
- <para>
- <methodname>toNumber($value, array $options = array())</methodname> can localize numbers
- to the following <link linkend="zend.locale.appendix">supported locales</link>. This
- function will return a localized string of the given number in a conventional format for
- a specific locale. The 'number_format' option explicitly specifies a non-default number
- format for use with <methodname>toNumber()</methodname>.
- </para>
- <example id="zend.locale.number.localize.example-1">
- <title>Number localization</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::toNumber(13547.36,
- array('locale' => $locale));
- // will return 13.547,36
- print $number;
- ]]></programlisting>
- </example>
- <para>
- <note>
- <title>Unlimited length</title>
- <para>
- <methodname>toNumber()</methodname> can localize numbers with unlimited length.
- It is not related to integer or float limitations.
- </para>
- </note>
- </para>
- <para>
- The same way as within <methodname>getNumber()</methodname>,
- <methodname>toNumber()</methodname> handles precision. If no precision is given, the
- complete localized number will be returned.
- </para>
- <example id="zend.locale.number.localize.example-2">
- <title>Number localization with precision</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::toNumber(13547.3678,
- array('precision' => 2,
- 'locale' => $locale));
- // will return 13.547,37
- print $number;
- ]]></programlisting>
- </example>
- <para>
- Using the option 'number_format' a self defined format for generating a number can be
- defined. The format itself has to be given in <acronym>CLDR</acronym> format as
- described below. The locale is used to get separation, precision and other number
- formatting signs from it. German for example defines ',' as precision separation and in
- English the '.' sign is used.
- </para>
- <table id="zend.locale.number.localize.table-1">
- <title>Format tokens for self generated number formats</title>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Token</entry>
- <entry>Description</entry>
- <entry>Example format</entry>
- <entry>Generated output</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>#0</entry>
- <entry>Generates a number without precision and separation</entry>
- <entry>#0</entry>
- <entry>1234567</entry>
- </row>
- <row>
- <entry>,</entry>
- <entry>
- Generates a separation with the length from separation to next
- separation or to 0
- </entry>
- <entry>#,##0</entry>
- <entry>1,234,567</entry>
- </row>
- <row>
- <entry>#,##,##0</entry>
- <entry>
- Generates a standard separation of 3 and all following separations with
- 2
- </entry>
- <entry>#,##,##0</entry>
- <entry>12,34,567</entry>
- </row>
- <row>
- <entry>.</entry>
- <entry>Generates a precision</entry>
- <entry>#0.#</entry>
- <entry>1234567.1234</entry>
- </row>
- <row>
- <entry>0</entry>
- <entry>Generates a precision with a defined length</entry>
- <entry>#0.00</entry>
- <entry>1234567.12</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <example id="zend.locale.number.localize.example-3">
- <title>Using a self defined number format</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')
- );
- // will return 1.35.47,36
- print $number;
- $number = Zend_Locale_Format::toNumber(13547.3,
- array('number_format' => '#,##0.00',
- 'locale' => 'de')
- );
- // will return 13.547,30
- print $number;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.number.test">
- <title>Number testing</title>
- <para>
- <methodname>isNumber($value, array $options = array())</methodname> checks if a given
- string is a number and returns <constant>TRUE</constant> or <constant>FALSE</constant>.
- </para>
- <example id="zend.locale.number.test.example-1">
- <title>Number testing</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale();
- if (Zend_Locale_Format::isNumber('13.445,36', array('locale' => 'de_AT'))) {
- print "Number";
- } else {
- print "not a Number";
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.float.normalize">
- <title>Float value normalization</title>
- <para>
- Floating point values can be parsed with the
- <methodname>getFloat($value, array $options = array())</methodname> function. A floating
- point value will be returned.
- </para>
- <example id="zend.locale.float.normalize.example-1">
- <title>Floating point value normalization</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::getFloat('13.524,678',
- array('precision' => 2,
- 'locale' => $locale)
- );
- // will return 13524.68
- print $number;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.float.localize">
- <title>Floating point value localization</title>
- <para>
- <methodname>toFloat()</methodname> can localize floating point values. This function
- will return a localized string of the given number.
- </para>
- <example id="zend.locale.float.localize.example-1">
- <title>Floating point value localization</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::toFloat(13547.3655,
- array('precision' => 1,
- 'locale' => $locale)
- );
- // will return 13.547,4
- print $number;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.float.test">
- <title>Floating point value testing</title>
- <para>
- <methodname>isFloat($value, array $options = array())</methodname> checks if a given
- string is a floating point value and returns <constant>TRUE</constant> or
- <constant>FALSE</constant>.
- </para>
- <example id="zend.locale.float.test.example-1">
- <title>Floating point value testing</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- if (Zend_Locale_Format::isFloat('13.445,36', array('locale' => $locale))) {
- print "float";
- } else {
- print "not a float";
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.integer.normalize">
- <title>Integer value normalization</title>
- <para>
- Integer values can be parsed with the <methodname>getInteger()</methodname> function. A
- integer value will be returned.
- </para>
- <example id="zend.locale.integer.normalize.example-1">
- <title>Integer value normalization</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::getInteger('13.524,678',
- array('locale' => $locale));
- // will return 13524
- print $number;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.integer.localize">
- <title>Integer point value localization</title>
- <para>
- <methodname>toInteger($value, array $options = array())</methodname> can localize
- integer values. This function will return a localized string of the given number.
- </para>
- <example id="zend.locale.integer.localize.example-1">
- <title>Integer value localization</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- $number = Zend_Locale_Format::toInteger(13547.3655,
- array('locale' => $locale));
- // will return 13.547
- print $number;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.integer.test">
- <title>Integer value testing</title>
- <para>
- <methodname>isInteger($value, array $options = array())</methodname> checks if a given
- string is an integer value and returns <constant>TRUE</constant> or
- <constant>FALSE</constant>.
- </para>
- <example id="zend.locale.integer.test.example-1">
- <title>Integer value testing</title>
- <programlisting language="php"><![CDATA[
- $locale = new Zend_Locale('de_AT');
- if (Zend_Locale_Format::isInteger('13.445', array('locale' => $locale))) {
- print "integer";
- } else {
- print "not an integer";
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.locale.numbersystems">
- <title>Numeral System Conversion</title>
- <para>
- <methodname>Zend_Locale_Format::convertNumerals()</methodname> converts digits between
- different <ulink url="http://en.wikipedia.org/wiki/Arabic_numerals">numeral
- systems</ulink>, including the standard Arabic/European/Latin numeral system
- (0,1,2,3,4,5,6,7,8,9), not to be confused with <ulink
- url="http://en.wikipedia.org/wiki/Eastern_Arabic_numerals">Eastern Arabic
- numerals</ulink> sometimes used with the Arabic language to express numerals.
- Attempts to use an unsupported numeral system will result in an exception, to avoid
- accidentally performing an incorrect conversion due to a spelling error. All characters
- in the input, which are not numerals for the selected numeral system, are copied to the
- output with no conversion provided for unit separator characters.
- <classname>Zend_Locale</classname>* components rely on the data provided by
- <acronym>CLDR</acronym> (see their <ulink
- url="http://unicode.org/cldr/data/diff/supplemental/languages_and_scripts.html?sortby=date">list
- of scripts grouped by language</ulink>).
- </para>
- <para>
- In <acronym>CLDR</acronym> and hereafter, the Europena/Latin numerals will
- be referred to as "Latin" or by the assigned 4-letter code "Latn".
- Also, the <acronym>CLDR</acronym> refers to this numeral systems as "scripts".
- </para>
- <para>
- Suppose a web form collected a numeric input expressed using Eastern Arabic digits
- "١٠٠". Most software and <acronym>PHP</acronym> functions expect input using Arabic
- numerals. Fortunately, converting this input to its equivalent Latin numerals "100"
- requires little effort using <methodname>convertNumerals($inputNumeralString,
- $sourceNumeralSystem, $destNumeralSystem)</methodname>, which returns the
- <varname>$input</varname> with numerals in the script
- <varname>$sourceNumeralSystem</varname> converted to the script
- <varname>$destNumeralSystem</varname>.
- </para>
- <example id="zend.locale.numbersystems.example-1">
- <title>Converting numerals from Eastern Arabic scripts to European/Latin scripts</title>
- <programlisting language="php"><![CDATA[
- $arabicScript = "١٠٠"; // Arabic for "100" (one hundred)
- $latinScript = Zend_Locale_Format::convertNumerals($arabicScript,
- 'Arab',
- 'Latn');
- print "\nOriginal: " . $arabicScript;
- print "\nNormalized: " . $latinScript;
- ]]></programlisting>
- </example>
- <para>
- Similarly, any of the supported numeral systems may be converted to any other supported
- numeral system.
- </para>
- <example id="zend.locale.numbersystems.example-2">
- <title>Converting numerals from Latin script to Eastern Arabic script</title>
- <programlisting language="php"><![CDATA[
- $latinScript = '123';
- $arabicScript = Zend_Locale_Format::convertNumerals($latinScript,
- 'Latn',
- 'Arab');
- print "\nOriginal: " . $latinScript;
- print "\nLocalized: " . $arabicScript;
- ]]></programlisting>
- </example>
- <example id="zend.locale.numbersystems.example-3">
- <title>
- Getting 4 letter CLDR script code using a native-language name of the script
- </title>
- <programlisting language="php"><![CDATA[
- function getScriptCode($scriptName, $locale)
- {
- $scripts2names = Zend_Locale_Data::getList($locale, 'script');
- $names2scripts = array_flip($scripts2names);
- return $names2scripts[$scriptName];
- }
- echo getScriptCode('Latin', 'en'); // outputs "Latn"
- echo getScriptCode('Tamil', 'en'); // outputs "Taml"
- echo getScriptCode('tamoul', 'fr'); // outputs "Taml"
- ]]></programlisting>
- </example>
- <para>
- For a list of supported numeral systems call
- <methodname>Zend_Locale::getTranslationList('numberingsystem', 'en')</methodname>.
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|