Addshore has uploaded a new change for review. https://gerrit.wikimedia.org/r/117196
Change subject: Correctly Format BC dates/times ...................................................................... Correctly Format BC dates/times Change-Id: Ib9dc95e78e7b9b99579e8309c1ba3481adcfa9b8 --- M lib/includes/formatters/MwTimeIsoFormatter.php M lib/tests/phpunit/formatters/MwTimeIsoFormatterTest.php M repo/tests/phpunit/includes/api/FormatSnakValueTest.php 3 files changed, 195 insertions(+), 52 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/96/117196/1 diff --git a/lib/includes/formatters/MwTimeIsoFormatter.php b/lib/includes/formatters/MwTimeIsoFormatter.php index 066fe21..eb228d2 100644 --- a/lib/includes/formatters/MwTimeIsoFormatter.php +++ b/lib/includes/formatters/MwTimeIsoFormatter.php @@ -16,6 +16,8 @@ * @licence GNU GPL v2+ * @author H. Snater < mediaw...@snater.com > * @author Adam Shorland + * + * @todo move me to DataValues-time */ class MwTimeIsoFormatter extends ValueFormatterBase implements TimeIsoFormatter { @@ -65,18 +67,23 @@ * [8] => 02 * [9] => 03 */ - $regexSuccess = preg_match( '/^(\+|\-)((\d{7})?(\d{4}))-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/', + $regexSuccess = preg_match( '/^(\+|\-)((\d{0,7})?(\d{4}))-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/', $extendedIsoTimestamp, $matches ); - //TODO: format values with - - if( !$regexSuccess || $matches[1] === '-') { + if( !$regexSuccess || intval( $matches[2] ) === 0 ) { return $extendedIsoTimestamp; } + $isBCE = ( $matches[1] === '-' ); // Positive 4-digit year allows using Language object. - $fourDigitYearTimestamp = str_replace( '+' . $matches[3], '', $extendedIsoTimestamp ); - $timestamp = wfTimestamp( TS_MW, $fourDigitYearTimestamp ); + $fourDigitYearTimestamp = str_pad( + substr( $extendedIsoTimestamp, strlen( $matches[1] . $matches[3] ) ), + 20, // This is the length of 2013-07-16T00:00:00Z + '0', + STR_PAD_LEFT + ); + $timestamp = wfTimestamp( TS_MW, $fourDigitYearTimestamp ); $localisedDate = $this->language->sprintfDate( $this->getDateFormat( $precision ), $timestamp @@ -90,7 +97,7 @@ $localisedDate = str_replace( $matches[4], - $this->formatYear( $matches[2], $precision ), + $this->formatYear( $matches[2], $precision, $isBCE ), $localisedDate ); @@ -123,54 +130,56 @@ /** * @param string $fullYear * @param integer $precision + * @param bool $isBCE * * @return string the formatted year */ - private function formatYear( $fullYear, $precision ) { + private function formatYear( $fullYear, $precision, $isBCE ) { + if( $isBCE ) { + $msgPrefix = 'wikibase-time-precision-BCE'; + } else { + $msgPrefix = 'wikibase-time-precision'; + } + switch( $precision ) { case TimeValue::PRECISION_Ga: $fullYear = round( $fullYear, -9 ); $fullYear = substr( $fullYear, 0, -9 ); - return $this->getMessage( 'wikibase-time-precision-Gannum', $fullYear ); + return $this->getMessage( $msgPrefix . '-Gannum', $fullYear ); case TimeValue::PRECISION_100Ma: $fullYear = round( $fullYear, -8 ); $fullYear = substr( $fullYear, 0, -6 ); - return $this->getMessage( 'wikibase-time-precision-Mannum', $fullYear ); + return $this->getMessage( $msgPrefix . '-Mannum', $fullYear ); case TimeValue::PRECISION_10Ma: $fullYear = round( $fullYear, -7 ); $fullYear = substr( $fullYear, 0, -6 ); - return $this->getMessage( 'wikibase-time-precision-Mannum', $fullYear ); + return $this->getMessage( $msgPrefix . '-Mannum', $fullYear ); case TimeValue::PRECISION_Ma: $fullYear = round( $fullYear, -6 ); $fullYear = substr( $fullYear, 0, -6 ); - return $this->getMessage( 'wikibase-time-precision-Mannum', $fullYear ); + return $this->getMessage( $msgPrefix . '-Mannum', $fullYear ); case TimeValue::PRECISION_100ka: $fullYear = round( $fullYear, -5 ); - return $this->getMessage( 'wikibase-time-precision-annum', $fullYear ); + return $this->getMessage( $msgPrefix . '-annum', $fullYear ); case TimeValue::PRECISION_10ka: $fullYear = round( $fullYear, -4 ); - return $this->getMessage( 'wikibase-time-precision-annum', $fullYear ); + return $this->getMessage( $msgPrefix . '-annum', $fullYear ); case TimeValue::PRECISION_ka: $fullYear = round( $fullYear, -3 ); $fullYear = substr( $fullYear, 0, -3 ); - return $this->getMessage( 'wikibase-time-precision-millennium', $fullYear ); + return $this->getMessage( $msgPrefix . '-millennium', $fullYear ); case TimeValue::PRECISION_100a: $fullYear = round( $fullYear, -2 ); $fullYear = substr( $fullYear, 0, -2 ); - return $this->getMessage( 'wikibase-time-precision-century', $fullYear ); + return $this->getMessage( $msgPrefix . '-century', $fullYear ); case TimeValue::PRECISION_10a: $fullYear = round( $fullYear, -1 ); - return $this->getMessage( 'wikibase-time-precision-10annum', $fullYear ); + return $this->getMessage( $msgPrefix . '-10annum', $fullYear ); default: //If not one of the above make sure the year have at least 4 digits $fullYear = ltrim( $fullYear, '0' ); - $fullYearLength = strlen( $fullYear ); - if( $fullYearLength < 4 ) { - $fullYear = str_repeat( '0', 4 - $fullYearLength ) . $fullYear; - } - //only add separators if there are more than 4 digits - if( strlen( $fullYear ) > 4 ) { - $fullYear = $this->language->formatNum( $fullYear ); + if( $isBCE ) { + $fullYear .= ' BCE'; } return $fullYear; } @@ -185,9 +194,10 @@ $message = new Message( $key ); //FIXME: as the frontend can not parse the translated precisions we only want to present the ENGLISH for now //once the frontend is using backend parsers we can switch the translation on + //See the fix me in: MwTimeIsoParser::reconvertOutputString //$message->inLanguage( $this->language ); $message->inLanguage( new Language() ); - $message->numParams( array( $fullYear ) ); + $message->params( array( $fullYear ) ); return $message->text(); } diff --git a/lib/tests/phpunit/formatters/MwTimeIsoFormatterTest.php b/lib/tests/phpunit/formatters/MwTimeIsoFormatterTest.php index 2a7675a..613db09 100644 --- a/lib/tests/phpunit/formatters/MwTimeIsoFormatterTest.php +++ b/lib/tests/phpunit/formatters/MwTimeIsoFormatterTest.php @@ -28,19 +28,20 @@ */ public function formatDateProvider() { $tests = array( + //+ dates + '16 August 2013' => array( + '+2013-08-16T00:00:00Z', + TimeValue::PRECISION_DAY, + ), '16 July 2013' => array( '+00000002013-07-16T00:00:00Z', TimeValue::PRECISION_DAY, ), - '1 January 0000' => array( - '+00000000000-01-01T00:00:00Z', - TimeValue::PRECISION_DAY, - ), - '14 January 0001' => array( + '14 January 1' => array( '+00000000001-01-14T00:00:00Z', TimeValue::PRECISION_DAY, ), - '1 January 10,000' => array( + '1 January 10000' => array( '+00000010000-01-01T00:00:00Z', TimeValue::PRECISION_DAY, ), @@ -52,80 +53,80 @@ '+00000002013-07-16T00:00:00Z', TimeValue::PRECISION_YEAR, ), - '0013' => array( + '13' => array( '+00000000013-07-16T00:00:00Z', TimeValue::PRECISION_YEAR, ), - '2,222,013' => array( + '2222013' => array( '+00002222013-07-16T00:10:00Z', TimeValue::PRECISION_YEAR, ), - '12,342,222,013' => array( + '12342222013' => array( '+12342222013-07-16T00:10:00Z', TimeValue::PRECISION_YEAR, ), //stepping through precisions - '12,345,678,910s' => array( + '12345678910s' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_10a, ), - '12,345,678,920s' => array( + '12345678920s' => array( '+12345678919-01-01T01:01:01Z', TimeValue::PRECISION_10a, ), - '123,456,789. century' => array( + '123456789. century' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_100a, ), - '123,456,790. century' => array( + '123456790. century' => array( '+12345678992-01-01T01:01:01Z', TimeValue::PRECISION_100a, ), - '12,345,678. millennium' => array( + '12345678. millennium' => array( '+12345678112-01-01T01:01:01Z', TimeValue::PRECISION_ka, ), - '12,345,679. millennium' => array( + '12345679. millennium' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_ka, ), - 'in 12,345,670,000 years' => array( + 'in 12345670000 years' => array( '+12345671912-01-01T01:01:01Z', TimeValue::PRECISION_10ka, ), - 'in 12,345,680,000 years' => array( + 'in 12345680000 years' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_10ka, ), - 'in 12,345,600,000 years' => array( + 'in 12345600000 years' => array( '+12345618912-01-01T01:01:01Z', TimeValue::PRECISION_100ka, ), - 'in 12,345,700,000 years' => array( + 'in 12345700000 years' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_100ka, ), - 'in 12,345 million years' => array( + 'in 12345 million years' => array( '+12345178912-01-01T01:01:01Z', TimeValue::PRECISION_Ma, ), - 'in 12,346 million years' => array( + 'in 12346 million years' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_Ma, ), - 'in 12,340 million years' => array( + 'in 12340 million years' => array( '+12341678912-01-01T01:01:01Z', TimeValue::PRECISION_10Ma, ), - 'in 12,350 million years' => array( + 'in 12350 million years' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_10Ma, ), - 'in 12,300 million years' => array( + 'in 12300 million years' => array( '+12345678912-01-01T01:01:01Z', TimeValue::PRECISION_100Ma, ), - 'in 12,400 million years' => array( + 'in 12400 million years' => array( '+12375678912-01-01T01:01:01Z', TimeValue::PRECISION_100Ma, ), @@ -137,11 +138,131 @@ '+12545678912-01-01T01:01:01Z', TimeValue::PRECISION_Ga, ), - //The below should still return the full timestamp as we can not yet format - '-00000000001-01-01T00:00:00Z' => array( - '-00000000001-01-01T00:00:00Z', + + //- dates + '16 August 2013 BCE' => array( + '-2013-08-16T00:00:00Z', TimeValue::PRECISION_DAY, ), + '16 July 2013 BCE' => array( + '-00000002013-07-16T00:00:00Z', + TimeValue::PRECISION_DAY, + ), + '14 January 1 BCE' => array( + '-00000000001-01-14T00:00:00Z', + TimeValue::PRECISION_DAY, + ), + '1 January 10000 BCE' => array( + '-00000010000-01-01T00:00:00Z', + TimeValue::PRECISION_DAY, + ), + 'July 2013 BCE' => array( + '-00000002013-07-16T00:00:00Z', + TimeValue::PRECISION_MONTH, + ), + '2013 BCE' => array( + '-00000002013-07-16T00:00:00Z', + TimeValue::PRECISION_YEAR, + ), + '13 BCE' => array( + '-00000000013-07-16T00:00:00Z', + TimeValue::PRECISION_YEAR, + ), + '2222013 BCE' => array( + '-00002222013-07-16T00:10:00Z', + TimeValue::PRECISION_YEAR, + ), + '12342222013 BCE' => array( + '-12342222013-07-16T00:10:00Z', + TimeValue::PRECISION_YEAR, + ), + //stepping through precisions + '12345678910s BCE' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_10a, + ), + '12345678920s BCE' => array( + '-12345678919-01-01T01:01:01Z', + TimeValue::PRECISION_10a, + ), + '123456789. century BCE' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_100a, + ), + '123456790. century BCE' => array( + '-12345678992-01-01T01:01:01Z', + TimeValue::PRECISION_100a, + ), + '12345678. millennium BCE' => array( + '-12345678112-01-01T01:01:01Z', + TimeValue::PRECISION_ka, + ), + '12345679. millennium BCE' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_ka, + ), + '12345670000 years ago' => array( + '-12345671912-01-01T01:01:01Z', + TimeValue::PRECISION_10ka, + ), + '12345680000 years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_10ka, + ), + '12345600000 years ago' => array( + '-12345618912-01-01T01:01:01Z', + TimeValue::PRECISION_100ka, + ), + '12345700000 years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_100ka, + ), + '12345 million years ago' => array( + '-12345178912-01-01T01:01:01Z', + TimeValue::PRECISION_Ma, + ), + '12346 million years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_Ma, + ), + '12340 million years ago' => array( + '-12341678912-01-01T01:01:01Z', + TimeValue::PRECISION_10Ma, + ), + '12350 million years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_10Ma, + ), + '12300 million years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_100Ma, + ), + '12400 million years ago' => array( + '-12375678912-01-01T01:01:01Z', + TimeValue::PRECISION_100Ma, + ), + '12 billion years ago' => array( + '-12345678912-01-01T01:01:01Z', + TimeValue::PRECISION_Ga, + ), + '13 billion years ago' => array( + '-12545678912-01-01T01:01:01Z', + TimeValue::PRECISION_Ga, + ), + + // Stuff we dont want to format so must return it :< + '-00000000000-01-01T01:01:01Z' => array( + '-00000000000-01-01T01:01:01Z', + TimeValue::PRECISION_Ga, + ), + '-0-01-01T01:01:01Z' => array( + '-0-01-01T01:01:01Z', + TimeValue::PRECISION_Ga, + ), + 'foobar' => array( + 'foobar', + TimeValue::PRECISION_Ga, + ), ); $argLists = array(); diff --git a/repo/tests/phpunit/includes/api/FormatSnakValueTest.php b/repo/tests/phpunit/includes/api/FormatSnakValueTest.php index 4c70191..6ec45e2 100644 --- a/repo/tests/phpunit/includes/api/FormatSnakValueTest.php +++ b/repo/tests/phpunit/includes/api/FormatSnakValueTest.php @@ -16,6 +16,7 @@ * @group Wikibase * @group WikibaseAPI * @group WikibaseRepo + * @group FormatSnakValueAPI * * @group medium * @@ -38,6 +39,11 @@ TimeValue::PRECISION_DAY, TimeFormatter::CALENDAR_GREGORIAN ); + $november = new TimeValue( '+00000002013-11-10T00:00:00Z', + 1 * 60 * 60, 0, 0, + TimeValue::PRECISION_MONTH, + TimeFormatter::CALENDAR_GREGORIAN ); + return array( array( new StringValue( 'test' ), null, @@ -51,6 +57,12 @@ array( TimeFormatter::OPT_LANG => 'en' ), '/^11 November 2013$/' ), + array( $november, + null, + null, + array( TimeFormatter::OPT_LANG => 'en' ), + '/^November 2013$/' ), + /* // TimeFormatter is currently bypassed; This test can only work once we start using it again. array( $november11, null, -- To view, visit https://gerrit.wikimedia.org/r/117196 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib9dc95e78e7b9b99579e8309c1ba3481adcfa9b8 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Addshore <addshorew...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits