時間處理函數總結
/**
* 獲得當前格林威治時間的時間戳
* @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);
}
更新中…