<?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));
?>摘取天上星-測試版
註釋部分爲調試所用,未及時清除請忽略!