最近维护公司的项目,报表功能有个计算周月均值的功能。就是选取一段时间算自然周月的数据平均值。
比如 20191015 - 20191029 是有三个自然周的(其中有不是整周的自然周),我需要把这三个自然周找到,算出这三个自然周的数据平均值,算出结果后类似下图:
只是类似这样的折线图。
<?php
/**
* Created by PhpStorm.
* User: v_bivwei
* Date: 2019/10/21
* Time: 10:56
* Desc: 时间处理工具类
*/
class ReportDateTools
{
/**
* @param $begin
* @param $end
* @param string $type
* @return array
* @description 获取一段时间的连续日期列表
* @author v_bivwei
*/
public static function timeList($begin, $end, $type = 'string')
{
$begin = strtotime($begin);
$end = strtotime($end);
$list = array();
switch ($type) {
case 'string':
for ($i = $begin; $i <= $end; $i += (24 * 3600)) {
$list[] = date("Y-m-d", $i);
}
break;
case 'int':
for ($i = $begin; $i <= $end; $i += (24 * 3600)) {
$list[] = date("Ymd", $i);
}
break;
}
return $list;
}
/**
* @param $startdate
* @param $enddate
* @param string $type
* @return array
* @description 获取一段时间的连续自然周
* @author v_bivwei
*/
public static function getWeek($startdate, $enddate, $type = 'string')
{
$beginDate = $startdate;
$endDate = $enddate;
//参数不能为空
if (!empty($startdate) && !empty($enddate)) {
//先把两个日期转为时间戳
$startdate = strtotime($startdate);
$enddate = strtotime($enddate);
//开始日期不能大于结束日期
if ($startdate <= $enddate) {
$end_date = strtotime("next monday", $enddate);
if (date("w", $startdate) == 1) {
$start_date = $startdate;
} else {
$start_date = strtotime("last monday", $startdate);
}
//计算时间差多少周
$countweek = ($end_date - $start_date) / (7 * 24 * 3600);
for ($i = 0; $i < $countweek; $i++) {
if ($type == 'string') {
$sd = date("Y-m-d", $start_date);
} else {
$sd = date("Ymd", $start_date);
}
$ed = strtotime("+ 6 days", $start_date);
if ($type == 'string') {
$eed = date("Y-m-d", $ed);
} else {
$eed = date("Ymd", $ed);
}
$arr[] = array(
$sd,
$eed
);
$start_date = strtotime("+ 1 day", $ed);
}
$timeList = self::timeList($beginDate, $endDate, $type);
foreach ($arr as $key => &$item) {
$diff = array_diff($item, $timeList);
if (empty($diff)) {
$item['full'] = true;
$list = self::timeList($item[0], $item[1], $type);
$item['list'] = array_values(array_intersect($timeList, $list));
} else {
$item['full'] = false;
$list = self::timeList($item[0], $item[1], $type);
$item['list'] = array_values(array_intersect($timeList, $list));
}
}
return $arr;
}
}
}
/**
* @param $start
* @param $end
* @param string $type
* @return array
* @description 获取一段时间的连续自然月
* @author v_bivwei
*/
public static function getMonth($start, $end, $type = 'string')
{
$startDate = $start;
$endDate = $end;
$end = date('Ym', strtotime($end)); // 转换为月
$range = array();
$i = 0;
do {
$month = date('Ym', strtotime($start . ' + ' . $i . ' month'));
$range[] = $month;
$i++;
} while ($month < $end);
$_ret = array();
$ret = array();
foreach ($range as $key => $item) {
switch ($type) {
case 'string':
$firstday = date('Y-m-01', strtotime($item . "01")); //月初
$lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));//月末
break;
case 'int':
$firstday = date('Ym01', strtotime($item . "01")); //月初
$lastday = date('Ymd', strtotime("$firstday +1 month -1 day"));//月末
break;
}
$_ret[$item] = array(
$firstday,
$lastday
);
}
$timeList = self::timeList($startDate, $endDate, $type);
foreach ($_ret as $key => &$value) {
$diff = array_diff($value, $timeList);
if (empty($diff)) {
$value['full'] = true;
$list = self::timeList($value[0], $value[1], $type);
$value['list'] = array_values(array_intersect($timeList, $list));
} else {
$value['full'] = false;
$list = self::timeList($value[0], $value[1], $type);
$value['list'] = array_values(array_intersect($timeList, $list));
}
$ret[$key] = $value;
}
return $ret;
}
}
使用示例:
<?php
/**
* Created by PhpStorm.
* User: v_bivwei
* Date: 2019/10/22
* Time: 11:49
*/
require_once 'ReportDateTools.php';
$startDate = '20191015';
$endDate = '20191029';
$type = 'int';
$timeList = ReportDateTools::timeList($startDate, $endDate, $type);
$weeks = ReportDateTools::getWeek($startDate, $endDate, $type);
$months = ReportDateTools::getMonth($startDate, $endDate, $type);
var_dump($timeList, $weeks, $months);
结果: