php 修改二维数组中的行,使日期时间戳连续

vlurs2pr  于 2023-02-28  发布在  PHP
关注(0)|答案(3)|浏览(92)

我有一个2d的作业数组,每个作业包含一个开始时间,一个结束时间(总是在开始时间之后60分钟),然后是一个"add"值(下一个作业开始之前的分钟数)。
我需要调整所有行,使每个开始时间等于前一个作业的结束时间加上其"添加"时间。
下面是一个示例数组:

[
    [
        'id' => 9,
        'needed_at' => '2023-02-26 03:31:04',
        'ended_at' => '2023-02-26 04:31:04',
        'add' => 20
    ],
    [
        'id' => 6,
        'needed_at' => '2023-02-26 04:51:04',
        'ended_at' => '2023-02-26 05:51:04',
        'add' => 30
    ],
    [
        'id' => 7,
        'needed_at' => '2023-02-26 09:21:04',
        'ended_at' => '2023-02-26 10:21:04',
        'add' => 30
    ]
]

我想要的结果:

[
    [
        'id' => 9,
        'needed_at' => '2023-02-26 03:31:04',
        'ended_at' => '2023-02-26 04:31:04',
        'add' => 20
    ],
    [
        'id' => 6,
        'needed_at' => '2023-02-26 04:51:04',
        'ended_at' => '2023-02-26 05:51:04',
        'add' => 30
    ],
    [
        'id' => 7,
        'needed_at' => '2023-02-26 06:21:04',  # changed based on id 6 data
        'ended_at' => '2023-02-26 07:21:04',   # changed based on new need_at time of this row
        'add' => 30                            # not actually used because no next job
    ]
]

我尝试的是:

foreach ($jobs as $k => $j) {
    $s = $k+1;
    $date = new \DateTimeImmutable($j->ended_at);
    $add = $j->add;
    $date_new = $date->modify('+'.$add.' minutes');
    $needed_at = $date_new->format('Y-m-d H:i:s');
    $data['needed_at'] = $needed_at;
    
    $date2 = new \DateTimeImmutable($needed_at);
    $ended_at = $date2->modify('+60 minutes');
    $data['ended_at'] = $ended_at->format('Y-m-d H:i:s');
    $d[]=[
        'id' => $jobs[$s]->id,
        'needed_at' => $needed_at,
        'ended_at' => $data['ended_at'],
        'add' => $add
    ];
}

它不起作用。是否可以将第一次迭代修改的数据用于第二次迭代?

dbf7pr2w

dbf7pr2w1#

由于数组的第一个元素不会改变,因此我们将其排除在循环之外。
要获得预期输出,有两个要素很重要:ended_atadd,则在每次迭代之后,这些变量将采用当前值,以此类推

$format = 'Y-m-d H:i:s';

$ended_at = $jobs[0]['ended_at'];
$add = $jobs[0]['add'];

$d[0] = $jobs[0];
foreach($jobs as $k => $j){
       if ($k < 1) continue;
       
       $ended_at = DateTimeImmutable::createFromFormat($format, $ended_at);
       
       $ended = $ended_at->modify('+'.$add.' minutes');
       $needed = $ended->modify('+60 minutes');
       
       $ended = $ended->format($format);
       $needed = $needed->format($format);
       
       $d[]=array(
         'id' => $jobs[$k]['id'],
         'needed_at' => $ended,
         'ended_at' => $needed,
         'add' => $jobs[$k]['add']
       );
       
       $ended_at = $needed;
       $add = $jobs[$k]['add'];
       
}

print_r($d);

Demo here

iswrvxsc

iswrvxsc2#

若要以直接简洁的方式在数据中的所有行上创建连续的日期时间戳,请使用单个循环,通过引用修改行,声明单个日期时间对象,然后根据需要切换或保存日期时间戳。
不需要通过构建一个全新的输出数组来浪费/加倍内存。
代码:(Demo

$format = 'Y-m-d H:i:s';
foreach ($jobs as &$row) {
    $dt ??= new DateTime($row['needed_at']);  // declare if not yet declared
    $row['needed_at'] = $dt->format($format); // save in desired format
    $dt->modify('+ 60 minutes');              // bump by duration in minutes
    $row['ended_at'] = $dt->format($format);  // save in desired format
    $dt->modify("+ {$row['add']} minutes");   // bump by gap in minutes in preparation for next row
}

var_export($jobs);
lf3rwulv

lf3rwulv3#

foreach($jobs as $k => $j){
    $s = $k+1;
    $date = new \DateTimeImmutable($j['ended_at']); // Modified to use array notation for $j
    $add = $j['add']; // Modified to use array notation for $j
    $date_new = $date->modify('+'.$add.' minutes');
    $needed_at = $date_new->format('Y-m-d H:i:s');
    $data['needed_at'] = $needed_at;
    
    $date2 = new \DateTimeImmutable($needed_at);
    $ended_at = $date2->modify('+60 minutes');
    $data['ended_at'] = $ended_at->format('Y-m-d H:i:s');

    $d[]=[
        'id' => $jobs[$s]['id'], // Modified to use array notation for $jobs
        'needed_at' => $data['needed_at'],
        'ended_at' => $data['ended_at'],
        'add' => $add
    ];

    // Update the value of $jobs[$s]['needed_at'] for the next iteration
    $jobs[$s]['needed_at'] = $data['ended_at'];
}

相关问题