PHP Internationalization and Localization Localizing Numbers - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript PHP Internationalization and Localization Localizing Numbers - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript

Breaking

Post Top Ad

Post Top Ad

Wednesday, June 26, 2019

PHP Internationalization and Localization Localizing Numbers

PHP Internationalization and Localization



Localizing Numbers


Problem

You want to display numbers in a locale-specific format.

Solution

Use the number argument type with MessageFormatter:

       $message = '{0,number} / {1,number} = {2,number}';
       $args = array(5327, 98, 5327/98);

       $us = new MessageFormatter('en_US',$message);
       $fr  = new MessageFormatter('fr_FR',$message);
       print $us->format($args) . "\n";
       print $fr->format($args) . "\n";

This prints:

       5,327 / 98 = 54.357
       5 327 / 98 = 54,357

Discussion

Notice in the output that the same message produces different output based on what locale the MessageFormatter is set to use. The characters used as the thousands separator and decimal point are locale-specific. What’s shown is the default number style output. With an additional style parameter added to the type, you can change that.

For example, there are easy shortcuts for displaying numbers as currency amounts and percentage amounts:

       $message = '{0,number,currency}, {0,number,percent}';
       $us = new MessageFormatter('en_US',$message);
       print $us->format(array(3.33333333));

This prints:

       $3.33, 333%

Instead of the shortcut words currency or percent, you can also specify a format string as understood by the ICU DecimalFormat class. Many of the characters that can go in this format string are.

Table DecimalFormat pattern characters

Character   Meaning                                                                                                                                                      
0                  Digit
1-9               Digit, with rounding
#                  Digit, display nothing for zero
@                 Significant digit
%                 Percent sign, multiplies number by 100
¤                  Currency symbol
¤¤                Three-letter currency abbreviation
;                   Separator for positive and negative patterns
______________________________________________________________________

This code runs through several of these patterns for a few different numbers:

       $args = array(7,159,-0.3782,6.815574);
    
       $messages = array("0", "00", "1", "11", "222",
                                           "#", "##", "@", "@@@",
                                           "##%", "¤#", "¤1.11",
                                           "¤¤#",
                                           "#.##;(#.## !!!)"
                                           );

       foreach ($messages as $message) {
             $fmt = new MessageFormatter('en_US',"{0,number,$message}\t{1,number,
                                                                       $message}\t"."{2,number,$message}\t
                                                                       {3,number,$message}");
             print "$message:\t" . $fmt->format($args) . "\n";
       }

And this survey of patterns produces:

0:                          7                    1590                     -0                    7
00:                       07                  159                       -00                  07
1:                           7                    159                       -0                    7
11:                         11                   154                      -00                  11
222:                      000               222                     -000                000
#:                          7                     159                      -0                     7
##:                       7                     159                       -0                    7
@:                         7                     200                     -0.4                 7
@@@:                 7.00               159                      -0.378             6.82
##%:                    700%            15900%              -38%               682%
¤#:                        $7                  $159                    -$0                  $7
¤1.11:                    $6.66            $158.73              -$0.00            $6.66
¤¤#:                     USD7            USD159              -USD0            USD7
#.##;(#.## !!!): 7                     159                      (0.38 !!!)        6.82

More precise control over number formatting is possible with the separate NumberFormatter class. Its constructor accepts a locale, a formatting style, and an optional pattern string. For example:

       $args = array(7,159,-0.3782,6.815574);

       $sci = new NumberFormatter('en_US', NumberFormatter::SCIENTIFIC);
       $dur = new NumberFormatter('en_US', NumberFormatter::DURATION);
       $ord = new NumberFormatter('en_US', NumberFormatter::ORDINAL);
       $pat = new NumberFormatter('en_US', NumberFormatter::PATTERN_DECIMAL,                        '@@@@');

       print $sci->format(10040)      . "\n";
       print $dur->format(64)            . "\n";
       print $ord->format(15)             . "\n";
       print $pat->format(1.357926) . "\n";

This prints:

       1.004E4
       1:04
       15th
       1.358

The first formatter, using the NumberFormatter::SCIENTIFIC style, turns 10040 into appropriate scientific notation: 1.004E4. The second formatter, using NumberFormatter::DURATION, turns 64 seconds into 1:04—one minute and four seconds. The third formatter, using NumberFormatter::ORDINAL, produces “15th” from 15. And the last formatter, using NumberFormatter::PATTERN_DECIMAL, makes use of the same decimal format pattern characters discussed earlier.

The possibilities listed here are only part of what NumberFormatter can do. The PHP manual page for NumberFormatter goes into great detail on additional capabilities.

No comments:

Post a Comment

Post Top Ad