/** * The date object has many getters which allow for you to determine things like day of the week, * day of the year, etc. The following tests those getters. */ public function testGetters() { $date = new qCal_Date(2009, 4, 23); /** * Month */ $this->assertEqual($date->getMonth(), 4); $this->assertEqual($date->getMonthName(), "April"); $this->assertEqual($date->getNumDaysInMonth(), 30); /** * Day */ $this->assertEqual($date->getDay(), 23); $this->assertEqual($date->getYearDay(), 112); $this->assertEqual($date->getFirstDayOfMonth()->__toString(), "04/01/2009"); $this->assertEqual($date->getFirstDayOfMonth()->format("l"), "Wednesday"); $this->assertEqual($date->getLastDayOfMonth()->__toString(), "04/30/2009"); $this->assertEqual($date->getLastDayOfMonth()->format("l"), "Thursday"); // find the xth weekday (mon-sun) of the month $this->assertEqual($date->getXthWeekdayOfMonth(2)->__toString(), "04/09/2009"); // find the second Thursday of the month (Because 4/23/2009 was on a Thursday, the weekday defaults to that. The year defaults to 2009 for basically the same reason) $this->assertEqual($date->getXthWeekdayOfMonth(2, "Monday")->__toString(), "04/13/2009"); // find the second monday of the month (month defaults to april because that's what $date is currently set to) $this->assertEqual($date->getXthWeekdayOfMonth(2, "Monday", "January")->__toString(), "01/12/2009"); // find the second monday in January (year defaults to 2009) $this->assertEqual($date->getXthWeekdayOfMonth(2, "Monday", "January", 2008)->__toString(), "01/14/2008"); // find the second Monday in January, 2008 // now try negatives and positives $this->assertEqual($date->getXthWeekdayOfMonth(-2)->__toString(), "04/23/2009"); // get the second to last Thursday of the month $this->assertEqual($date->getXthWeekdayOfMonth("-2")->__toString(), "04/23/2009"); // get the second to last Thursday of the month $this->assertEqual($date->getXthWeekdayOfMonth(+2)->__toString(), "04/09/2009"); // surprisingly, this works... interesting... $this->assertEqual($date->getXthWeekdayOfMonth("+2")->__toString(), "04/09/2009"); // we can also use numbers instead of spelling out the names of weekdays and months. For the weekday part, use 0 for Sunday through 6 for Saturday (the same as PHP's date function's "w" metacharacter) $this->assertEqual($date->getXthWeekdayOfMonth(2, 1)->__toString(), "04/13/2009"); // second monday $this->assertEqual($date->getXthWeekdayOfMonth(2, 1, 1)->__toString(), "01/12/2009"); // second monday in january $this->assertEqual($date->getXthWeekdayOfMonth(-2, 1)->__toString(), "04/20/2009"); // second to last monday in april /** * Year */ $this->assertEqual($date->getYear(), 2009); /** * Week */ $this->assertEqual($date->getWeekDay(), 4); $this->assertEqual($date->getWeekDayName(), "Thursday"); $this->assertEqual($date->getWeekOfYear(), 17); /** * Unix Timestamp */ $this->assertEqual($date->getUnixTimestamp(), gmmktime(0, 0, 0, 4, 23, 2009)); }
/** * Determine the number or Tuesdays (or whatever day of the week this date is) since the * beginning or end of the year. */ public function getXthWeekdayOfYear($xth, $weekday = null, $year = null) { $negpos = substr($xth, 0, 1); if ($negpos == "+" || $negpos == "-") { $xth = (int) substr($xth, 1); } else { $negpos = "+"; } if (is_null($weekday)) { $weekday = $this->getWeekday(); } if (ctype_digit((string) $weekday)) { if (!array_key_exists($weekday, $this->weekdays)) { throw new qCal_Date_Exception_InvalidWeekday("\"{$weekday}\" is not a valid weekday."); } } else { $weekday = strtolower($weekday); if (!in_array($weekday, $this->weekdays)) { throw new qCal_Date_Exception_InvalidWeekday("\"{$weekday}\" is not a valid weekday."); } $wdays = array_flip($this->weekdays); $weekday = $wdays[$weekday]; } if (is_null($year)) { $year = $this->getYear(); } if (!ctype_digit((string) $year) || strlen($year) != 4) { throw new qCal_Date_Exception_InvalidYear("\"{$year}\" is not a valid year."); } // now find the specified day by counting either forwards or backwards to the day in question $firstofyear = new qCal_Date($year, 1, 1); $numdaysinyear = $firstofyear->isLeapYear() ? 366 : 365; $numweekdays = 0; // the number of weekdays that have occurred within the loop $found = false; // whether or not the specified day has been found if ($negpos == "+") { // count forward // loop over every day of every month looking for the right one $day = 1; $wday = $firstofyear->getWeekDay(); while ($day <= $numdaysinyear) { // if the specified weekday == the current week day in the loop if ($weekday == $wday) { $numweekdays++; if ($numweekdays == $xth) { // break out of the loop, we've found the right day! yay! $found = $day; break; } } if ($wday == 6) { $wday = 0; } else { $wday++; } $day++; } } else { // count backward $lastofyear = new qCal_Date($year, 12, 31); // count forward // loop over every day of every month looking for the right one $day = $numdaysinyear; $wday = $lastofyear->getWeekDay(); while ($day >= 1) { // if the specified weekday == the current week day in the loop if ($weekday == $wday) { $numweekdays++; if ($numweekdays == $xth) { // break out of the loop, we've found the right day! yay! $found = $day; break; } } if ($wday == 0) { $wday = 6; } else { $wday--; } $day--; } } // @todo: Can't use checkdate here, so find another validation method... if ($found) { $date = new qCal_Date($year, 1, $found, true); // takes advantage of the rollover feature :) } else { throw new qCal_DateTime_Exception_InvalidDate("You have specified an incorrect number of days for qCal_Date::getXthWeekdayOfYear()"); } return $date; }