Merge "Do correct average year length arithmetic."
authorIAlex <ialex.wiki@gmail.com>
Sat, 29 Dec 2012 19:18:05 +0000 (19:18 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 29 Dec 2012 19:18:05 +0000 (19:18 +0000)
1  2 
languages/Language.php
tests/phpunit/languages/LanguageTest.php

diff --combined languages/Language.php
@@@ -160,10 -160,10 +160,10 @@@ class Language 
         * @var array
         */
        static public $durationIntervals = array(
-               'millennia' => 31557600000,
-               'centuries' => 3155760000,
-               'decades' => 315576000,
-               'years' => 31557600, // 86400 * 365.25
+               'millennia' => 31556952000,
+               'centuries' => 3155695200,
+               'decades' => 315569520,
+               'years' => 31556952, // 86400 * ( 365 + ( 24 * 3 + 25 ) / 400 )
                'weeks' => 604800,
                'days' => 86400,
                'hours' => 3600,
                return "<em>$text</em>";
        }
  
 -       /**
 -        * Normally we output all numbers in plain en_US style, that is
 -        * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
 -        * point twohundredthirtyfive. However this is not suitable for all
 -        * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
 -        * Icelandic just want to use commas instead of dots, and dots instead
 -        * of commas like "293.291,235".
 -        *
 -        * An example of this function being called:
 -        * <code>
 -        * wfMessage( 'message' )->numParams( $num )->text()
 -        * </code>
 -        *
 -        * See LanguageGu.php for the Gujarati implementation and
 -        * $separatorTransformTable on MessageIs.php for
 -        * the , => . and . => , implementation.
 -        *
 -        * @todo check if it's viable to use localeconv() for the decimal
 -        *       separator thing.
 -        * @param $number Mixed: the string to be formatted, should be an integer
 -        *        or a floating point number.
 -        * @param $nocommafy Bool: set to true for special numbers like dates
 -        * @return string
 -        */
 +      /**
 +       * Normally we output all numbers in plain en_US style, that is
 +       * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
 +       * point twohundredthirtyfive. However this is not suitable for all
 +       * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
 +       * Icelandic just want to use commas instead of dots, and dots instead
 +       * of commas like "293.291,235".
 +       *
 +       * An example of this function being called:
 +       * <code>
 +       * wfMessage( 'message' )->numParams( $num )->text()
 +       * </code>
 +       *
 +       * See LanguageGu.php for the Gujarati implementation and
 +       * $separatorTransformTable on MessageIs.php for
 +       * the , => . and . => , implementation.
 +       *
 +       * @todo check if it's viable to use localeconv() for the decimal
 +       *       separator thing.
 +       * @param $number Mixed: the string to be formatted, should be an integer
 +       *        or a floating point number.
 +       * @param $nocommafy Bool: set to true for special numbers like dates
 +       * @return string
 +       */
        public function formatNum( $number, $nocommafy = false ) {
                global $wgTranslateNumerals;
                if ( !$nocommafy ) {
        /**
         * Adds commas to a given number
         * @since 1.19
 -       * @param $_ mixed
 +       * @param $number mixed
         * @return string
         */
 -      function commafy( $_ ) {
 +      function commafy( $number ) {
                $digitGroupingPattern = $this->digitGroupingPattern();
 -              if ( $_ === null ) {
 +              if ( $number === null ) {
                        return '';
                }
  
                if ( !$digitGroupingPattern || $digitGroupingPattern === "###,###,###" ) {
                        // default grouping is at thousands,  use the same for ###,###,### pattern too.
 -                      return strrev( (string)preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1,', strrev( $_ ) ) );
 +                      return strrev( (string)preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1,', strrev( $number ) ) );
                } else {
                        // Ref: http://cldr.unicode.org/translation/number-patterns
                        $sign = "";
 -                      if ( intval( $_ ) < 0 ) {
 +                      if ( intval( $number ) < 0 ) {
                                // For negative numbers apply the algorithm like positive number and add sign.
                                $sign =  "-";
 -                              $_ = substr( $_, 1 );
 +                              $number = substr( $number, 1 );
                        }
 -                      $numberpart = array();
 -                      $decimalpart = array();
 +                      $integerPart = array();
 +                      $decimalPart = array();
                        $numMatches = preg_match_all( "/(#+)/", $digitGroupingPattern, $matches );
 -                      preg_match( "/\d+/", $_, $numberpart );
 -                      preg_match( "/\.\d*/", $_, $decimalpart );
 -                      $groupedNumber = ( count( $decimalpart ) > 0 ) ? $decimalpart[0]:"";
 -                      if ( $groupedNumber  === $_ ) {
 +                      preg_match( "/\d+/", $number, $integerPart );
 +                      preg_match( "/\.\d*/", $number, $decimalPart );
 +                      $groupedNumber = ( count( $decimalPart ) > 0 ) ? $decimalPart[0]:"";
 +                      if ( $groupedNumber  === $number ) {
                                // the string does not have any number part. Eg: .12345
                                return $sign . $groupedNumber;
                        }
 -                      $start = $end = strlen( $numberpart[0] );
 +                      $start = $end = strlen( $integerPart[0] );
                        while ( $start > 0 ) {
                                $match = $matches[0][$numMatches -1] ;
                                $matchLen = strlen( $match );
                                if ( $start < 0 ) {
                                        $start = 0;
                                }
 -                              $groupedNumber = substr( $_ , $start, $end -$start ) . $groupedNumber ;
 +                              $groupedNumber = substr( $number , $start, $end -$start ) . $groupedNumber ;
                                $end = $start;
                                if ( $numMatches > 1 ) {
                                        // use the last pattern for the rest of the number
                        return $sign . $groupedNumber;
                }
        }
 +
        /**
         * @return String
         */
@@@ -847,35 -847,36 +847,36 @@@ class LanguageTest extends LanguageClas
                                '2 days',
                        ),
                        array(
-                               365.25 * 86400, // 365.25 * 86400 = 31557600
+                               // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952
+                               ( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400,
                                '1 year',
                        ),
                        array(
-                               2 * 31557600,
+                               2 * 31556952,
                                '2 years',
                        ),
                        array(
-                               10 * 31557600,
+                               10 * 31556952,
                                '1 decade',
                        ),
                        array(
-                               20 * 31557600,
+                               20 * 31556952,
                                '2 decades',
                        ),
                        array(
-                               100 * 31557600,
+                               100 * 31556952,
                                '1 century',
                        ),
                        array(
-                               200 * 31557600,
+                               200 * 31556952,
                                '2 centuries',
                        ),
                        array(
-                               1000 * 31557600,
+                               1000 * 31556952,
                                '1 millennium',
                        ),
                        array(
-                               2000 * 31557600,
+                               2000 * 31556952,
                                '2 millennia',
                        ),
                        array(
                                '1 hour and 1 second'
                        ),
                        array(
-                               31557600 + 2 * 86400 + 9000,
+                               31556952 + 2 * 86400 + 9000,
                                '1 year, 2 days, 2 hours and 30 minutes'
                        ),
                        array(
-                               42 * 1000 * 31557600 + 42,
+                               42 * 1000 * 31556952 + 42,
                                '42 millennia and 42 seconds'
                        ),
                        array(
                                array( 'seconds' ),
                        ),
                        array(
-                               31557600 + 2 * 86400 + 9000,
+                               31556952 + 2 * 86400 + 9000,
                                '1 year, 2 days and 150 minutes',
                                array( 'years', 'days', 'minutes' ),
                        ),
                                array( 'years', 'days' ),
                        ),
                        array(
-                               31557600 + 2 * 86400 + 9000,
+                               31556952 + 2 * 86400 + 9000,
                                '1 year, 2 days and 150 minutes',
                                array( 'minutes', 'days', 'years' ),
                        ),
                        array( 'dummy', 'dummy', 'return garbage as is' ),
                );
        }
 +
 +      /**
 +       * @covers Language::commafy()
 +       * @dataProvider provideCommafyData
 +       */
 +      function testCommafy( $number, $numbersWithCommas ) {
 +              $this->assertEquals(
 +                      $numbersWithCommas,
 +                      $this->getLang()->commafy( $number ),
 +                      "commafy('$number')"
 +              );
 +      }
 +
 +      function provideCommafyData() {
 +              return array(
 +                      array( 1, '1' ),
 +                      array( 10, '10' ),
 +                      array( 100, '100' ),
 +                      array( 1000, '1,000' ),
 +                      array( 10000, '10,000' ),
 +                      array( 100000, '100,000' ),
 +                      array( 1000000, '1,000,000' ),
 +                      array( 1.0001, '1.0001' ),
 +                      array( 10.0001, '10.0001' ),
 +                      array( 100.0001, '100.0001' ),
 +                      array( 1000.0001, '1,000.0001' ),
 +                      array( 10000.0001, '10,000.0001' ),
 +                      array( 100000.0001, '100,000.0001' ),
 +                      array( 1000000.0001, '1,000,000.0001' ),
 +              );
 +      }
  }