/** * Determine the number or Tuesdays (or whatever day of the week this date is) since the * beginning or end of the month. * @param integer $xth A positive or negative number that determines which weekday of the month we want * @param string|integer $weekday Either Sunday-Saturday or 0-6 to specify the weekday we want * @param string|integer $month Either January-December or 1-12 to specify the month we want * @param integer $year A valid year to specify which year we want */ public function getXthWeekdayOfMonth($xth, $weekday = null, $month = 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($month)) { $month = $this->getMonth(); } if (ctype_digit((string) $month)) { if (!array_key_exists($month, $this->months)) { throw new qCal_Date_Exception_InvalidMonth("\"{$month}\" is not a valid month."); } } else { $month = strtolower($month); if (!in_array($month, $this->months)) { throw new qCal_Date_Exception_InvalidMonth("\"{$month}\" is not a valid month."); } $mons = array_flip($this->months); $month = $mons[$month]; } 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, using the year, month and numbered weekday, we need to find the actual day of the month... $firstofmonth = new qCal_Date($year, $month, 1); $numdaysinmonth = $firstofmonth->getNumDaysInMonth(); $numweekdays = 0; // the number of weekdays that have occurred (in the loop) $foundday = false; if ($negpos == "+") { $day = 1; $wday = $firstofmonth->getWeekday(); // while we are in the current month, loop while ($day <= $numdaysinmonth) { // 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! $foundday = $day; break; } } if ($wday == 6) { $wday = 0; } else { $wday++; } $day++; } } else { $day = $numdaysinmonth; $lastofmonth = $firstofmonth->getLastDayOfMonth(); $wday = $lastofmonth->getWeekday(); while ($day >= 1) { if ($weekday == $wday) { $numweekdays++; if ($numweekdays == $xth) { // break out of the loop, we've found the right day! yay! $foundday = $day; break; } } if ($wday == 0) { $wday = 6; } else { $wday--; } $day--; } } if ($foundday && checkdate($month, $day, $year)) { $date = new qCal_Date($year, $month, $day); } else { if ($day == 32) { throw new qCal_DateTime_Exception_InvalidDate("You have specified an incorrect number of days for qCal_Date::getXthWeekdayOfMonth()"); } else { throw new qCal_DateTime_Exception_InvalidDate("You have entered an invalid date."); } } return $date; }
/** * 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)); }
public function testGetFirstAndLastDayOfMonth() { $date = new qCal_Date(2010, 1, 10); $first = $date->getFirstDayOfMonth(); // will return a qCal_Date object for January 1st, 2010 $this->assertEqual($first->__toString(), "01/01/2010"); $date = new qCal_Date(2010, 1, 10); $last = $date->getLastDayOfMonth(); // will return a qCal_Date object for January 31st, 2010 $this->assertEqual($last->__toString(), "01/31/2010"); }