Ejemplo n.º 1
0
 /**
  * Return the plural rule ('zero', 'one', 'two', 'few', 'many' or 'other') for a number and a locale
  * @param string|int|float $number The number to check the plural rule for for
  * @param string $locale = '' The locale to use. If empty we'll use the default locale set in \Punic\Data
  * @return string Returns one of the following values: 'zero', 'one', 'two', 'few', 'many', 'other'
  * @throws \Punic\Exception\BadArgumentType Throws a \Punic\Exception\BadArgumentType if $number is not a valid number
  * @throws \Exception Throws a \Exception if there were problems calculating the plural rule
  */
 public static function getRule($number, $locale = '')
 {
     if (is_int($number)) {
         $intPartAbs = strval(abs($number));
         $floatPart = '';
     } elseif (is_float($number)) {
         $s = strval($number);
         if (strpos($s, '.') === false) {
             $intPart = $s;
             $floatPart = '';
         } else {
             list($intPart, $floatPart) = explode('.', $s);
         }
         $intPartAbs = strval(abs(intval($intPart)));
     } elseif (is_string($number) && strlen($number)) {
         if (preg_match('/^[+|\\-]?\\d+\\.?$/', $number)) {
             $v = intval($number);
             $intPartAbs = strval(abs($v));
             $floatPart = '';
         } elseif (preg_match('/^(\\d*)\\.(\\d+)$/', $number, $m)) {
             list($intPart, $floatPart) = explode('.', $number);
             $v = @intval($intPart);
             $intPartAbs = strval(abs($v));
         } else {
             throw new Exception\BadArgumentType($number, 'number');
         }
     } else {
         throw new Exception\BadArgumentType($number, 'number');
     }
     // 'n' => '%1$s', // absolute value of the source number (integer and decimals).
     $v1 = $intPartAbs . (strlen($floatPart) ? ".{$floatPart}" : '');
     // 'i' => '%2$s', // integer digits of n
     $v2 = $intPartAbs;
     // 'v' => '%3$s', // number of visible fraction digits in n, with trailing zeros.
     $v3 = strlen($floatPart);
     // 'w' => '%4$s', // number of visible fraction digits in n, without trailing zeros.
     $v4 = strlen(rtrim($floatPart, '0'));
     // 'f' => '%5$s', // visible fractional digits in n, with trailing zeros.
     $v5 = strlen($floatPart) ? strval(intval($floatPart)) : '0';
     // 't' => '%6$s', // visible fractional digits in n, without trailing zeros.
     $v6 = trim($floatPart, '0');
     if (!strlen($v6)) {
         $v6 = '0';
     }
     $result = 'other';
     $node = \Punic\Data::getLanguageNode(\Punic\Data::getGeneric('plurals'), $locale);
     foreach ($node as $rule => $formulaPattern) {
         $formula = sprintf($formulaPattern, $v1, $v2, $v3, $v4, $v5, $v6);
         $check = str_replace(array('static::inRange(', ' and ', ' or ', ', false, ', ', true, ', ', array('), ' , ', $formula);
         if (preg_match('/[a-z]/', $check)) {
             throw new \Exception('Bad formula!');
         }
         // fix for difference in modulo (%) in the definition and the one implemented in PHP for decimal numbers
         while (preg_match('/(\\d+\\.\\d+) % (\\d+(\\.\\d+)?)/', $formula, $m)) {
             list(, $decimalPart) = explode('.', $m[1], 2);
             $decimals = strlen(rtrim($decimalPart, '0'));
             if ($decimals > 0) {
                 $pow = intval(pow(10, $decimals));
                 $repl = '(' . strval(intval(floatval($m[1]) * $pow)) . ' % ' . strval(intval(floatval($m[2] * $pow))) . ') / ' . $pow;
             } else {
                 $repl = strval(intval($m[1])) . ' % ' . $m[2];
             }
             $formula = str_replace($m[0], $repl, $formula);
         }
         $formulaResult = @eval("return ({$formula}) ? 'yes' : 'no';");
         if ($formulaResult === 'yes') {
             $result = $rule;
             break;
         } elseif ($formulaResult !== 'no') {
             throw new \Exception('There was a problem in the formula ' . $formulaPattern);
         }
     }
     return $result;
 }
Ejemplo n.º 2
0
 /**
  * Retrieve the first weekday for a specific locale (from 0-Sunday to 6-Saturnday)
  * @param string $locale = '' The locale to use. If empty we'll use the default locale set in \Punic\Data
  * @return int Returns a number from 0 (Sunday) to 7 (Saturnday)
  */
 public static function getFirstWeekday($locale = '')
 {
     static $cache = array();
     $locale = empty($locale) ? \Punic\Data::getDefaultLocale() : $locale;
     if (!array_key_exists($locale, $cache)) {
         $result = 0;
         $data = \Punic\Data::getGeneric('weekData');
         $i = \Punic\Data::getTerritoryNode($data['firstDay'], $locale);
         if (is_int($i)) {
             $result = $i;
         }
         $cache[$locale] = $result;
     }
     return $cache[$locale];
 }