예제 #1
0
파일: Calc.php 프로젝트: ulrikkold/cal
 /**
  * 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);
 }