From bcc23d6f465c47617e7c351c17c1a0d360e31dc6 Mon Sep 17 00:00:00 2001 From: Platonides Date: Sun, 31 Oct 2010 23:30:41 +0000 Subject: [PATCH] Change wfTimestamp() to an array() and add a bunch of timestamp tests hard for 32 bit php. Intended to ease transition to DateTime. See r74778 and Bug 25451 --- includes/GlobalFunctions.php | 49 +++++------ .../tests/phpunit/includes/GlobalTest.php | 81 +++++++++++++++++++ 2 files changed, 106 insertions(+), 24 deletions(-) diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index c082acc712..7b23e3dbd9 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2017,32 +2017,33 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { (int)$da[2], (int)$da[3], (int)$da[1] ); } - switch( $outputtype ) { - case TS_UNIX: + static $formats = array ( + TS_UNIX => 'U', + TS_MW => 'YmdHis', + TS_DB => 'Y-m-d H:i:s', + TS_ISO_8601 => 'Y-m-d\TH:i:s\Z', + TS_ISO_8601_BASIC => 'Ymd\THis\Z', + TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness + TS_RFC2822 => 'D, d M Y H:i:s', + TS_ORACLE => 'd-m-Y H:i:s.000000', //Was 'd-M-y h.i.s A' . ' +00:00' before r51500 + TS_POSTGRES => 'Y-m-d H:i:s', + TS_DB2 => 'Y-m-d H:i:s', + ); + + if ( !isset( $formats[$outputtype] ) ) { + throw new MWException( 'wfTimestamp() called with illegal output type.' ); + } + + if ( TS_UNIX == $outputtype ) return $uts; - case TS_MW: - return gmdate( 'YmdHis', $uts ); - case TS_DB: - return gmdate( 'Y-m-d H:i:s', $uts ); - case TS_ISO_8601: - return gmdate( 'Y-m-d\TH:i:s\Z', $uts ); - case TS_ISO_8601_BASIC: - return gmdate( 'Ymd\THis\Z', $uts ); - // This shouldn't ever be used, but is included for completeness - case TS_EXIF: - return gmdate( 'Y:m:d H:i:s', $uts ); - case TS_RFC2822: - return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT'; - case TS_ORACLE: - return gmdate( 'd-m-Y H:i:s.000000', $uts ); - //return gmdate( 'd-M-y h.i.s A', $uts ) . ' +00:00'; - case TS_POSTGRES: - return gmdate( 'Y-m-d H:i:s', $uts ) . ' GMT'; - case TS_DB2: - return gmdate( 'Y-m-d H:i:s', $uts ); - default: - throw new MWException( 'wfTimestamp() called with illegal output type.' ); + + $output = gmdate( $formats[$outputtype], $uts ); + + if ( ( $outputtype == TS_RFC2822 ) || ( $outputtype == TS_POSTGRES ) ) { + $output .= ' GMT'; } + + return $output; } /** diff --git a/maintenance/tests/phpunit/includes/GlobalTest.php b/maintenance/tests/phpunit/includes/GlobalTest.php index e41fbf1bec..a4aa2e30ec 100644 --- a/maintenance/tests/phpunit/includes/GlobalTest.php +++ b/maintenance/tests/phpunit/includes/GlobalTest.php @@ -145,6 +145,10 @@ class GlobalTest extends PHPUnit_Framework_TestCase { '20010115123456', wfTimestamp( TS_MW, $t ), 'TS_UNIX to TS_MW' ); + $this->assertEquals( + '19690115123456', + wfTimestamp( TS_MW, -30281104 ), + 'Negative TS_UNIX to TS_MW' ); $this->assertEquals( 979562096, wfTimestamp( TS_UNIX, $t ), @@ -193,6 +197,83 @@ class GlobalTest extends PHPUnit_Framework_TestCase { 'TS_DB to TS_ISO_8601_BASIC' ); } + /** + * This test checks wfTimestamp() with values outside. + * It needs PHP 64 bits or PHP > 5.1. + * See r74778 and bug 25451 + */ + function testOldTimestamps() { + $this->assertEquals( 'Fri, 13 Dec 1901 20:45:54 GMT', + wfTimestamp( TS_RFC2822, '19011213204554' ), + 'Earliest time according to php documentation' ); + + $this->assertEquals( 'Tue, 19 Jan 2038 03:14:07 GMT', + wfTimestamp( TS_RFC2822, '20380119031407' ), + 'Latest 32 bit time' ); + + $this->assertEquals( '-2147483648', + wfTimestamp( TS_UNIX, '19011213204552' ), + 'Earliest 32 bit unix time' ); + + $this->assertEquals( '2147483647', + wfTimestamp( TS_UNIX, '20380119031407' ), + 'Latest 32 bit unix time' ); + + $this->assertEquals( 'Fri, 13 Dec 1901 20:45:52 GMT', + wfTimestamp( TS_RFC2822, '19011213204552' ), + 'Earliest 32 bit time' ); + + $this->assertEquals( 'Fri, 13 Dec 1901 20:45:51 GMT', + wfTimestamp( TS_RFC2822, '19011213204551' ), + 'Earliest 32 bit time - 1' ); + + $this->assertEquals( 'Tue, 19 Jan 2038 03:14:08 GMT', + wfTimestamp( TS_RFC2822, '20380119031408' ), + 'Latest 32 bit time + 1' ); + + $this->assertEquals( '19011212000000', + wfTimestamp(TS_MW, '19011212000000'), + 'Convert to itself r74778#c10645' ); + + $this->assertEquals( '-2147483649', + wfTimestamp( TS_UNIX, '19011213204551' ), + 'Earliest 32 bit unix time - 1' ); + + $this->assertEquals( '2147483648', + wfTimestamp( TS_UNIX, '20380119031408' ), + 'Latest 32 bit unix time + 1' ); + + $this->assertEquals( '19011213204551', + wfTimestamp( TS_MW, '-2147483649' ), + '1901 negative unix time to MediaWiki' ); + + $this->assertEquals( '18010115123456', + wfTimestamp( TS_MW, '-5331871504' ), + '1801 negative unix time to MediaWiki' ); + + $this->assertEquals( 'Tue, 09 Aug 0117 12:34:56 GMT', + wfTimestamp( TS_RFC2822, '0117-08-09 12:34:56'), + 'Death of Roman Emperor [[Trajan]]'); + + /* FIXME: 00 to 101 years are taken as being in [1970-2069] */ + + $this->assertEquals( 'Sun, 01 Jan 0101 00:00:00 GMT', + wfTimestamp( TS_RFC2822, '-58979923200'), + '1/1/101'); + + $this->assertEquals( 'Mon, 01 Jan 0001 00:00:00 GMT', + wfTimestamp( TS_RFC2822, '-62135596800'), + 'Year 1'); + + /* It is not clear if we should generate a year 0 or not + * We are completely off RFC2822 requirement of year being + * 1900 or later. + */ + $this->assertEquals( 'Wed, 18 Oct 0000 00:00:00 GMT', + wfTimestamp( TS_RFC2822, '-62142076800'), + 'ISO 8601:2004 [[year 0]], also called [[1 BC]]'); + } + function testBasename() { $sets = array( '' => '', -- 2.20.1