summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwei <>2006-08-30 08:35:39 +0000
committerwei <>2006-08-30 08:35:39 +0000
commitadab65ab49f125b39bf819abe68b0790cbf394df (patch)
tree280c6f994e1341f3915f71805fbcf22e5b059e5d
parentda895b1c97234c9640d94bef0e2027b9fc8a6a66 (diff)
Added TDateTimeStamp class for supporting time stamps outside 1970-2038 using float
-rw-r--r--.gitattributes2
-rw-r--r--HISTORY1
-rw-r--r--framework/3rdParty/readme.html29
-rw-r--r--framework/Util/TSimpleDateFormatter.php14
-rw-r--r--framework/Web/UI/WebControls/TDatePicker.php8
-rw-r--r--tests/FunctionalTests/tickets/protected/pages/Ticket351.page12
-rw-r--r--tests/unit/Util/DateTimeStampTestCase.php162
7 files changed, 211 insertions, 17 deletions
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.
<td><a href="http://pear.php.net/package/DB">PEAR :: Package :: DB</a></td>
<td><a href="http://www.php.net/license/3_0.txt">PHP License 3.0</a></td>
<td>N.A.</td>
- <td>The parseDSN() function from DB.php file.</td>
+ <td>The parseDSN() function from DB.php file.</td>
</tr>
<tr>
<td><a href="../I18N/core/TCache_Lite.php">../I18N/core/TCache_Lite.php</a></td>
<td><a href="http://pear.php.net/package/Cache_Lite">PEAR :: Package :: Cache_Lite</a></td>
<td><a href="http://www.gnu.org/licenses/lgpl.html">LGPL</a></td>
<td>N.A.</td>
- <td>Cache_Lite class was renamed as TCache_Lite for packaging purposes.</td>
+ <td>Cache_Lite class was renamed as TCache_Lite for packaging purposes.</td>
</tr>
<tr>
<td><a href="../I18N/core/Gettext">../I18N/core/Gettext</a></td>
<td><a href="http://pear.php.net/package/File_Gettext">PEAR :: Package :: File_Gettext</a></td>
<td><a href="http://www.php.net/license/3_0.txt">PHP License 3.0</a></td>
<td>N.A.</td>
- <td>File_Gettext, File::Gettext::MO, and File::Gettext::PO</td>
+ <td>File_Gettext, File::Gettext::MO, and File::Gettext::PO</td>
</tr>
<tr>
@@ -83,7 +83,7 @@ projects.
<td><a href="http://pear.php.net/pepr/pepr-proposal-show.php?id=198">Service_JSON proposal</a></td>
<td><a href="http://www.opensource.org/licenses/bsd-license.php">BSD</a></td>
<td>N.A.</td>
- <td>JSON encoder/decoder by Michal Migurski, Matt Knapp and Brett Stimmerman</td>
+ <td>JSON encoder/decoder by Michal Migurski, Matt Knapp and Brett Stimmerman</td>
</tr>
<tr>
@@ -91,21 +91,21 @@ projects.
<td><a href="http://openrico.org/">Rico</a></td>
<td><a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache License v2</a></td>
<td>N.A.</td>
- <td>Rico Javascript Library (not yet utilized in Prado)</td>
+ <td>Rico Javascript Library (not yet utilized in Prado)</td>
</tr>
<tr>
<td><a href="../Web/Javascripts/prototype/">../Web/Javascripts/prototype</a></td>
<td><a href="http://dev.rubyonrails.org/browser/spinoffs/prototype">Prototype javascript library</a></td>
<td><a href="../Web/Javascripts/prototype/LICENSE">The Prototype License (MIT based)</a></td>
<td>N.A.</td>
- <td>Core of Prado javascript library.</td>
+ <td>Core of Prado javascript library.</td>
</tr>
<tr>
<td><a href="../Web/Javascripts/extra/logger.js">../Web/Javascripts/extra/logger.js</a></td>
<td><a href="http://gleepglop.com/javascripts/logger/">http://gleepglop.com/javascripts/logger/</a> <a href="http://slayeroffice.com">http://slayeroffice.com</a></td>
<td>None</td>
<td>TJavascriptLogger</td>
- <td>Javascript logger by Corey Johnson. Object Tree by S.G. Chipman.</td>
+ <td>Javascript logger by Corey Johnson. Object Tree by S.G. Chipman.</td>
</tr>
<tr>
@@ -113,7 +113,7 @@ projects.
<td><a href="http://www.JSON.org">http://www.JSON.org</a></td>
<td><a href="http://www.json.org/license.html">MIT based</a></td>
<td>N.A.</td>
- <td>Has "The Software shall be used for Good, not Evil." clause.</td>
+ <td>Has "The Software shall be used for Good, not Evil." clause.</td>
</tr>
<tr>
@@ -122,7 +122,7 @@ projects.
<td><a href="../../demos/quickstart/protected/index/Zend/LICENSE.txt">BSD</a></td>
<td>Quickstart tutorial indexing and search is provided the Zend Lucene search implementation.</td>
<td>This product includes the Zend Framework, freely available at
- http://www.zend.com</td>
+ http://www.zend.com</td>
</tr>
<tr>
@@ -130,9 +130,18 @@ projects.
<td><a href="http://www.michelf.com/projects/php-markdown/">PHP Markdown</a></td>
<td><a href="Markdown/License.text">BSD</a></td>
<td>System.Web.UI.WebControls.TMarkdown</td>
- <td>PHP5 class implementation of the PHP Markdown.</td>
+ <td>PHP5 class implementation of the PHP Markdown.</td>
</tr>
+<tr>
+ <td><a href="../Util">../Util</a></td>
+ <td><a href="http://phplens.com/phpeverywhere/adodb_date_library">ADOdb Date Time Library</a></td>
+ <td><a href="http://phplens.com/phpeverywhere/adodb_date_library">BSD</a></td>
+ <td>System.Util.TDateTimeStamp</td>
+ <td>TimeStamp support for dates outside the 1970-2038.</td>
+</tr>
+
+
</table>
</p>
</body>
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 @@
+<com:TContent ID="Content">
+<com:TDatePicker ID="Birthdate"
+ DateFormat="MMM/d/yyyy"
+ FromYear="1900" UpToYear="1990" InputMode="DropDownList" />
+
+<br />
+<%= $this->Birthdate->Date %>
+<br />
+<%= $this->Birthdate->TimeStamp %>
+
+<com:TButton Text="Submit!" />
+</com:TContent> \ 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 @@
+<?php
+
+require_once dirname(__FILE__).'/../phpunit2.php';
+
+Prado::using('System.Util.TDateTimeStamp');
+
+class DateTimeStampTestCase extends PHPUnit2_Framework_TestCase
+{
+ function testGetTimeStampAndFormat()
+ {
+ $s = new TDateTimeStamp;
+ $t = $s->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 <br>$s2 <p>";
+ $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