| // +----------------------------------------------------------------------+ // // $Id: Week_Magic.php,v 1.1 2005/06/05 12:14:13 nepto Exp $ /** * Date_Week_Magic - ISO 8601 implemetation * * This package implements ISO 8601 specification. It can count week and day * number for specified date. It can also count date of Monday for * specified week in year. * * Usage: * * * @author Ondrej Jombik * @package Date_Week_Magic * @version 0.1 * @access public */ class Date_Week_Magic { /** * Validate date * * Validate passed date. * * @access public * @param int $year year (allowed forms: YYYY, YY) * @param int $month month (from 1 to 12) * @param int $day day (from 1 to 31) * @return bool true if is valid date, false otherwise */ function validate($year, $month, $day) { $timeNowInSeconds = mktime(0, 0, 0, $month, $day, $year); $timeNow = localtime($timeNowInSeconds, 1 /* associative */); if ((($timeNow['tm_year'] >= 100 && $timeNow['tm_year'] - 100 == $year) || ($timeNow['tm_year'] < 100 && $timeNow['tm_year'] == $year) || (1900 + $timeNow['tm_year'] == $year)) && $timeNow['tm_mon'] + 1 == $month && $timeNow['tm_mday'] == $day) { return true; } return false; } /** * Get week information for date * * Method returns associative array with two keys: week and weekday. * Key week contain week number (from 1 to 53) and weekday contain week * day number. First day of week is Monday with value of 1. Sunday * have value 7. 0 is undefined. On error, false is returned. * * @access public * @param int $year year (allowed forms: YYYY, YY) * @param int $month month (from 1 to 12) * @param int $day day (from 1 to 31) * @return array 'week' => week number * 'weekday' => week day (1 - Mon, 7 - Sun) * on error false is returned */ function week($year, $month, $day) { if (Date_Week_Magic::validate($year, $month, $day) == false) { return false; } $timeNow = localtime(mktime(0, 0, 0, $month, $day, $year), 1 /* associative */); // Function localtime() 'tm_yday' 0 based, we need it 1 based. $YearDay_I = $timeNow['tm_yday'] + 1; $yearNow = $timeNow['tm_year']; // American weeks begin on Sundays. ISO doesn't. $WeekDay_I = $timeNow['tm_wday']; if (0 == $WeekDay_I) { // if it's Sunday $WeekDay_I = 7; // make it Sunday } $WeekNo_I = intval($YearDay_I / 7); $FirstWeek_I = $YearDay_I % 7; $FirstWeek_I -= $WeekDay_I; if (($FirstWeek_I <= 0) && ($WeekNo_I > 0)) { // Break up one week and add the days to FirstWeek_I. $WeekNo_I--; $FirstWeek_I += 7; } if ($FirstWeek_I > (-4)) { $WeekNo_I += 1; } if ($FirstWeek_I > 3) { $WeekNo_I += 1; } if ($WeekNo_I == 0) { // Same as previous year's last day. $ar = Date_Week_Magic::week($year - 1, 12 /* December is 12 */, 31); $WeekNo_I = $ar['week']; } else if($WeekNo_I > 52) { // The last days of the year. if($WeekDay_I < 4 && $day > 28) { // Three or less days of this year in 53 makes it week 1 instead! $WeekNo_I = 1; } } return array( 'week' => $WeekNo_I, 'weekday' => $WeekDay_I ); } /** * Get day information for week * * Returns asssociative array with two keys: day and month. It is day and * month of Monday of passed week and year. Note, that the first week can * begin in the previous year. * * @access public * @param int $year year (allowed forms: YYYY, YY) * @param int $week week (from 1 to 53) * @return array 'day' => day of Monday * 'month' => month of Monday * on error false is returned */ function monday($year, $week) { $day = 15; while ($week > 53) { $week -= 53; } $month = intval((11 * $week) / 53); // assume 53 weeks a year while (1) { $ar = Date_Week_Magic::week($year, $month + 1, $day); if ($ar == false) { $month++; $day = 1; continue; } $getweek = $ar['week']; $getday = $ar['weekday']; if (($getweek > $week - 3) && ($getweek < $week + 3)) { if (($getweek == $week) && ($getday == 1)) { break; } else { if ($day == 1 && $month == 0) { return false; } if ($getweek < $week) { if ($week - $getweek > 1) { $day += 7; } else { $day += (8 - $getday); } } else { if ($getweek - $week > 1) { $day -= 7; } else if ($getweek == $week) { $day -= ($getday - 1); } else { $day -= ($getday + 6); } if ($day <= 0) { $day = 28; $month--; } } } } else { if(++$month > 11) { return false; } } } return array( 'day' => $day, 'month' => $month + 1 ); } } ?>