时间处理函数总结
程序员文章站
2024-01-27 08:11:04
...
时间处理函数总结
/**
* 获得当前格林威治时间的时间戳
* @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);
}
更新中…