根据指定时间范围取得对应(第几)周信息,以及一年当中所有周时间范围列表信息(可用于学期第几周,年第几周)

  
<?php error_reporting(E_ALL);

/**
 * 日期控件
 * 取得一年中周信息以及学期中周信息,根据指定时间取得周信息
 *
 */
class Week{
	
	private $term_last = 1; //代表上学期 用于可能的学期分表联动
	private $term_next = 2; //代表下学期 用于可能的学期分表联动

	/**
	 * 获取指定年指定周对应的周开始时间(单位秒)
	 *  
	 * @param int $sYear(参数1:年号,字符型或数值型 例:2011)
	 * @param int $sWeekNo(参数2:周号,字符型或数值型 例:4)
	 * @return int (时间戳型日期)
	 */
	public function getWeekNoToFirstDay($sYear,$sWeekNo){
		return strtotime($this->getWeekDay($sYear,$sWeekNo,1));
	}

	/**
	* 获取指定周的第几天的日期
	*
	* @param int $year 年
	* @param int $wek 周
	* @param int $day天
	* @param string $format显示时间的格式
	* @return string $str
	*/
	public function getWeekDay($year,$week,$day,$format='Y-m-d'){

		$time=new DateTime();
		$time->setISODate($year,$week,$day);
		return $time->format($format);

	}

	/**
	 * 功能:获取指定年周对应的日期范围文本
	 *
	 * @param int $sYear (年号,字符型或数值型 例:2011)
	 * @param int $sWeek (周号,字符型或数值型 例:4)
	 * @return array 不带年份的日期范围文字例:['satrt_date'3.2,'end_date'=>3.8])
	 */
	public function getWeekNoToDateRange($sYear,$sWeekNo){

		$dateTemp=$this->getWeekNoToFirstDay($sYear,$sWeekNo);
		$arr = ['start_date'=>date('Y-m-d',$dateTemp),'end_date'=>date('Y-m-d',strtotime("+6 day",$dateTemp))];
		return $arr;

	}

	/** 
	 * 获取指定2个年周之间的周数
	 *
	 * @param  int $from_year (开始年号,字符型或数值型 例:2011)
	 * @param  int $from_week (开始周号,字符型或数值型例:4)
	 * @param  int $end_year (结束年号,字符型或数值型 例:2011)
	 * @param  int $end_week (结束周号,字符型或数值型 例:26)
	 * @return int
	 */
	public function getWeekNoToTotalWeeks($from_year,$from_week,$end_year,$end_week){

		if(!$from_year or !$from_week or !$end_year or !$end_week){
			return -1;
		}

		$time_from_yearweek= $this->getWeekNoToFirstDay($from_year,$from_week);
		$time_end_yearweek = $this->getWeekNoToFirstDay($end_year,$end_week);
		$total_weeks=($time_end_yearweek-$time_from_yearweek)/86400/7;

		if($total_weeks >= 0){
			$total_weeks++;
		}

		return $total_weeks;

	}

	/**
	 * 取得指定日期在年的第几周
	 *
	 * @param  string $date 例: 2017-08-29
	 * @return int
	 */
	public function getWeekForDate($date){
		
		$arr = $this->getWeekYearForDate($date);
		return $arr['week'];

	}

	/**
	 * 取得指定日期在哪一年的哪一周
	 *
	 * @param  string $date 例: 2017-08-29
	 * @return array
	 */
	public function getWeekYearForDate($date){
		
		$int = date('oW',strtotime($date));
		$arr = ['year'=>substr($int,0,4),'week'=>substr($int,4)];
		return $arr;

	}

	/**
	 * 取得指定年的最后一周开始时间
	 *
	 * @param  int   $date 例: 2017
	 * @return array
	 */
	public function getWeekExitDate($year){
		
		$week = $this->getYearWeeks($year);
		return $this->getWeekDay($year,$week,1);
		
	}

	/**
	* 取得指定年份一共有多少周
	*
	* @param int $year
	* @return int;
	*/
	public function getYearWeeks($year){

		$date = new DateTime;
		$date->setISODate($year, 53);
		$weeks = max($date->format("W"),52);
		unset($date);
		return $weeks;

	}

	/**
	 * 取得指定时间范围内的所有周的总列表时间范围信息(可跨年) - 含开始结束时间
	 * 如果开始时间==结束时间,则可取出时间所在学期的第几周以及所在年的第几周以及周开始+结束时间范围
	 *
	 * @param string $start_date 例:2017-09-01
	 * @param string $end_date 例:2018-01-26
	 * @param array array(1=>array(xx,xx,xx));
	 */
	public function getTermWeeks($start_date='2017-09-01',$end_date='2018-01-26'){
		
		$year_start = intval(substr(trim($start_date),0,4));
		$year_end = intval(substr(trim($end_date),0,4));
		$year_start_week_total = $this->getYearWeeks($year_start);		
		$year_end_week_total = $this->getYearWeeks($year_end);	
		//echo "<br/>{$year_start}年共几周:",$year_start_week_total,"|||{$year_end}年共几周:",$year_end_week_total,"<br/>";
		$year_start_date_week = $this->getWeekForDate($start_date); //开始时间属于开始年的第几周
		$year_end_date_week = $this->getWeekForDate($end_date); //结束时间属于结束年的第几周
		//echo "{$year_start}第几周开始:",$year_start_date_week,"||{$year_end}第几周结束",$year_end_date_week;//
		if($year_end>$year_start){
			$year_start_arr = $this->getYearWeeksList($year_start); //开始时间所在年的所有周的时间范围列表
			$year_end_arr = $this->getYearWeeksList($year_end); //结束时间所在年的所有周的时间范围列表
			//echo "{$year_start}年所有周:";
			//var_dump($year_start_arr);
			//echo "{$year_end}年所有周:";
			//var_dump($year_end_arr);
			$year_start_have_weeks_count = intval($year_start_date_week)-1; //取得开始周在数组中的第几项 	
			$year_end_have_weeks_count = intval($year_end_date_week);//取得结束时间所在周在一年的第几周			
			//截取开始时间到年末的所有周的时间范围列表		
			$year_start_weeks = array_slice($year_start_arr,$year_start_have_weeks_count,$year_start_week_total,true);
			$year_end_weeks = array_slice($year_end_arr,0,$year_end_have_weeks_count,true);
			$arr = [];
			$i = 0;
			foreach($year_start_weeks as $k=>$v){
				$i++;	//year所在年,year_week_num所在年的第几周,term_week_num所在时间范围内的第几周,dates当前周时间范围			
				$arr[$i] = ['year'=>$year_start,'term'=>$this->term_last,'year_week_num'=>$k,'term_week_num'=>$i,'dates'=>$v];			
			}
			foreach($year_end_weeks as $k=>$v){
				$i++;
				$arr[$i] = ['year'=>$year_end,'term'=>$this->term_last,'year_week_num'=>$k,'term_week_num'=>$i,'dates'=>$v];		
			}
			//return $arr;
		}else{
			$year_start_arr = $year_end_arr = $this->getYearWeeksList($year_start);
			$year_start_have_weeks_count = intval($year_start_date_week)-1; //取得开始周在数组中的第几项 	
			$year_end_have_weeks_count = intval($year_end_date_week);//-1;//取得结束时间所在周在一年的第几周
			$total_week = $year_end_have_weeks_count - $year_start_have_weeks_count;
			$year_start_end_weeks = array_slice($year_start_arr,$year_start_have_weeks_count,$total_week,true);
			$arr = [];
			$i = 0;
			foreach($year_start_end_weeks as $k=>$v){
				$i++;	//year所在年,year_week_num所在年的第几周,term_week_num所在时间范围内的第几周,dates当前周时间范围			
				$arr[$i] = ['year'=>$year_start,'term'=>$this->term_next,'year_week_num'=>$k,'term_week_num'=>$i,'dates'=>$v];			
			}
			//echo "{$year_start}年所有周:";
			//var_dump($year_start_arr);
			//return $arr;
		}
		$year_start_weeks = $year_end_arr = $year_start_weeks = $year_end_weeks = NULL;		
		if($start_date==$end_date && !empty($start_date) && !empty($arr)){
			$new_arr = [];
			foreach($arr as $v){
				$new_arr = $v;			
			}		
			return $new_arr;
		}

		return $arr;

	}
	/**
	 * 取得(指定)一年当中所有周的时间范围(Key值为一年当中第几周,Value为周的日期范围)
	 *
	 * @param int $year
	 * @return array
	 */
	public function getYearWeeksList($year=''){
		
		if(empty($year)) $year = date('Y',time());
		$week_total = $this->getYearWeeks($year);
		$year_arr = [];
		for($i=1;$i<=$week_total;$i++){
			$year_arr[$i] = $this->getWeekNoToDateRange($year,$i);
		}
		return $year_arr;
		
	}

	/**
	 * 取得指定日期在当前学期/指定时间范围的第几周
	 *
	 * @param string $term_start_date (start Y-m-d)
	 * @param string $term_end_date (end Y-m-d)
	 * @param string $_date (this Y-m-d)
	 * @param return int
	 */
	public function getDateWeekForTerm($term_start_date,$term_end_date,$_date=''){	

		$week = $this->getDateWeekInfoForTerm($term_start_date,$term_end_date,$_date);
		if(isset($week['term_week_num']))return intval($week['term_week_num']);
		return 0;

	}
	/**
	 * 取得指定日期在当前学期第几周+年第几周+周开始结束日期范围
	 *
	 * @param string $term_start_date (start Y-m-d)
	 * @param string $term_end_date (end Y-m-d)
	 * @param string $_date (this Y-m-d)
	 * @param return array
	 */
	public function getDateWeekInfoForTerm($term_start_date,$term_end_date,$_date=''){

		$_date = trim($_date);
		$week_num=0;
		if(empty($_date)) $_date = date('Y-m-d',time());
		$arr = $this->getTermWeeks($term_start_date,$term_end_date);
		$tmp_date = str_replace('-','',$_date);
		foreach($arr as $v){
			if(isset($v['dates']['start_date']) && isset($v['dates']['end_date'])){
				$start = str_replace('-','',$v['dates']['start_date']);
				$end   = str_replace('-','',$v['dates']['end_date']);
				if(($tmp_date>=$start) && ($tmp_date<=$end)){
					$week = $v;
					break;
				}
							
			}
		}
		
		unset($arr);
		return $week;	

	}
	/**
     * 取得指定日期与学期对应的所在年的第几周该方法与getWeekForDate方法功能重复,仅仅在调试状态使用该方法用以验证学期推算功能的正确性,如果两个方法结果一致则正确无误
     *
     * @param string $_date
     * @return int
     */
	public function getDateWeekForYear($_date=''){
		if(empty($_date)) $_date = date('Y-m-d',time());
		$arr = $this->getTermWeeks($_date,$_date);
		if(isset($arr['year_week_num'])) return $arr['year_week_num'];	
	}

}


echo "<hr/>";

$W = new Week();
/*
echo "指定(学期)日期所在一年当中的第几周:";
$term_week = $W->getWeekForDate('2017-09-01');
echo $term_week;
echo "<br/>2017年最后一周开始时间:";
$last_week = $W->getWeekExitDate(2017);
echo $last_week;
echo "<br/>取得当前2014-12-29时间在一年当中的第几周:";
$the_date = date('Y-m-d',strtotime('2014-12-29'));
$the_week = $W->getWeekForDate($the_date);
echo $the_week;
echo "<br/>取得当前".date('Y-m-d',time())."时间在一年当中的第几周:";
$the_date = date('Y-m-d',time());
$the_week = $W->getWeekForDate($the_date);
echo $the_week;
echo "<br/>取得当前时间在本学期的第几周:";
echo intval($the_week - $term_week);
echo "<br/>取得元旦(2017-01-01)在新年的第几周:";
$yd_week = $W->getWeekForDate('2017-01-01'); 
echo $yd_week;
echo "<br/>取得2020年第一周开始时间:";
$_t = $W->getWeekNoToFirstDay(2020,1);
echo date('Y-m-d',$_t);
echo "<br/>取得指定周对应的日期范围";
$_fw = $W->getWeekNoToDateRange(2017,3);
var_dump($_fw);
echo "<hr/>";

//按给定的年份计算本年周总数
echo "<hr/><br/><hr/>一年中所有周开始结束时间:<br/>";
$total_week = $W->getYearWeeks(2017);
$arr = [];
for($i=1;$i<=$total_week;$i++){
	$arr[$i] = $W->getWeekNoToDateRange(2017,$i);
}
echo "<pre>";
echo $total_week;
var_dump($arr);
echo "2017-09-01在2017年那一周:";
$week91 = $W->getWeekForDate('2017-09-01');
echo $week91;
echo "<br/>2018-01-26在2018年那一周:";
$week201831 = $W->getWeekForDate('2018-01-26');
echo $week201831;
$_date = '2017-12-31';
echo "<br/>{$_date}在(20171)新学期的第几周:";
echo $W->getWeekForDate($_date)-$week91+1;
echo "<br/>取得2017-09-01到2018-01-26一共多少周:";
echo $W->getWeekNoToTotalWeeks(2017,35,2018,4);
$total_week = $W->getYearWeeks(2018);
$arr2=[];
for($i=1;$i<=$total_week;$i++){
	$arr2[$i] = $W->getWeekNoToDateRange(2017,$i);
}
$week2017 = array_slice($arr,34,53,true);
var_dump($week2017);
$last_count = count($week2017);
for($i=1;$i<=4;$i++){
	$week2017[$i] = $arr2[$i];
}
var_dump($week2017);
*/
echo "<pre>";
echo "<hr/>2017-09-01~2018-01-26 20171学期:";
$week20171 = $W->getTermWeeks('2017-02-01','2017-08-31');
var_dump($week20171);
var_dump($week20171[30]);
var_dump($W->getWeekForDate('2017-02-01'));
var_dump($W->getTermWeeks('2017-02-01','2017-02-01'));
echo $W->getWeekNoToTotalWeeks(2017,5,2017,34);
$tmp_date ='2017-08-01';
echo "<br/>{$tmp_date}在年的第几周:";
echo $W->getDateWeekForYear($tmp_date),"||",$W->getWeekForDate($tmp_date);
echo "<br/>{$tmp_date}在学期第几周:",$W->getDateWeekForTerm('2017-02-01','2017-08-31',$tmp_date);
var_dump($W->getDateWeekInfoForTerm('2017-02-01','2017-08-31',$tmp_date));
?>摘取天上星-测试版
注释部分为调试所用,未及时清除请忽略!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值