/** * Returns array defining the 'ISO Week Date' as defined in ISO 8601 * * Expects a date in the proleptic Gregorian calendar using 'Astronomical' * year numbering, that is, with a year 0. Algorithm is valid for all * years (positive and negative). * * N.B. the ISO week day no for Sunday is defined as 7, whereas this * class and its related functions defines Sunday as 0. * * @param int $pn_day * the day of the month * @param int $pn_month * the month * @param int $pn_year * the year * * @return array array of ISO Year, ISO Week No, ISO Day No as * integers * @access public * @static * * @since Method available since Release 1.5.0 */ static function isoWeekDate($pn_day = 0, $pn_month = 0, $pn_year = null) { if (is_null($pn_year)) { $pn_year = Calc::dateNow('%Y'); } if (empty($pn_month)) { $pn_month = Calc::dateNow('%m'); } if (empty($pn_day)) { $pn_day = Calc::dateNow('%d'); } $hn_jd = Calc::dateToDays($pn_day, $pn_month, $pn_year); $hn_wd = Calc::daysToDayOfWeek($hn_jd); if ($hn_wd == 0) { $hn_wd = 7; } $hn_jd1 = Calc::firstDayOfYear($pn_year); $hn_day = $hn_jd - $hn_jd1 + 1; if ($hn_wd <= $hn_jd - Calc::lastDayOfYear($pn_year) + 3) { // ISO week is the first week of the next ISO year: // $hn_year = $pn_year + 1; $hn_isoweek = 1; } else { switch ($hn_wd1 = Calc::daysToDayOfWeek($hn_jd1)) { case 1: case 2: case 3: case 4: // Monday - Thursday: // $hn_year = $pn_year; $hn_isoweek = floor(($hn_day + $hn_wd1 - 2) / 7) + 1; break; case 0: $hn_wd1 = 7; case 5: case 6: // Friday - Sunday: // if ($hn_day <= 8 - $hn_wd1) { // ISO week is the last week of the previous ISO year: // list($hn_year, $hn_lastmonth, $hn_lastday) = explode(" ", Calc::daysToDate($hn_jd1 - 1, "%Y %m %d")); list($hn_year, $hn_isoweek, $hn_pisoday) = Calc::isoWeekDate($hn_lastday, $hn_lastmonth, $hn_year); } else { $hn_year = $pn_year; $hn_isoweek = floor(($hn_day + $hn_wd1 - 9) / 7) + 1; } break; } } return array((int) $hn_year, (int) $hn_isoweek, (int) $hn_wd); }