時間處理函數總結

時間處理函數總結

/**
 * 獲得當前格林威治時間的時間戳
 * @return  integer
 */
function gmtime(){
	return (time());
}
/**
 * 將GMT時間戳格式化爲用戶自定義時區日期
 * @param  string  $format
 * @param  integer $time 該參數必須是一個GMT的時間戳
 *
 * @return  string
 */
function local_date($format='Y-m-d H:i:s', $time = NULL){
	//$timezone = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : $GLOBALS['_CFG']['timezone'];
	if ($time === NULL) {
		$time = gmtime();
	} elseif ($time <= 0) {
		return '';
	}
	//$time += ($timezone * 3600);
	return date($format, $time);
}   
/**
 * 格式化時間戳
 * @param        $timestamp
 * @return string
 */
function time_format($timestamp) {
	return local_date('Y-m-d H:i:s', $timestamp);
}       
/**
 *  將一個用戶自定義時區的日期轉爲GMT時間戳
 * @access  public
 * @param   string $str
 * @return  integer
 */
function local_strtotime($str){
	//$timezone = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : $GLOBALS['_CFG']['timezone'];

	/**
	 * $time = mktime($hour, $minute, $second, $month, $day, $year) - date('Z') + (date('Z') - $timezone * 3600)
	 * 先用mktime生成時間戳,再減去date('Z')轉換爲GMT時間,然後修正爲用戶自定義時間。以下是化簡後結果
	 **/
	$time = strtotime($str);// - $timezone * 3600;
	return $time;

}    
/**
 * 根據時間戳獲取當天開始的時間戳
 * @param $time
 * @return int
 */
function get_day_start($time){
	if (empty($time))return 0;
	return local_strtotime(time_day_of_start($time));
}         
/**
 * 根據時間戳獲取當天結束的時間戳
 * @param $time
 * @return int
 */
function get_day_end($time){
	if (empty($time))return 0;
	return local_strtotime(time_day_of_end($time));
}
/**
 * 根據時間戳獲取當週開始的時間戳
 * @param $time
 * @param $weekStartIndex 指定一週的開始, 0週日 1週一
 * @return int|mixed
 */
function get_week_start($time, $weekStartIndex=1) {
	if (empty($time)) {
		return 0;
	}
	$range = week_range(time_day_of_start($time), $weekStartIndex);
	return local_strtotime($range[0]);
}

/**
 * 根據時間戳獲取當週結束的時間戳
 * @param $time
 * @param $weekStartIndex 指定一週的開始, 0週日 1週一
 * @return int|mixed
 */
function get_week_end($time, $weekStartIndex=1) {
	if (empty($time)) {
		return 0;
	}
	$range = week_range(time_day_of_start($time), $weekStartIndex);
	return local_strtotime($range[1]. "23:59:59");
}
/**
 * 字符串轉時間戳,時間戳直接返回, 錯誤格式返回0
 * @param $t
 * @return mixed
 */
function to_timestamp($t){
	if (is_numeric($t) && $t > 0) {
		return $t;
	}
	return local_strtotime($t);
}

/**
 * 根據時間戳獲取當月第一天(日期)
 * @param  [type] $time 時間參數,時間戳
 * @return [type] 字符串形式的日期,如2011-01-01
 */
function get_month_first_day_s($time){
	if (empty($time))$time = time();
	//獲取第一天
	$firstday = date("Y-m-01", $time);
	return $firstday;
}

/**
 * 根據時間戳獲取當月第一天(時間戳)
 * @param  [type] $time 某天的時間戳
 * @return [type]       時間戳
 */
function get_month_first_day($time){
	return local_strtotime(time_month_of_first($time));
}
/**
 * 根據時間戳獲取當月最後一天(日期)
 * @param  [type] $time 時間參數
 * @return [type] 字符串形式的日期,如2011-01-01
 */
function get_month_last_day_s($time){
	$firstday = time_month_of_first($time);
	//獲取最後一天
	$lastday = date("Y-m-d", strtotime("$firstday +1 month -1 day"));
	return $lastday;
}
/**
 * 根據時間戳獲取當月最後一天(時間戳)
 * @param  [type] $time 某天的時間戳
 * @return [type]       時間戳
 */
function get_month_last_day($time){
	return local_strtotime(time_month_of_last($time));
}
/**
 * 根據yyyy-MM-dd格式獲取時間戳
 * @return [type] 錯誤返回0
 */
function get_time_by_date_string($time){
	if ($time){
		return local_strtotime($time);
	}else{
		return 0;
	}
}
/**
 * 根據yyyy-MM-dd獲取時間戳並將時間調整到當天德最後一秒,即yyyy-MM-dd 23:59:59的時間戳
 * 錯誤返回0
 */
function get_time_day_end_by_date_string($time){
	if ($time) {
		return local_strtotime(substr($time, 0, 10) . " 23:59:59");//結束時間到當天最後一秒
	} else {
		return 0;
	}
}
/**
 * 根據不同的時間間隔類型,獲取開始時間
 * @param  [type] $time [description]
 * @param  [type] $type 1.一天的開始 2 3 一個月的開始 4 季度的開始 5 年的開始
 * @return [type]       [description]
 */
function time_split_start_time_by_type($time, $type){
	if ($type == 1) {
		return local_strtotime(time_day_of_start($time));
	} elseif ($type == 2) {
	} elseif ($type == 3) {
		return local_strtotime(time_month_of_first($time));
	} elseif ($type == 4) {
		return local_strtotime(time_quarter_of_first($time));
	} elseif ($type == 5) {
		return local_strtotime(time_year_of_first($time));
	}
}
/**
 * 根據不同的時間間隔類型,獲取結束時間
 * @param  [type] $time [description]
 * @param  [type] $type 一天的結束 2 3 一個月的結束 4 季度的結束 5 年的結束
 * @return [type]       [description]
 */
function time_split_end_time_by_type($time, $type){
	if ($type == 1) {
		return local_strtotime(time_day_of_end($time));
	} elseif ($type == 2) {
	} elseif ($type == 3) {
		return local_strtotime(time_month_of_last($time));
	} elseif ($type == 4) {
		return local_strtotime(time_quarter_of_last($time));
	} elseif ($type == 5) {
		return local_strtotime(time_year_of_last($time));
	}
}

/**
 * 根據start_time和end_time生成時間間隔數組
 * 時間間隔,天,周,月,季度,年(分別使用1,2,3,4,5表示)
 * 程序自動計算start_time到end_time中間根據時間隔產生不同的數組
 * 如2019-01-01 ~ 2019-01-03,按照天當做時間間隔,將得到結果
 * array( array(2019-01-01 00:00:00,2019-01-01 23:59:59),
 *        array(2019-01-02 00:00:00,2019-01-02 23:59:59),
 *        array(2019-01-03 00:00:00,2019-01-03 23:59:59))
 * 每一天開始時間和結束時間放到一個數組的[0,1]元素位裏
 * 注意得到的結果是時間戳而不是字符串形式的日期
 *
 * 周統計功能未實現
 *
 * @param  [type] $start 開始時間
 * @param  [type] $end   結束時間
 * @param  [type] $type  時間間隔類型1天,2周,3月,4季度,5年
 *
 * @return [type]        時間間隔數組
 *
 */
function time_split($start, $end, $type){
	if ($type == 2){
		return;
	}
	//獲取日開始時間
	$day_start = $start;//local_strtotime(time_day_of_start($start));
	//獲取日結束時間
	$day_end = time_split_end_time_by_type($start, $type);//local_strtotime(time_day_of_end($start));
	$day_arr = array();
	while (true) {
		if ($day_end >= $end) {
			//如果日結束時間小於end,結束 add array(day_start,end)
			$day_arr[] = array($day_start, $end);
			break;
		} else {
			//否則add array(day_start,day_end)
			$day_arr[] = array($day_start, $day_end);
			$day_end++;
			$day_start = time_split_start_time_by_type($day_end, $type);//local_strtotime(time_day_of_start($day_end));
			$day_end = time_split_end_time_by_type($day_end, $type);//local_strtotime(time_day_of_end($day_end));
		}
	}
	return $day_arr;
}

/**
 * 根據start_time和end_time生成時間間隔數組
 * 時間間隔,天,周,月,季度,年(分別使用1,2,3,4,5表示)
 * 程序自動計算start_time到end_time中間根據時間隔產生不同的數組
 * 如2019-01-01 ~ 2019-01-03,按照天當做時間間隔,將得到結果
 * array( array(2019-01-01 00:00:00,2019-01-01 23:59:59),
 *        array(2019-01-02 00:00:00,2019-01-02 23:59:59),
 *        array(2019-01-03 00:00:00,2019-01-03 23:59:59))
 * 每一天開始時間和結束時間放到一個數組的[0,1]元素位裏
 * 注意得到的結果是字符串形式的日期
 *
 * 周統計功能未實現
 *
 * @param  [string] $start 開始時間
 * @param  [string] $end   結束時間
 * @param  [int] $type  時間間隔類型1天,2周,3月,4季度,5年
 * @return [type]        時間間隔數組
 *
 */
function time_split_s2s($start, $end, $type,$format=null){
	// 分別是天,月,季度,年   //周未實現
	$typearr = array(1,3,4,5);
	if (!in_array($type, $typearr)) {
		return;
	}
	$arr = time_split(local_strtotime($start), local_strtotime($end), $type);
	$format = "Y-m-d H:i:s";
    if($format){
        $format = "Y-m-d";
    }
	foreach ($arr as $k=>$v) {
		$val = array();
		$val[] = local_date($format, $v[0]);
		$val[] = local_date($format, $v[1]);
		$arr[$k] = $val;
	}
	return $arr;
}
/**
 * 按天分割時間
 * @param  $start int
 * @param  $end int
 * @return [type] [description]
 */
function time_split_day($start, $end){
	// echo "start:". local_date('Y-m-d H:i:s', $start);
	// echo ", end:". local_date('Y-m-d H:i:s', $end);
	//獲取日開始時間
	$day_start = $start;//local_strtotime(time_day_of_start($start));
	//獲取日結束時間
	$day_end = local_strtotime(time_day_of_end($start));
	$day_arr = array();
	while (true) {
		if ($day_end >= $end) {
			//如果日結束時間小於end,結束 add array(day_start,end)
			$day_arr[] = array($day_start, $end);
			break;
		} else {
			//否則add array(day_start,day_end)
			$day_arr[] = array($day_start, $day_end);
			$day_end++;
			$day_start = local_strtotime(time_day_of_start($day_end));
			$day_end = local_strtotime(time_day_of_end($day_end));
		}
	}
	return $day_arr;
}

/**
 * 按月分割時間
 * @param  $start int
 * @param  $end int
 * @return [type]        [description]
 */
function time_split_month($start, $end){
	//獲取日開始時間
	$day_start = $start;//local_strtotime(time_month_of_first($start));
	//獲取日結束時間
	$day_end = local_strtotime(time_month_of_last($start));
	$day_arr = array();
	while (true) {
		if ($day_end >= $end) {
			//如果日結束時間小於end,結束 add array(day_start,end)
			$day_arr[] = array($day_start, $end);
			break;
		} else {
			//否則add array(day_start,day_end)
			$day_arr[] = array($day_start, $day_end);
			$day_end++;
			$day_start = local_strtotime(time_month_of_first($day_end));
			$day_end = local_strtotime(time_month_of_last($day_end));
		}
	}
	return $day_arr;
}
/**
 * 獲取年月組合
 * months_of_year("2017-11", "2018-01") => ['2017-11', '2017-12', '2018-01']
 * @param $start string 開始年月份 格式 Y-m
 * @param $end string 結束年月份 格式 Y-m
 */
function months_of_year($start, $end){
    $starts = explode("-", $start);
    $ends = explode("-", $end);
    $data = [];
    for ($i=intval($starts[0]); $i<=$ends[0]; $i++) {
        if ($i == $starts[0]) {
            $j = intval($starts[1]);
        } else {
            $j = 1;
        }
        for (; $j<=12; $j++) {
            if ($j > intval($ends[1]) && $i == intval($ends[0])) {
                break;
            }
            $data[] = $i . "-" . ($j>9? $j: "0" . $j);
        }
    }
    return $data;
}
/**
 * 每天的開始
 * @return [type] [description]
 */
function time_day_of_start($timestamp){
	return local_date('Y-m-d 00:00:00', $timestamp);
}

/**
 * 每天的結束
 * @return [type] [description]
 */
function time_day_of_end($timestamp){
	return local_date('Y-m-d 23:59:59', $timestamp);
}
/**
 * 取當月的第一天
 * @return [type] [description]
 */
function time_month_of_first($timestamp){
	return local_date('Y-m-01', $timestamp);
}
/**
 * 當月的最後一天
 *
 * @param  [type] $timestamp [description]
 *
 * @return [type]            [description]
 */
function time_month_of_last($timestamp){
	$firstday = time_month_of_first($timestamp);
	//獲取最後一天
	$lastday = local_date("Y-m-d", strtotime("$firstday +1 month -1 day"));
	return $lastday . " 23:59:59";
}
/**
 * 獲取季度的第一天
 * @param  [type] $timestamp [description]
 * @return [type]            [description]
 */
function time_quarter_of_first($timestamp){
	$year = local_date('Y', $timestamp);
	$month = local_date('m', $timestamp);
	$strart = intval(($month + 2) / 3); //獲取當月位於第幾季度
	$q = intval((($month + 2) / 3));
	$m = ($q - 1) * 3 + 1;
	$m = $m > 9 ? $m : "0$m";
	return $year . "-$m-01";
}
/**
 * 獲取季度的最後一天
 * @param  [type] $timestamp [description]
 * @return [type]            [description]
 */
function time_quarter_of_last($timestamp){
	$firstday = time_quarter_of_first($timestamp);
	//獲取最後一天
	$lastday = local_date("Y-m-d", strtotime("$firstday +3 month -1 day"));
	return $lastday . " 23:59:59";
}
/**
 * 獲取年的第一天
 * @param  [type] $timestamp [description]
 * @return [type]            [description]
 */
function time_year_of_first($timestamp){
	return local_date('Y-01-01', $timestamp);
}
/**
 * 獲取年的最後一天
 * @param  [type] $timestamp [description]
 * @return [type]            [description]
 */
function time_year_of_last($timestamp){
	$firstday = time_year_of_first($timestamp);
	//獲取最後一天
	$lastday = local_date("Y-m-d", strtotime("$firstday +1 year -1 day"));
	return $lastday . " 23:59:59";
}
/**
 * 日期添加天數,返回字符串日期, 如: 2016-05-05
 * @param $date 日期字符串(如2016-05-05)
 * @param $days 天數,可爲負數
 */
function date_add_days($date, $days){
	$date = date("Y-m-d", strtotime("$date $days day"));
	return $date;
}
/**
 * 計算指定日期的一週開始及結束日期
 * @param  DateTime $date  日期字符串
 * @param  Int      $start 周幾作爲一週的開始 1-6爲週一~週六,0爲週日,默認0
 * @retrun Array array(week_start, week_end)
 */
function week_range($date, $start=0) {
	// 將日期轉時間戳
	$dt = new DateTime($date);
	$timestamp = $dt->format('U');

	// 獲取日期是周幾
	$day = (new DateTime('@'.$timestamp))->format('w');

	// 計算開始日期
	if($day>=$start){
		$startdate_timestamp = mktime(0,0,0,date('m',$timestamp),date('d',$timestamp)-($day-$start),date('Y',$timestamp));
	}elseif($day<$start){
		$startdate_timestamp = mktime(0,0,0,date('m',$timestamp),date('d',$timestamp)-7+$start-$day,date('Y',$timestamp));
	}

	// 結束日期=開始日期+6
	$enddate_timestamp = mktime(0,0,0,date('m',$startdate_timestamp),date('d',$startdate_timestamp)+6,date('Y',$startdate_timestamp));

	$startdate = (new DateTime('@'.$startdate_timestamp))->format('Y-m-d');
	$enddate = (new DateTime('@'.$enddate_timestamp))->format('Y-m-d');

	return array($startdate, $enddate);
}

/**
 * 比較2個日期段,獲取時間重合部分的天數
 * todo 未實現
 * 或許使用時間段更好,但現在沒有這個需求,因此參數就定義爲日期
 * example:
 * day_by_2time_period('2011-01-01','2011-01-02','2011-01-02','2011-01-03')  => 1
 * day_by_2time_period('2011-01-01','2011-01-02','2011-02-01','2011-01-02')  => 0
 */
function day_by_2time_period($start1, $end1, $start2, $end2) {
    $t1 = new DateTime($start1);
    $t2 = new DateTime($end1);
    $t3 = new DateTime($start2);
    $t4 = new DateTime($end2);
    // 時間順序錯誤,交換彼此順序
    if ($t1 > $t2) {
        $t = $t2;
        $t1 = $t2;
        $t2 = $t;
        $t = $start1;
        $start1 = $end1;
        $end1 = $t;
    }
    if ($t3 > $t4) {
        $t = $t3;
        $t3 = $t4;
        $t4 = $t;
        $t = $start2;
        $start2 = $end2;
        $end2 = $t;
    }
    $days = 0;
    //沒有重合
    if ($t4 < $t1) return $days;
    if ($t3 > $t2) return $days;
    // t1,t2包含t3,t4
    if ($t3>=$t1 && $t4<=$t2) {
        // 中間的重合部分時間就是s2和e2 s2=>start2, e2=>end2,下同
        $days = $t3->diff($t4)->days;
        $days = day_by_time_period($start2, $end2);
    } else if ($t3>=$t1) {// 開始時間在區間內
        // 重合部分就是s2和e1
        $days = $t3->diff($t2)->days;
        $days = day_by_time_period($start2, $end1);
    } else if ($t4<=$t2) {// 結束時間在區間內
        // 重合部分就是s1和e2
        $days = day_by_time_period($start1, $end2);
    } else { // t3和t4包含 t1,t2
        $days = day_by_time_period($start1, $end1);
        // 重合部分就是s1和e1的重合部分
    }
	return $days;
}
/**
 * 比較2個日期,獲取相隔有多少天
 *
 * 注意這裏時間間隔的問題, 要不然涉及時間計算的地方就容易出bug
 * 2011-11-11          ~ 2011-11-12          => 2
 * 2011-11-11 00:00:00 ~ 2011-11-11 00:00:00 => 2
 * 2011-11-11 00:00:01 ~ 2011-11-12 00:00:00 => 1
 * example:
 * day_by_time_period('2011-01-01','2011-01-02')  => 2
 *
 * @param $start string 時間開始日期 格式string Y-m-d
 * @param $end1 string 時間結束日期 格式string Y-m-d
 * @return int 天數
 */
function day_by_time_period($start, $end) {
	$t1 = new DateTime($start);
    $t2 = new DateTime($end);
    $d = $t1->diff($t2)->days;
    return $d+1;
}
/**
 * 秒轉成 X天X時X秒
 * @param $seconds
 * @return string
 * @author xietaotao
 */
function secsToStr($secs){
    if ($secs >= 86400) {
        $days = floor($secs / 86400);
        $secs = $secs % 86400;
        $r = $days . ' 天';
        if ($days <> 1) {
            $r .= '';//分隔符,臨時刪除但備用 exp: XX天,XX小時,XX分
        }
        if ($secs > 0) {
            $r .= '';
        }
    }
    if ($secs >= 3600) {
        $hours = floor($secs / 3600);
        $secs = $secs % 3600;
        $r .= $hours . ' 小時';
        if ($hours <> 1) {
            $r .= '';
        }
        if ($secs > 0) {
            $r .= '';
        }
    }
    if ($secs >= 60) {
        $minutes = floor($secs / 60);
        $secs = $secs % 60;
        $r .= $minutes . ' 分';
        if ($minutes <> 1) {
            $r .= '';
        }
        if ($secs > 0) {
            $r .= '';
        }
    }
    $r .= $secs . ' 秒';
    if ($secs <> 1) {
        $r .= '';
    }
    return $r;
}    
/**
 * 計算2個時間差多少秒 文本格式返回
 * @param $date1
 * @param $date2
 * @return number
 */
function getDiffSeconds($date1, $date2){
    $date1_stamp = strtotime($date1);
    $date2_stamp = strtotime($date2);
    $diffTime = $date2_stamp - $date1_stamp;
    $diffTime = $diffTime > 0 ? $diffTime : 0;
    return secsToStr($diffTime);
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

更新中…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章