[MediaWiki-commits] [Gerrit] mediawiki...Wikibase[master]: Fix (Julian)DateTimeValueCleaner for extreme years
jenkins-bot has submitted this change and it was merged. Change subject: Fix (Julian)DateTimeValueCleaner for extreme years .. Fix (Julian)DateTimeValueCleaner for extreme years This fixes a series of issues, including: * Converting years to int fails on Int32 systems. * PHP's Julian day conversion functions return zero in many cases. Bug: T146356 Change-Id: Ia6941a20da7e3daf232f54118aff1296bbedb1e8 --- M repo/includes/Rdf/DateTimeValueCleaner.php M repo/includes/Rdf/JulianDateTimeValueCleaner.php M repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php 3 files changed, 40 insertions(+), 14 deletions(-) Approvals: Hoo man: Looks good to me, approved jenkins-bot: Verified diff --git a/repo/includes/Rdf/DateTimeValueCleaner.php b/repo/includes/Rdf/DateTimeValueCleaner.php index 45a673f..459cecc 100644 --- a/repo/includes/Rdf/DateTimeValueCleaner.php +++ b/repo/includes/Rdf/DateTimeValueCleaner.php @@ -86,7 +86,7 @@ // If we have year's or finer precision, to make year match XSD 1.1 we // need to bump up the negative years by 1 // Note that $y is an absolute value here. - $y = (string)( (int)$y - 1 ); + $y = number_format( (float)$y - 1, 0, '', '' ); if ( $y == "0" ) { $minus = ""; } diff --git a/repo/includes/Rdf/JulianDateTimeValueCleaner.php b/repo/includes/Rdf/JulianDateTimeValueCleaner.php index b25f634..f247ec5 100644 --- a/repo/includes/Rdf/JulianDateTimeValueCleaner.php +++ b/repo/includes/Rdf/JulianDateTimeValueCleaner.php @@ -54,21 +54,27 @@ } catch ( IllegalValueException $e ) { return null; } - // We accept here certain precision loss since we will need to do calculations anyway, - // and we can't calculate with dates that don't fit in int. - $y = $minus ? -(int)$y : (int)$y; - // cal_to_jd needs int year - // If it's too small it's fine, we'll get 0 - // If it's too big, it doesn't make sense anyway, - // since who uses Julian with day precision in year 2 billion? - $jd = cal_to_jd( CAL_JULIAN, $m, $d, (int)$y ); - if ( $jd == 0 ) { - // that means the date is broken - return null; + $y = $minus ? -$y : $y + 0; + if ( !is_int( $y ) || $y < -4713 ) { + // Fall back to >= 1 year precision when Julian to Gregorian conversion is not possible. + return $this->cleanupGregorianValue( $dateValue, TimeValue::PRECISION_YEAR ); } + + $jd = juliantojd( $m, $d, $y ); + if ( $jd == 0 ) { + // Fall back to >= 1 year precision when Julian to Gregorian conversion is not possible. + return $this->cleanupGregorianValue( $dateValue, TimeValue::PRECISION_YEAR ); + } + // PHP API for Julian/Gregorian conversions is kind of awful - list( $m, $d, $y ) = explode( '/', jdtogregorian( $jd ) ); + $gregorian = jdtogregorian( $jd ); + if ( $gregorian === '0/0/0' ) { + // Fall back to >= 1 year precision when Julian to Gregorian conversion is not possible. + return $this->cleanupGregorianValue( $dateValue, TimeValue::PRECISION_YEAR ); + } + + list( $m, $d, $y ) = explode( '/', $gregorian ); if ( $this->xsd11 && $y < 0 ) { // To make year match XSD 1.1 we need to bump up the negative years by 1 diff --git a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php index ec56642..1295ef4 100644 --- a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php +++ b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php @@ -44,13 +44,23 @@ [ '+0002204-04-31T00:00:00Z', $greg, '2204-04-01T00:00:00Z', $month ], [ '+000-04-31T00:00:00Z', $greg, null ], [ '-000-04-31T00:00:00Z', $greg, null ], + [ '+98765432198765-00-00T00:00:00Z', $greg, '98765432198765-01-01T00:00:00Z', $year ], + [ '-98765432198765-00-00T00:00:00Z', $greg, '-98765432198765-01-01T00:00:00Z', $year ], + [ '+-01-01T00:00:00Z', $greg, '-01-01T00:00:00Z' ], + [ '--01-01T00:00:00Z', $greg, '--01-01T00:00:00Z' ], // Julian [
[MediaWiki-commits] [Gerrit] mediawiki...Wikibase[master]: Fix (Julian)DateTimeValueCleaner for extreme years
Thiemo Mättig (WMDE) has uploaded a new change for review. https://gerrit.wikimedia.org/r/312215 Change subject: Fix (Julian)DateTimeValueCleaner for extreme years .. Fix (Julian)DateTimeValueCleaner for extreme years This fixes a series of issues, including: * Converting years to int fails on Int32 systems. * PHP's Julian day conversion functions return zero in many cases. Bug: T146356 Change-Id: Ia6941a20da7e3daf232f54118aff1296bbedb1e8 --- M repo/includes/Rdf/DateTimeValueCleaner.php M repo/includes/Rdf/JulianDateTimeValueCleaner.php M repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php 3 files changed, 29 insertions(+), 7 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/15/312215/1 diff --git a/repo/includes/Rdf/DateTimeValueCleaner.php b/repo/includes/Rdf/DateTimeValueCleaner.php index 45a673f..459cecc 100644 --- a/repo/includes/Rdf/DateTimeValueCleaner.php +++ b/repo/includes/Rdf/DateTimeValueCleaner.php @@ -86,7 +86,7 @@ // If we have year's or finer precision, to make year match XSD 1.1 we // need to bump up the negative years by 1 // Note that $y is an absolute value here. - $y = (string)( (int)$y - 1 ); + $y = number_format( (float)$y - 1, 0, '', '' ); if ( $y == "0" ) { $minus = ""; } diff --git a/repo/includes/Rdf/JulianDateTimeValueCleaner.php b/repo/includes/Rdf/JulianDateTimeValueCleaner.php index b25f634..d0060be 100644 --- a/repo/includes/Rdf/JulianDateTimeValueCleaner.php +++ b/repo/includes/Rdf/JulianDateTimeValueCleaner.php @@ -54,21 +54,27 @@ } catch ( IllegalValueException $e ) { return null; } + // We accept here certain precision loss since we will need to do calculations anyway, // and we can't calculate with dates that don't fit in int. $y = $minus ? -(int)$y : (int)$y; // cal_to_jd needs int year // If it's too small it's fine, we'll get 0 - // If it's too big, it doesn't make sense anyway, - // since who uses Julian with day precision in year 2 billion? $jd = cal_to_jd( CAL_JULIAN, $m, $d, (int)$y ); if ( $jd == 0 ) { - // that means the date is broken - return null; + // Fall back to >= 1 year precision when Julian to Gregorian conversion is not possible. + return $this->cleanupGregorianValue( $dateValue, TimeValue::PRECISION_YEAR ); } + // PHP API for Julian/Gregorian conversions is kind of awful - list( $m, $d, $y ) = explode( '/', jdtogregorian( $jd ) ); + $gregorian = jdtogregorian( $jd ); + if ( $gregorian === '0/0/0' ) { + // Fall back to >= 1 year precision when Julian to Gregorian conversion is not possible. + return $this->cleanupGregorianValue( $dateValue, TimeValue::PRECISION_YEAR ); + } + + list( $m, $d, $y ) = explode( '/', $gregorian ); if ( $this->xsd11 && $y < 0 ) { // To make year match XSD 1.1 we need to bump up the negative years by 1 diff --git a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php index ec56642..edb5b77 100644 --- a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php +++ b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php @@ -44,13 +44,21 @@ [ '+0002204-04-31T00:00:00Z', $greg, '2204-04-01T00:00:00Z', $month ], [ '+000-04-31T00:00:00Z', $greg, null ], [ '-000-04-31T00:00:00Z', $greg, null ], + [ '+98765432198765-00-00T00:00:00Z', $greg, '98765432198765-01-01T00:00:00Z', $year ], + [ '-98765432198765-00-00T00:00:00Z', $greg, '-98765432198765-01-01T00:00:00Z', $year ], + [ '+-01-01T00:00:00Z', $greg, '-01-01T00:00:00Z' ], + [ '--01-01T00:00:00Z', $greg, '--01-01T00:00:00Z' ], // Julian [ '+0002014-01-05T12:34:56Z', $jul, '2014-01-18T12:34:56Z' ], [ '-0002014-01-05T12:34:56Z', $jul, '-2015-12-19T12:34:56Z' ], [ '+200-02-31T00:00:00Z', $jul, '0200-03-02T00:00:00Z' ], [ '+204-02-31T00:00:00Z', $jul, '0204-03-02T00:00:00Z' ], - [