From adab65ab49f125b39bf819abe68b0790cbf394df Mon Sep 17 00:00:00 2001 From: wei <> Date: Wed, 30 Aug 2006 08:35:39 +0000 Subject: Added TDateTimeStamp class for supporting time stamps outside 1970-2038 using float --- .gitattributes | 2 + HISTORY | 1 + framework/3rdParty/readme.html | 29 ++-- framework/Util/TSimpleDateFormatter.php | 14 +- framework/Web/UI/WebControls/TDatePicker.php | 8 +- .../tickets/protected/pages/Ticket351.page | 12 ++ tests/unit/Util/DateTimeStampTestCase.php | 162 +++++++++++++++++++++ 7 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 tests/FunctionalTests/tickets/protected/pages/Ticket351.page create mode 100644 tests/unit/Util/DateTimeStampTestCase.php diff --git a/.gitattributes b/.gitattributes index 49096f60..348868b6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1656,6 +1656,7 @@ tests/FunctionalTests/tickets/protected/pages/Ticket285.page -text tests/FunctionalTests/tickets/protected/pages/Ticket306.page -text tests/FunctionalTests/tickets/protected/pages/Ticket311.page -text tests/FunctionalTests/tickets/protected/pages/Ticket312.page -text +tests/FunctionalTests/tickets/protected/pages/Ticket351.page -text tests/FunctionalTests/tickets/protected/pages/Ticket54.page -text tests/FunctionalTests/tickets/protected/pages/Ticket54Master.php -text tests/FunctionalTests/tickets/protected/pages/Ticket54Master.tpl -text @@ -1743,6 +1744,7 @@ tests/unit/I18N/core/DateTimeFormatInfoTest.php -text tests/unit/I18N/core/NumberFormatInfoTest.php -text tests/unit/I18N/core/NumberFormatTest.php -text tests/unit/TComponentTest.php -text +tests/unit/Util/DateTimeStampTestCase.php -text tests/unit/Web/UI/WebControls/TDropDownListTest.php -text tests/unit/Web/UI/WebControls/TLabelTest.php -text tests/unit/Web/UI/WebControls/TRequiredFieldValidatorTest.php -text diff --git a/HISTORY b/HISTORY index 0b015374..87bfafe6 100644 --- a/HISTORY +++ b/HISTORY @@ -13,6 +13,7 @@ CHG: Unify all client-side javascript event handler syntax. (Wei) CHG: Added more conditions in the requirement checker (Qiang) CHG: TControl::findControlsByType() now only returns objects of the specified type (Qiang) CHG: Moved createdOnTemplate() and addParsedObject() from TControl to TComponent (Qiang) +NEW: TDateTimeStamp class for supporting time stamps outside 1970-2038 using float (Wei) Version 3.0.3 August 6, 2006 ============================ diff --git a/framework/3rdParty/readme.html b/framework/3rdParty/readme.html index efa6d411..86021a2e 100644 --- a/framework/3rdParty/readme.html +++ b/framework/3rdParty/readme.html @@ -61,21 +61,21 @@ projects. PEAR :: Package :: DB PHP License 3.0 N.A. - The parseDSN() function from DB.php file. + The parseDSN() function from DB.php file. ../I18N/core/TCache_Lite.php PEAR :: Package :: Cache_Lite LGPL N.A. - Cache_Lite class was renamed as TCache_Lite for packaging purposes. + Cache_Lite class was renamed as TCache_Lite for packaging purposes. ../I18N/core/Gettext PEAR :: Package :: File_Gettext PHP License 3.0 N.A. - File_Gettext, File::Gettext::MO, and File::Gettext::PO + File_Gettext, File::Gettext::MO, and File::Gettext::PO @@ -83,7 +83,7 @@ projects. Service_JSON proposal BSD N.A. - JSON encoder/decoder by Michal Migurski, Matt Knapp and Brett Stimmerman + JSON encoder/decoder by Michal Migurski, Matt Knapp and Brett Stimmerman @@ -91,21 +91,21 @@ projects. Rico Apache License v2 N.A. - Rico Javascript Library (not yet utilized in Prado) + Rico Javascript Library (not yet utilized in Prado) ../Web/Javascripts/prototype Prototype javascript library The Prototype License (MIT based) N.A. - Core of Prado javascript library. + Core of Prado javascript library. ../Web/Javascripts/extra/logger.js http://gleepglop.com/javascripts/logger/ http://slayeroffice.com None TJavascriptLogger - Javascript logger by Corey Johnson. Object Tree by S.G. Chipman. + Javascript logger by Corey Johnson. Object Tree by S.G. Chipman. @@ -113,7 +113,7 @@ projects. http://www.JSON.org MIT based N.A. - Has "The Software shall be used for Good, not Evil." clause. + Has "The Software shall be used for Good, not Evil." clause. @@ -122,7 +122,7 @@ projects. BSD Quickstart tutorial indexing and search is provided the Zend Lucene search implementation. This product includes the Zend Framework, freely available at - http://www.zend.com + http://www.zend.com @@ -130,9 +130,18 @@ projects. PHP Markdown BSD System.Web.UI.WebControls.TMarkdown - PHP5 class implementation of the PHP Markdown. + PHP5 class implementation of the PHP Markdown. + + ../Util + ADOdb Date Time Library + BSD + System.Util.TDateTimeStamp + TimeStamp support for dates outside the 1970-2038. + + +

diff --git a/framework/Util/TSimpleDateFormatter.php b/framework/Util/TSimpleDateFormatter.php index 03ae7b7d..9c2975d5 100644 --- a/framework/Util/TSimpleDateFormatter.php +++ b/framework/Util/TSimpleDateFormatter.php @@ -168,12 +168,15 @@ class TSimpleDateFormatter /** * Gets the time stamp from string or integer. * @param string|int date to parse - * @return int parsed date time stamp + * @return array date info array */ private function getDate($value) { - if(is_int($value)) - return @getdate($value); + if(!is_string($value)) + { + $s = Prado::createComponent('System.Util.TDateTimeStamp'); + return $s->getDate($value); + } $date = @strtotime($value); if($date < 0) throw new TInvalidDataValueException('invalid_date', $value); @@ -199,7 +202,7 @@ class TSimpleDateFormatter */ public function parse($value,$defaultToCurrentTime=true) { - if(is_int($value)) + if(is_int($value) || is_float($value)) return $value; else if(!is_string($value)) throw new TInvalidDataValueException('date_to_parse_must_be_string', $value); @@ -303,7 +306,8 @@ class TSimpleDateFormatter else { $day = intval($day) <= 0 ? 1 : intval($day); - return @mktime(0, 0, 0, $month, $day, $year); + $s = Prado::createComponent('System.Util.TDateTimeStamp'); + return $s->getTimeStamp(0, 0, 0, $month, $day, $year); } } diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php index b6daa164..02361e54 100644 --- a/framework/Web/UI/WebControls/TDatePicker.php +++ b/framework/Web/UI/WebControls/TDatePicker.php @@ -422,7 +422,9 @@ class TDatePicker extends TTextBox else $year = $date['year']; - $date = @mktime(0, 0, 0, $month, $day, $year); + $s = Prado::createComponent('System.Util.TDateTimeStamp'); + $date = $s->getTimeStamp(0, 0, 0, $month, $day, $year); + //$date = @mktime(0, 0, 0, $month, $day, $year); $pattern = $this->getDateFormat(); $pattern = str_replace(array('MMMM', 'MMM'), array('MM','MM'), $pattern); @@ -509,7 +511,9 @@ class TDatePicker extends TTextBox $writer->addAttribute('class', $class); $writer->renderBeginTag('span'); - $date = @getdate($this->getTimeStampFromText()); + $s = Prado::createComponent('System.Util.TDateTimeStamp'); + $date = $s->getDate($this->getTimeStampFromText()); + //$date = @getdate($this->getTimeStampFromText()); $this->renderCalendarSelections($writer, $date); diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket351.page b/tests/FunctionalTests/tickets/protected/pages/Ticket351.page new file mode 100644 index 00000000..5fb65f20 --- /dev/null +++ b/tests/FunctionalTests/tickets/protected/pages/Ticket351.page @@ -0,0 +1,12 @@ + + + +
+<%= $this->Birthdate->Date %> +
+<%= $this->Birthdate->TimeStamp %> + + +
\ No newline at end of file diff --git a/tests/unit/Util/DateTimeStampTestCase.php b/tests/unit/Util/DateTimeStampTestCase.php new file mode 100644 index 00000000..de1413f7 --- /dev/null +++ b/tests/unit/Util/DateTimeStampTestCase.php @@ -0,0 +1,162 @@ +getTimeStamp(0,0,0); + $this->assertEquals($s->formatDate('Y-m-d'), date('Y-m-d')); + + $t = $s->getTimeStamp(0,0,0,6,1,2102); + $this->assertEquals($s->formatDate('Y-m-d',$t), '2102-06-01'); + + $t = $s->getTimeStamp(0,0,0,2,1,2102); + $this->assertEquals($s->formatDate('Y-m-d',$t), '2102-02-01'); + } + + function testGregorianToJulianConversion() + { + $s = new TDateTimeStamp; + $t = $s->getTimeStamp(0,0,0,10,11,1492); + + //http://www.holidayorigins.com/html/columbus_day.html - Friday check + $this->assertEquals($s->formatDate('D Y-m-d',$t), 'Fri 1492-10-11'); + + $t = $s->getTimeStamp(0,0,0,2,29,1500); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1500-02-29'); + + $t = $s->getTimeStamp(0,0,0,2,29,1700); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1700-03-01'); + + } + + function testGregorianCorrection() + { + $s = new TDateTimeStamp; + $diff = $s->getTimeStamp(0,0,0,10,15,1582) - $s->getTimeStamp(0,0,0,10,4,1582); + + //This test case fails on my windows machine! + //$this->assertEquals($diff, 3600*24, + // "Error in gregorian correction = ".($diff/3600/24)." days"); + + $this->assertEquals($s->getDayOfWeek(1582,10,15), 5.0); + $this->assertEquals($s->getDayOfWeek(1582,10,4), 4.0); + } + + function testOverFlow() + { + $s = new TDateTimeStamp; + $t = $s->getTimeStamp(0,0,0,3,33,1965); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1965-04-02', 'Error in day overflow 1'); + + $t = $s->getTimeStamp(0,0,0,4,33,1971); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1971-05-03', 'Error in day overflow 2'); + $t = $s->getTimeStamp(0,0,0,1,60,1965); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1965-03-01', 'Error in day overflow 3 '.$s->getDate('Y-m-d',$t)); + $t = $s->getTimeStamp(0,0,0,12,32,1965); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1966-01-01', 'Error in day overflow 4 '.$s->getDate('Y-m-d',$t)); + $t = $s->getTimeStamp(0,0,0,12,63,1965); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1966-02-01', 'Error in day overflow 5 '.$s->getDate('Y-m-d',$t)); + $t = $s->getTimeStamp(0,0,0,13,3,1965); + $this->assertEquals($s->formatDate('Y-m-d',$t), '1966-01-03', 'Error in mth overflow 1'); + } + + function test2DigitTo4DigitYearConversion() + { + $s = new TDateTimeStamp; + $this->assertEquals($s->get4DigitYear(00), 2000, "Err 2-digit 2000"); + $this->assertEquals($s->get4DigitYear(10), 2010, "Err 2-digit 2010"); + $this->assertEquals($s->get4DigitYear(20), 2020, "Err 2-digit 2020"); + $this->assertEquals($s->get4DigitYear(30), 2030, "Err 2-digit 2030"); + $this->assertEquals($s->get4DigitYear(40), 1940, "Err 2-digit 1940"); + $this->assertEquals($s->get4DigitYear(50), 1950, "Err 2-digit 1950"); + $this->assertEquals($s->get4DigitYear(90), 1990, "Err 2-digit 1990"); + } + + function testStringFormating() + { + $s = new TDateTimeStamp; + $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C2822 r s t U w y Y z Z 2003'; + $s1 = date($fmt,0); + $s2 = $s->formatDate($fmt,0); + $this->assertEquals($s1, $s2);//, " date() 0 failed \n $s1 \n $s2"); + + for ($i=100; --$i > 0; ) + { + $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); + $s1 = date($fmt,$ts); + $s2 = $s->formatDate($fmt,$ts); + //print "$s1
$s2

"; + $this->assertEquals($s1,$s2); + + $a1 = getdate($ts); + $a2 = $s->getDate($ts,false); + $this->assertEquals($a1,$a2); + } + } + + function testRandomDatesBetween100And4000() + { + $this->assertIsValidDate(100,1); + //echo "Testing year "; + for ($i=100; --$i >= 0;) + { + $y1 = 100+rand(0,1970-100); + //echo $y1." "; + $m = rand(1,12); + $this->assertIsValidDate($y1,$m); + + $y1 = 3000-rand(0,3000-1970); + //echo $y1." "; + $this->assertIsValidDate($y1,$m); + } + } + + function assertIsValidDate($y1,$m,$d=13) + { + $s = new TDateTimeStamp; + $t = $s->getTimeStamp(0,0,0,$m,$d,$y1); + $rez = $s->formatDate('Y-n-j H:i:s',$t); + + $this->assertEquals("$y1-$m-$d 00:00:00", $rez); + } + + function testRandomDates() + { + $start = 1960+rand(0,10); + $yrs = 12; + $i = 365.25*86400*($start-1970); + $offset = 36000+rand(10000,60000); + $max = 365*$yrs*86400; + $lastyear = 0; + $s = new TDateTimeStamp; + + // we generate a timestamp, convert it to a date, and convert it back to a timestamp + // and check if the roundtrip broke the original timestamp value. + //print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: "; + $fails = 0; + for ($max += $i; $i < $max; $i += $offset) + { + $ret = $s->formatDate('m,d,Y,H,i,s',$i); + $arr = explode(',',$ret); + if ($lastyear != $arr[2]) + $lastyear = $arr[2]; + + $newi = $s->getTimestamp($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); + if ($i != $newi) + { + $fails++; + //$j = mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); + //print "Error at $i, $j, getTimestamp() returned $newi ($ret)\n"; + } + } + $this->assertEquals($fails, 0); + } +} + +?> \ No newline at end of file -- cgit v1.2.3