Php 几周前的时候

Php 几周前的时候,php,arrays,date,mktime,Php,Arrays,Date,Mktime,所以我有这种情况。我有多个数组,如下所示: $array('date'=>'00-00-00', 'value'=>'xx'); $array = array(...); // your input array $start_time = new DateTime(); // Alternately, if you need week boundary to not be based on "now" // but rather on fixed start of week yo

所以我有这种情况。我有多个数组,如下所示:

$array('date'=>'00-00-00', 'value'=>'xx');
$array = array(...); // your input array
$start_time = new DateTime();
// Alternately, if you need week boundary to not be based on "now" 
// but rather on fixed start of week you could do something like
// $current_time = new DateTime('Monday this week 00:00:00');
$date_interval = new DateInterval('P1W');
$date_interval->invert = 1; // make it negative interval
// build DatePeriod object with 4 interval periods - don't include start date
$date_period = new DatePeriod($start_time, $date_interval, 4, DatePeriod::EXCLUDE_START_DATE);

$final_array = array(0,0,0,0); // the destination array with default start values
array_walk($array, function($item, $key_not_used) use ($date_period, $final_array) {
    // change date format as necessary below
    $item_time = DateTime::createFromFormat('y-m-d', $item['date']);
    $value = $item['value'];
    foreach($date_period as $i => $comparison_time) {
        if ($item_time > $comparison_time) {
            // aggregate this value into $final_array.
            // I assume this is simple addition but any sort of aggregation can be used by changing this line below
            $final_array[$i] = $final_array[$i] + $value;
            // break out of loop since comparison already completed
            break;
        }
    }
});
var_dump($final_array);
我要做的是遍历所有数组,并生成4个变量:
$week1、$week2、$week3、$week4
,根据从某个日期算起的时间是1周前、2周前、3周前还是4周前,我将在其中存储聚合值

我试过这个,但不起作用。尽管我有很多日期,它们都有值,但它返回0表示所有内容,名称只是占位符,我实际上并没有称它们为“数组”:

     $date = 'xx-xx-xx';
     $month = array();

     $week1 = strtotime($date . '-1 week');
     $week2 = strtotime($date . '-2 week');
     $week3 = strtotime($date . '-3 week');
     $week4 = strtotime($date . '-4 week');


     foreach($arrays as $array){

        if( (date('W', strtotime($array['date']) == date('W', strtotime($week1)))) AND (date('Y', strtotime($array['date'])) == date('Y', strtotime($week1)))){
            $month['week1'] += $array['value'];
        }

        if( (date('W', strtotime($array['date']) == date('W', strtotime($week2)))) AND (date('Y', strtotime($array['date'])) == date('Y', strtotime($week2)))){
            $month['week2'] += $array['value'];
        }

        if( (date('W', strtotime($array['date']) == date('W', strtotime($week3)))) AND (date('Y', strtotime($array['date'])) == date('Y', strtotime($week3)))){
            $month['week3'] += $array['value'];
        }

        if( (date('W', strtotime($array['date']) == date('W', strtotime($week4)))) AND (date('Y', strtotime($array['date'])) == date('Y', strtotime($week4)))){
            $month['week4'] += $array['value'];
        }           
     }

     return $month;

您的数据格式有点问题,因为您使用的是不明确的XX-XX-XX格式。这是什么意思?年月日?年月日?年月日?如果不进一步定义日期字符串代表的内容,就不能期望strotime转换该格式

我还建议使用DateTime、DateInterval、DatePeriod等类,因为这些类比旧的PHP日期操作函数功能更全面

因此,我可以这样实现:

$array('date'=>'00-00-00', 'value'=>'xx');
$array = array(...); // your input array
$start_time = new DateTime();
// Alternately, if you need week boundary to not be based on "now" 
// but rather on fixed start of week you could do something like
// $current_time = new DateTime('Monday this week 00:00:00');
$date_interval = new DateInterval('P1W');
$date_interval->invert = 1; // make it negative interval
// build DatePeriod object with 4 interval periods - don't include start date
$date_period = new DatePeriod($start_time, $date_interval, 4, DatePeriod::EXCLUDE_START_DATE);

$final_array = array(0,0,0,0); // the destination array with default start values
array_walk($array, function($item, $key_not_used) use ($date_period, $final_array) {
    // change date format as necessary below
    $item_time = DateTime::createFromFormat('y-m-d', $item['date']);
    $value = $item['value'];
    foreach($date_period as $i => $comparison_time) {
        if ($item_time > $comparison_time) {
            // aggregate this value into $final_array.
            // I assume this is simple addition but any sort of aggregation can be used by changing this line below
            $final_array[$i] = $final_array[$i] + $value;
            // break out of loop since comparison already completed
            break;
        }
    }
});
var_dump($final_array);
这将为最终数组提供如下值:

Array(
    [0] => ?, // aggregation for dates > 1 week ago
    [1] => ?, // aggregation for dates between 1 and 2 weeks ago
    [2] => ?, // aggregation for dates between 2 and 3 weeks ago
    [3] => ? // aggregation for dates between 3 and 4 weeks ago
)

你的方法似乎很好。为什么你会认为它很慢?你可以用elseif代替if

如果你感觉不好,考虑一周是7×24×3600=604800秒。因此,一周中的周一上午(00:00)是:

$timestamp = strtotime($date);
$time_since_thursday = $timestamp % 604800;
$time_since_monday = ($time_since_thursday + 259200) % 604800;
$monday = $timestamp - $time_since_monday;
那么你就可以用这个星期一早上到另一个日期的时间差:

foreach($arrays as $array) {
  $difference = $monday - $array['date'];
  if ($difference > 0) { // else it would be in the same week or even later
    $difference_weeks = (int)($difference / 604800);
    if ($differenceWeeks <= 3) { // else it is more than the 4th week behind
      $month['week' . ($difference_weeks + 1)] += $array['value'];
    }
  }
}
foreach($array作为$array){
$difference=$monday-$array['date'];
如果($difference>0){//否则它将在同一周内,甚至更晚
$difference_weeks=(int)($difference/604800);

如果($differenceWeeks)由于某种原因,我的代码不仅速度慢,而且现在无法工作check@raygo你读过Mike Brant的答案吗?也许这是一个问题(它在YYYY-mm-dd日期应该可以正常工作)。另外,我会用
$month=array('week1'=>0,'week2'=>0,'week3'=>0,'week4'=>0)初始化数组;
是我的$date变量等于date('Y-m-d')