[limb-svn] r5832 - in 3.x/trunk/limb/datetime: src tests/cases
svn at limb-project.com
svn at limb-project.com
Tue May 8 16:32:32 MSD 2007
Author: pachanga
Date: 2007-05-08 16:32:32 +0400 (Tue, 08 May 2007)
New Revision: 5832
URL: http://fisheye.limb-project.com/changelog/limb/?cs=5832
Modified:
3.x/trunk/limb/datetime/src/lmbDate.class.php
3.x/trunk/limb/datetime/src/lmbMonthCalendar.class.php
3.x/trunk/limb/datetime/tests/cases/lmbDateTest.class.php
3.x/trunk/limb/datetime/tests/cases/lmbMonthCalendarTest.class.php
Log:
-- static lmbDate :: set/getFirstDayOfWeek() added
-- static lmbDate :: createByDays($days) added
-- static lmbDate :: createWithoutTime($year, $month, $day, $tz = '') added
-- lmbDate :: getBeginOfWeek() added
-- lmbDate :: getEndOfWeek() added
-- lmbDate :: getWeekOfYear() a bit simplified and fixed for values over 52
-- lmbMonthCalendar :: getWeek($n) added
-- lmbMonthCalendar :: getAllWeeks() added
-- lmbMonthCalendar :: getNextMonth() added
-- lmbMonthCalendar :: getPrevMonth() added
-- lmbMonthCalendar :: getNumberOfWeeks() is way more comprehensive and takes into account first day of week
Modified: 3.x/trunk/limb/datetime/src/lmbDate.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbDate.class.php 2007-05-08 11:45:14 UTC (rev 5831)
+++ 3.x/trunk/limb/datetime/src/lmbDate.class.php 2007-05-08 12:32:32 UTC (rev 5832)
@@ -11,11 +11,15 @@
*/
lmb_require('limb/core/src/lmbObject.class.php');
+define('LIMB_DATE_FIRST_WEEKDAY', 1);
+
class lmbDate extends lmbObject
{
//YYYY-MM-DD HH:MM:SS timezone
const DATE_ISO_REGEX = '~^(([0-9]{4})-([0-9]{2})-([0-9]{2}))?((?(1)\s+)([0-9]{2}):([0-9]{2}):?([0-9]{2})?)?$~';
+ static protected $first_day_week = 1;
+
protected $year = 0;
protected $month = 0;
protected $day = 0;
@@ -59,10 +63,13 @@
if(!$this->isValid())
{
$args = func_get_args();
- throw new lmbException("Could not create date using args '$args'");
+ throw new lmbException("Could not create date using args", $args);
}
}
+ /**
+ * Wrapper around constructor, it can be useful since the following is not allowed in PHP 'new lmbDate(..)->addDay(..)->'
+ */
static function create($hour_or_date=null, $minute_or_tz=0, $second=0, $day=0, $month=0, $year=0, $tz='')
{
if(func_num_args() > 2)
@@ -71,8 +78,57 @@
return new lmbDate($hour_or_date, $minute_or_tz);
}
- static function stampToISO($stamp)
+ static function createWithoutTime($year, $month, $day, $tz='')
{
+ return new lmbDate(0, 0, 0, $day, $month, $year, $tz);
+ }
+
+ static function createByDays($days)
+ {
+ $days -= 1721119;
+ $century = floor((4 * $days - 1) / 146097);
+ $days = floor(4 * $days - 1 - 146097 * $century);
+ $day = floor($days / 4);
+
+ $year = floor((4 * $day + 3) / 1461);
+ $day = floor(4 * $day + 3 - 1461 * $year);
+ $day = floor(($day + 4) / 4);
+
+ $month = floor((5 * $day - 3) / 153);
+ $day = floor(5 * $day - 3 - 153 * $month);
+ $day = floor(($day + 5) / 5);
+
+ if($month < 10)
+ {
+ $month +=3;
+ }
+ else
+ {
+ $month -=9;
+ if($year++ == 99)
+ {
+ $year = 0;
+ $century++;
+ }
+ }
+
+ $century = sprintf('%02d', $century);
+ $year = sprintf('%02d', $year);
+ return new lmbDate(0, 0, 0, $day, $month, $century . $year);
+ }
+
+ static function setFirstDayOfWeek($n)
+ {
+ self :: $first_day_week = $n;
+ }
+
+ static function getFirstDayOfWeek()
+ {
+ return self :: $first_day_week;
+ }
+
+ static function stampToIso($stamp)
+ {
$date = new lmbDate((int)$stamp);
return $date->getIsoDate();
}
@@ -289,6 +345,14 @@
$month = $this->month;
$day = $this->day;
+ if(1901 < $year && $year < 2038)
+ return (int)date('w', mktime(0, 0, 0, $month, $day, $year));
+
+ //gregorian correction
+ $correction = 0;
+ if(($year < 1582) || (($year == 1582) || (($month < 10) || (($month == 10) || ($day < 15)))))
+ $correction = 3;
+
if($month > 2)
{
$month -= 2;
@@ -299,15 +363,23 @@
$year--;
}
- $day = ( floor((13 * $month - 1) / 5) +
- $day + ($year % 100) +
- floor(($year % 100) / 4) +
- floor(($year / 100) / 4) - 2 *
- floor($year / 100) + 77);
+ $day = floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4);
+ $day += floor(($year / 100) / 4) - 2 * floor($year / 100) + 77 + $correction;
+ return (int)($day - 7 * floor($day / 7));
+ }
- $weekday_number = (($day - 7 * floor($day / 7)));
+ function getBeginOfWeek()
+ {
+ $this_weekday = $this->getDayOfWeek();
+ $interval = (7 - self :: $first_day_week + $this_weekday) % 7;
+ return lmbDate :: createByDays($this->getDateDays() - $interval);
+ }
- return $weekday_number - 1;
+ function getEndOfWeek()
+ {
+ $this_weekday = $this->getDayOfWeek();
+ $interval = (6 + self :: $first_day_week - $this_weekday) % 7;
+ return lmbDate :: createByDays($this->getDateDays() + $interval);
}
function getWeekOfYear()
@@ -316,61 +388,31 @@
$month = $this->month;
$year = $this->year;
- $mnth = array (0,31,59,90,120,151,181,212,243,273,304,334);
- $y_isleap = $this->isLeapYear();
- $d = new lmbDate($this);
- $d = $d->setYear($year - 1);
- $y_1_isleap = $d->isLeapYear();
-
- $day_of_year_number = $day + $mnth[$month - 1];
- if($y_isleap && $month > 2)
- $day_of_year_number++;
-
- // find Jan 1 weekday (monday = 1, sunday = 7)
- $yy = ($year - 1) % 100;
- $c = ($year - 1) - $yy;
- $g = $yy + intval($yy/4);
- $jan1_weekday = 1 + intval((((($c / 100) % 4) * 5) + $g) % 7);
- // weekday for year-month-day
- $h = $day_of_year_number + ($jan1_weekday - 1);
- $weekday = 1 + intval(($h - 1) % 7);
- // find if Y M D falls in YearNumber Y-1, WeekNumber 52 or
- if($day_of_year_number <= (8 - $jan1_weekday) && $jan1_weekday > 4)
+ if((1901 < $year) && ($year < 2038))
{
- $yearnumber = $year - 1;
- if($jan1_weekday == 5 || ($jan1_weekday == 6 && $y_1_isleap))
- $weeknumber = 53;
- else
- $weeknumber = 52;
+ $res = (int)date('W', mktime(0, 0, 0, $month, $day, $year));
+ if($res > 52) //bug in PHP date???
+ return $res % 52;
+ return $res;
}
- else
- $yearnumber = $year;
- // find if Y M D falls in YearNumber Y+1, WeekNumber 1
- if($yearnumber == $year)
- {
- if($y_isleap)
- $i = 366;
- else
- $i = 365;
- if(($i - $day_of_year_number) < (4 - $weekday))
- {
- $yearnumber++;
- $weeknumber = 1;
- }
- }
- // find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
- if($yearnumber == $year)
+ $dayofweek = $this->getDayOfWeek();
+ $firstday = self :: createWithoutTime($year, 1, 1)->getDayOfWeek();
+ if(($month == 1) && (($firstday < 1) || ($firstday > 4)) && ($day < 4))
{
- $j = $day_of_year_number + (7 - $weekday) + ($jan1_weekday - 1);
- $weeknumber = intval($j / 7);
- if($jan1_weekday > 4)
- $weeknumber--;
+ $firstday = self :: createWithoutTime($year - 1, 1, 1)->getDayOfWeek();
+ $month = 12;
+ $day = 31;
}
- return $weeknumber;
+ elseif(($month == 12) && ((self :: createWithoutTime($year + 1, 1, 1)->getDayOfWeek() < 5) &&
+ (self :: createWithoutTime($year + 1, 1, 1)->getDayOfWeek() > 0)))
+ return 1;
+
+ return intval(((self :: createWithoutTime($year, 1, 1)->getDayOfWeek() < 5) && (self :: createWithoutTime($year, 1, 1)->getDayOfWeek() > 0)) +
+ 4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
}
- function dateToDays()
+ function getDateDays()
{
$century = (int)substr("{$this->year}", 0, 2);
$year = (int)substr("{$this->year}", 2, 2);
Modified: 3.x/trunk/limb/datetime/src/lmbMonthCalendar.class.php
===================================================================
--- 3.x/trunk/limb/datetime/src/lmbMonthCalendar.class.php 2007-05-08 11:45:14 UTC (rev 5831)
+++ 3.x/trunk/limb/datetime/src/lmbMonthCalendar.class.php 2007-05-08 12:32:32 UTC (rev 5832)
@@ -15,14 +15,14 @@
{
protected $start_date;
protected $end_date;
-
+
function __construct($year, $month)
{
$tmp_date = new lmbDate(0, 0, 0, 0, $month, $year);
$this->start_date = $tmp_date->setDay(1);
$this->end_date = $this->start_date->addMonth(1)->addDay(-1);
}
-
+
function getStartDate()
{
return $this->start_date;
@@ -32,19 +32,69 @@
{
return $this->end_date;
}
-
+
function getNumberOfDays()
{
return $this->end_date->getDay();
}
-
+
function getNumberOfWeeks()
- {
- $dof_start = $this->start_date->getDayOfWeek();
- $dof_end = $this->end_date->getDayOfWeek() + 1;//fix it???
-
- $days = ($this->getNumberOfDays() - (7 - $dof_start) - $dof_end);
- return ((int)$days / 7) + 1 + (($dof_end > 0) ? 1 : 0);
+ {
+ $dof = $this->start_date->getDayOfWeek();
+ if(lmbDate :: getFirstDayOfWeek() == 1 && $dof == 0)
+ {
+ $first_week_days = 7 - $dof + lmbDate :: getFirstDayOfWeek();
+ $weeks = 1;
+ }
+ elseif(lmbDate :: getFirstDayOfWeek() == 0 && $dof == 6)
+ {
+ $first_week_days = 7 - $dof + lmbDate :: getFirstDayOfWeek();
+ $weeks = 1;
+ }
+ else
+ {
+ $first_week_days = lmbDate :: getFirstDayOfWeek() - $dof;
+ $weeks = 0;
+ }
+
+ $first_week_days %= 7;
+ return ceil(($this->getNumberOfDays() - $first_week_days) / 7) + $weeks;
}
+
+ function getWeek($n)
+ {
+ if($n < 0 || $n > $this->getNumberOfWeeks()-1)
+ return null;
+
+ $week_array = array();
+ $curr_day = ($n * 7) + $this->start_date->getBeginOfWeek()->getDateDays();
+
+ for($i=0;$i<=6;$i++)
+ {
+ $week_array[$i] = lmbDate :: createByDays($curr_day);
+ $curr_day++;
+ }
+ return $week_array;
+ }
+
+ function getAllWeeks()
+ {
+ $weeks = array();
+ for($i = 0; $i < $this->getNumberOfWeeks(); $i++)
+ $weeks[$i] = $this->getWeek($i);
+ return $weeks;
+ }
+
+ function getNextMonth()
+ {
+ $date = $this->end_date->addDay(1);
+ return new lmbMonthCalendar($date->getYear(), $date->getMonth());
+ }
+
+ function getPrevMonth()
+ {
+ $date = $this->start_date->addDay(-1);
+ return new lmbMonthCalendar($date->getYear(), $date->getMonth());
+ }
}
?>
\ No newline at end of file
Modified: 3.x/trunk/limb/datetime/tests/cases/lmbDateTest.class.php
===================================================================
--- 3.x/trunk/limb/datetime/tests/cases/lmbDateTest.class.php 2007-05-08 11:45:14 UTC (rev 5831)
+++ 3.x/trunk/limb/datetime/tests/cases/lmbDateTest.class.php 2007-05-08 12:32:32 UTC (rev 5832)
@@ -129,7 +129,7 @@
$this->assertEqual($date, $sample);
}
- function testCreateByISO()
+ function testCreateByIso()
{
$date = new lmbDate('2005-12-01 12:45:12');
$this->assertEqual(lmbDate :: create('2005-12-01 12:45:12'), $date);
@@ -144,7 +144,7 @@
$this->assertEqual($date->toString(), '2005-12-01 12:45:12');
}
- function testCreateByISODateOnly()
+ function testCreateByIsoDateOnly()
{
$date = new lmbDate('2005-12-01');
$this->assertEqual(lmbDate :: create('2005-12-01'), $date);
@@ -159,8 +159,14 @@
$this->assertEqual($date->toString(), '2005-12-01 00:00:00');
}
- function testCreateByISOTimeOnly()
+ function testCreateWithoutTime()
{
+ $date = new lmbDate('2005-12-01');
+ $this->assertEqual(lmbDate :: createWithoutTime(2005, 12, 1), $date);
+ }
+
+ function testCreateByIsoTimeOnly()
+ {
$date = new lmbDate('12:45:12');
$this->assertEqual(lmbDate :: create('12:45:12'), $date);
@@ -174,7 +180,7 @@
$this->assertEqual($date->toString(), '0000-00-00 12:45:12');
}
- function testCreateByISOTimeWithSecondsOmitted()
+ function testCreateByIsoTimeWithSecondsOmitted()
{
$date = new lmbDate('12:45');
$this->assertEqual(lmbDate :: create('12:45'), $date);
@@ -189,10 +195,10 @@
$this->assertEqual($date->toString(), '0000-00-00 12:45:00');
}
- function testStampToISO()
+ function testStampToIso()
{
$stamp = mktime(21, 45, 13, 12, 1, 2005);
- $iso = lmbDate :: stampToISO($stamp);
+ $iso = lmbDate :: stampToIso($stamp);
$this->assertEqual($iso, '2005-12-01 21:45:13');
}
@@ -211,26 +217,87 @@
$this->assertEqual($date->toString(), '2005-12-01 21:45:13');
}
+ function testCreateByDays()
+ {
+ $date = new lmbDate('2005-12-01');
+ $days = $date->getDateDays();
+ $this->assertEqual(lmbDate :: createByDays($days), $date);
+ }
+
function testGetStamp()
{
$date = new lmbDate($stamp = mktime(21, 45, 13, 12, 1, 2005));
$this->assertEqual($date->getStamp(), $stamp);
}
+ function testGetDayOfWeekForSunday()
+ {
+ $date = new lmbDate('2005-01-16');
+ $this->assertEqual($date->getDayOfWeek(), 0);
+ }
+
+ function testGetDayOfWeekForMonday()
+ {
+ $date = new lmbDate('2005-01-17');
+ $this->assertEqual($date->getDayOfWeek(), 1);
+ }
+
+ function testGetDayOfWeekForSuturday()
+ {
+ $date = new lmbDate('2005-01-15');
+ $this->assertEqual($date->getDayOfWeek(), 6);
+ }
+
//in the two tests below we're testing a boundary situtation
//for day of the week which happens in February
function testGetDayOfWeekMonthBeforeFebruary()
{
- $date = new lmbDate('2005-01-20 10:20:30');
- $this->assertEqual($date->getDayOfWeek(), 3);
+ $date = new lmbDate('2005-01-20');
+ $this->assertEqual($date->getDayOfWeek(), 4);
}
function testGetDayOfWeekMonthAfterFebruary()
{
- $date = new lmbDate('2005-08-20 10:20:30');
- $this->assertEqual($date->getDayOfWeek(), 5);
+ $date = new lmbDate('2005-08-20');
+ $this->assertEqual($date->getDayOfWeek(), 6);
}
+ function testGetBeginOfWeek()
+ {
+ $date = new lmbDate('2005-01-20');
+ $this->assertEqual($date->getBeginOfWeek(), new lmbDate('2005-01-17'));
+ }
+
+ function testGetBeginOfWeekForMonday()
+ {
+ $date = new lmbDate('2005-01-17');
+ $this->assertEqual($date->getBeginOfWeek(), new lmbDate('2005-01-17'));
+ }
+
+ function testGetBeginOfWeekForSunday()
+ {
+ $date = new lmbDate('2005-01-16');
+ $this->assertEqual($date->getBeginOfWeek(), new lmbDate('2005-01-10'));
+ }
+
+ function testGetEndOfWeek()
+ {
+ $date = new lmbDate('2005-01-20');
+ $this->assertEqual($date->getEndOfWeek(), new lmbDate('2005-01-23'));
+ }
+
+ function testGetEndOfWeekForMonday()
+ {
+ $date = new lmbDate('2005-01-17');
+ $this->assertEqual($date->getEndOfWeek(), new lmbDate('2005-01-23'));
+ }
+
+ function testGetEndOfWeekForSunday()
+ {
+ $date = new lmbDate('2005-01-16');
+ $this->assertEqual($date->getEndOfWeek(), new lmbDate('2005-01-16'));
+ }
+
function testSetYear()
{
$date = new lmbDate('2005-01-01');
@@ -441,9 +508,8 @@
function testGetWeekOfYear()
{
- //this one fails
- //$date = new lmbDate('2005-01-01 12:20:40');
- //$this->assertEqual($date->getWeekOfYear(), 1);
+ $date = new lmbDate('2005-01-01 12:20:40');
+ $this->assertEqual($date->getWeekOfYear(), 1);
$date = new lmbDate('2005-01-06 12:20:40');
$this->assertEqual($date->getWeekOfYear(), 1);
Modified: 3.x/trunk/limb/datetime/tests/cases/lmbMonthCalendarTest.class.php
===================================================================
--- 3.x/trunk/limb/datetime/tests/cases/lmbMonthCalendarTest.class.php 2007-05-08 11:45:14 UTC (rev 5831)
+++ 3.x/trunk/limb/datetime/tests/cases/lmbMonthCalendarTest.class.php 2007-05-08 12:32:32 UTC (rev 5832)
@@ -19,32 +19,143 @@
$this->assertEqual(new lmbDate('2007-05-01'), $c->getStartDate());
$this->assertEqual(new lmbDate('2007-05-31'), $c->getEndDate());
}
-
+
function testGetNumberOfDays()
- {
+ {
$c = new lmbMonthCalendar(2007, 5);
- $this->assertEqual($c->getNumberOfDays(), 31);
+ $this->assertEqual($c->getNumberOfDays(), 31);
}
-
+
function testGetNumberOfDaysForLeapYear()
{
$c1 = new lmbMonthCalendar(2005, 2);
$this->assertEqual($c1->getNumberOfDays(), 28);
-
+
$c2 = new lmbMonthCalendar(2004, 2);
- $this->assertEqual($c2->getNumberOfDays(), 29);
+ $this->assertEqual($c2->getNumberOfDays(), 29);
}
-
+
function testGetNumberOfWeeks()
{
$c1 = new lmbMonthCalendar(1999, 2);
$this->assertEqual($c1->getNumberOfWeeks(), 4);
-
+
$c2 = new lmbMonthCalendar(2007, 2);
$this->assertEqual($c2->getNumberOfWeeks(), 5);
-
+
$c3 = new lmbMonthCalendar(2010, 5);
- $this->assertEqual($c3->getNumberOfWeeks(), 6);
- }
+ $this->assertEqual($c3->getNumberOfWeeks(), 6);
+ }
+
+ function testGetWeekFailed()
+ {
+ $c = new lmbMonthCalendar(1999, 2);
+ $this->assertNull($c->getWeek(4));
+ $this->assertNull($c->getWeek(10));
+ $this->assertNull($c->getWeek(-1));
+ }
+
+ function testGetIdealWeek()
+ {
+ $c = new lmbMonthCalendar(1999, 2);
+ $week0 = $c->getWeek(0);
+ $week1 = $c->getWeek(1);
+ $week2 = $c->getWeek(2);
+ $week3 = $c->getWeek(3);
+
+ $expected0 = array();
+ $expected1 = array();
+ $expected2 = array();
+ $expected3 = array();
+
+ for($i=0;$i<7;$i++)
+ $expected0[] = new lmbDate(sprintf("1999-02-%02d", $i+1));
+ for($i=7;$i<14;$i++)
+ $expected1[] = new lmbDate(sprintf("1999-02-%02d", $i+1));
+ for($i=14;$i<21;$i++)
+ $expected2[] = new lmbDate(sprintf("1999-02-%02d", $i+1));
+ for($i=21;$i<28;$i++)
+ $expected3[] = new lmbDate(sprintf("1999-02-%02d", $i+1));
+
+ $this->assertEqual($week0, $expected0);
+ $this->assertEqual($week1, $expected1);
+ $this->assertEqual($week2, $expected2);
+ $this->assertEqual($week3, $expected3);
+ }
+
+ function testGetWeekWithDaysFromBoundaryMonths()
+ {
+ $c = new lmbMonthCalendar(2007, 2);
+ $week0 = $c->getWeek(0);
+ $week1 = $c->getWeek(1);
+ $week2 = $c->getWeek(2);
+ $week3 = $c->getWeek(3);
+ $week4 = $c->getWeek(4);
+
+ $expected0 = array();
+ $expected1 = array();
+ $expected2 = array();
+ $expected3 = array();
+ $expected4 = array();
+
+ for($i=29;$i<32;$i++)
+ $expected0[] = new lmbDate(sprintf("2007-01-%02d", $i));
+ for($i=1;$i<5;$i++)
+ $expected0[] = new lmbDate(sprintf("2007-02-%02d", $i));
+
+ for($i=5;$i<12;$i++)
+ $expected1[] = new lmbDate(sprintf("2007-02-%02d", $i));
+ for($i=12;$i<19;$i++)
+ $expected2[] = new lmbDate(sprintf("2007-02-%02d", $i));
+ for($i=19;$i<26;$i++)
+ $expected3[] = new lmbDate(sprintf("2007-02-%02d", $i));
+
+ for($i=26;$i<29;$i++)
+ $expected4[] = new lmbDate(sprintf("2007-02-%02d", $i));
+ for($i=1;$i<5;$i++)
+ $expected4[] = new lmbDate(sprintf("2007-03-%02d", $i));
+
+ $this->assertEqual($week0, $expected0);
+ $this->assertEqual($week1, $expected1);
+ $this->assertEqual($week2, $expected2);
+ $this->assertEqual($week3, $expected3);
+ $this->assertEqual($week4, $expected4);
+ }
+
+ function testGetAllWeeks()
+ {
+ $c = new lmbMonthCalendar(2007, 2);
+ $weeks = $c->getAllWeeks();
+ $this->assertEqual($weeks, array($c->getWeek(0), $c->getWeek(1), $c->getWeek(2),
+ $c->getWeek(3), $c->getWeek(4)));
+ }
+
+ function testGetNextMonth()
+ {
+ $c = new lmbMonthCalendar(2007, 2);
+ $next = $c->getNextMonth();
+ $this->assertEqual(new lmbMonthCalendar(2007, 3), $next);
+ }
+
+ function testGetNextMothFromDecember()
+ {
+ $c = new lmbMonthCalendar(2007, 12);
+ $next = $c->getNextMonth();
+ $this->assertEqual(new lmbMonthCalendar(2008, 1), $next);
+ }
+
+ function testGetPrevMonth()
+ {
+ $c = new lmbMonthCalendar(2007, 2);
+ $prev = $c->getPrevMonth();
+ $this->assertEqual(new lmbMonthCalendar(2007, 1), $prev);
+ }
+
+ function testGetPrevMonthFromJanuary()
+ {
+ $c = new lmbMonthCalendar(2007, 1);
+ $prev = $c->getPrevMonth();
+ $this->assertEqual(new lmbMonthCalendar(2006, 12), $prev);
+ }
}
?>
\ No newline at end of file
More information about the limb-svn
mailing list