так что я вернулся, я добавлю лучший закомментированный код, здесь: не могу редактировать старый ответ, так как я удалил свою учетную запись и забыл отменить: |
В любом случае, вы спросили, как манипулировать данными. Это простой массив, и все внутренние массивы являются суммами от начала недели до конца. Теперь вы можете хранить их с разными ключами, я просто использовал назначение по умолчанию из-за простоты.
<code>$results=array(
array( 'due_date'=>'12/02/2020', 'run_hours'=>12.4, 'setup_hours'=>2.4, ), // 2020-02-12 00:00:00
array( 'due_date'=>'15/02/2020', 'run_hours'=>10.4, 'setup_hours'=>1.4, ), // 2020-02-15 00:00:00
array( 'due_date'=>'18/02/2020', 'run_hours'=>8.4, 'setup_hours'=>3.4, ), // 2020-02-18 00:00:00
array( 'due_date'=>'20/02/2020', 'run_hours'=>2.4, 'setup_hours'=>1.4, ), // 2020-02-20 00:00:00
array( 'due_date'=>'21/02/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ), // 2020-02-21 00:00:00
array( 'due_date'=>'24/02/2020', 'run_hours'=>12.4, 'setup_hours'=>1.4, ), // 2020-02-24 00:00:00
array( 'due_date'=>'26/02/2020', 'run_hours'=>11.3, 'setup_hours'=>1.4, ), // 2020-02-26 00:00:00
array( 'due_date'=>'29/02/2020', 'run_hours'=>4.4, 'setup_hours'=>2.4, ), // 2020-02-29 00:00:00
array( 'due_date'=>'02/03/2020', 'run_hours'=>5.7, 'setup_hours'=>4, ), // 2020-03-02 00:00:00
array( 'due_date'=>'04/03/2020', 'run_hours'=>11.5, 'setup_hours'=>3.4, ), // 2020-03-04 00:00:00
array( 'due_date'=>'06/03/2020', 'run_hours'=>7.3, 'setup_hours'=>1.4, ), // 2020-03-06 00:00:00
array( 'due_date'=>'08/03/2020', 'run_hours'=>9.6, 'setup_hours'=>1.4, ), // 2020-03-08 00:00:00
array( 'due_date'=>'12/03/2020', 'run_hours'=>14.7, 'setup_hours'=>1.4, ), // 2020-03-12 00:00:00
array( 'due_date'=>'15/03/2020', 'run_hours'=>12.5, 'setup_hours'=>1.4, ), // 2020-03-15 00:00:00
array( 'due_date'=>'19/03/2020', 'run_hours'=>4.4, 'setup_hours'=>1.4, ), // 2020-03-19 00:00:00
array( 'due_date'=>'21/03/2020', 'run_hours'=>5.6, 'setup_hours'=>4, ), // 2020-03-21 00:00:00
array( 'due_date'=>'24/03/2020', 'run_hours'=>11.4, 'setup_hours'=>1.4, ), // 2020-03-24 00:00:00
array( 'due_date'=>'29/03/2020', 'run_hours'=>7.4, 'setup_hours'=>1.4, ), // 2020-03-29 00:00:00
array( 'due_date'=>'01/04/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ), // 2020-04-01 00:00:00
// some far off weeks
array( 'due_date'=>'18/06/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ),
array( 'due_date'=>'21/06/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ),
array( 'due_date'=>'09/07/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ),
array( 'due_date'=>'12/08/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ),
);
$time=strtotime(date('Y-m-d')); // get time in same
// wrapping time in strtotime and date trims the seconds to the desired format
$one_week=60*60*24*7;
$sums=array();
foreach($results as $row){
/* php 5.3+ this block of code gets the time of the date, this conversions are made in case a custom non standard date format is made, alternatively one can use strtotime with the correct date format
$date = DateTime::createFromFormat('d/m/Y', $row['due_date']);//use your format and values
if(!$date){
echo 'Not a valid format';
break;
}
$entry_time = strtotime(date('Y-m-d',$date->getTimestamp()));
// if your date format doesnt have hours minutes and seconds then timestamp will add the current h,min,s,
// this may not be desired, so this wrapping it in strtotime and date trims the values
*/
// WARNING: If the format is right weeks will be way off
$entry_time = strtotime($row['due_date']); // if due_date is a valid format, see PHP docs for more information
if (!$entry_time) {
echo "Not a valid date format";
break;
}
$entry_work_hours=$row['run_hours']+$row['setup_hours'];
// if the entry time is by some reason smaller then the current time save it to a special past_due container
if ($entry_time < $time) {
// if a past_due container exists add the sum, otherwise create a past_due container
if (isset($sums['past_due'])) {
$sums['past_due']['sum']+=$entry_work_hours;
} else {
$sums['past_due']= array(
'sum' => $entry_work_hours,
'start' => $row['due_date'], // the earliest event
'end' => date('d/m/Y',$time), // current time, if $entry_time is bigger or equal we're talking about entries that are yet to happen
);
}
} else if ( $entry_time >= $time ){
// getting the future_dues array, every object holds an array/map, that holds the sum, the start of the week and when the week ends
// endings are exclusive ie. if an entry_data falls on the end date it goes to the start of the next container
if (isset($sums['future_dues'])) {
$future_dues=$sums['future_dues'];
} else {
$future_dues = array(
array(
'sum' => 0,
'start' => $time,
'end' => $time+$one_week
)
);
}
// get the last week container, and save the key so we can reassign it back to the $sums array on the right spot
$last_index = count($future_dues)-1;
$future_due = $future_dues[$last_index];
// manipulate the week data
// if the entry time is smaller then the current end of the week add to the sum, otherwise add a new week interval container
if ($entry_time < $future_due['end']) {
$future_due['sum']+=$entry_work_hours;
// reassign week container
$future_dues[$last_index]=$future_due;
} else {
$last_week_end = $future_due['end'];
$new_end = $last_week_end + $one_week;
//do a while loop to get the next week end in which the work is done
while ($new_end < $entry_time) {
// skip this part if empty weeks are not desired
$future_dues[] = array(
'sum' => 0,
'start' => $last_week_end,
'end' => $new_end
);
$last_week_end = $new_end;
$new_end = $new_end + $one_week;
// echo "$new_end < $entry_time".'<br>';
}
// add a new week container, the start of the week is the end of the previous one and the end is 7 days from that
$future_dues[]=array(
'sum' => $entry_work_hours,
'start' => $last_week_end,
'end' => $new_end
);
}
// reassign the whole week containers container to the array
$sums['future_dues']=$future_dues;
}
}
// convert time back to dates
foreach ($sums['future_dues'] as $key => &$due) {
$due['start']=date('d/m/Y',$due['start']);
$due['end']=date('d/m/Y',$due['end']);
}
// use $sums to display the values you need, use:
// echo "<pre>";
// print_r($sums);
// echo "
"; //, чтобы лучше понять, как хранятся данные echo"
"; // use pre tags to have a nice inline values, this can be rewriten into a table
$past_due=$sums['past_due'];
//past due is a single container
$time_prefix="Time: ";
$working_hours_prefix="Working hours: ";
$time = $time_prefix.$sums['past_due']['start']." - ".$sums['past_due']['end'];
echo $time."<br>";
echo $working_hours_prefix.str_pad($sums['past_due']['sum'],abs(strlen($time)-strlen($working_hours_prefix)),' ',STR_PAD_LEFT);
// make it inline with the time
echo "<br><br>";
$due_dates=$sums['future_dues'];
foreach($due_dates as $week_container){
$time = $time_prefix.$week_container['start']." - ".$week_container['end'];
echo $time."<br>";
echo $working_hours_prefix.str_pad($week_container['sum'],abs(strlen($time)-strlen($working_hours_prefix)),' ',STR_PAD_LEFT);
echo "<br><br>";
//echo $week_container['sum']; /// if you want to show the sum
//echo $week_container['start']; /// if you want to show the start
//echo $week_container['end']; /// if you want to show the end
}
echo "
"; // выше немного абстрагировано, но это обязательно делает это эхо "
"; эхо "
"; $ past_due = $ sums ['past_due']; $ past_start = $ sums ['past_due'] ['start ']; $ past_end = $ sums [' past_due '] [' end ']; $ past_sum = $ sums [' past_due '] [' sum ']; echo "Время: $ past_start - $ past_end
"; echo "Рабочее время: $ past_sum"; // предыдущий случай добавляет разрывы для встроенного эха "
"; $ due_dates = $ sums ['future_dues']; foreach ($ due_dates as $ week_container) {$ week_start = $ week_container ['start']; $ week_end = $ week_container ['end']; $ week_sum = $ week_container ['sum']; echo "Время: $ week_start - $ week_end
"; echo "Рабочее время: $ week_sum "; // предыдущий случай добавляет разрывы, чтобы быть встроенным эхом"
";}
Редактировать: Новое, в то время как l oop было добавлено к счету для пустых недель. Примечание д / м / у не пора распознанный формат и будет читаться как м / д / у. Чтобы преобразовать , обратитесь к этому вопросу.
Edit-2: Чтобы ответить на ваш комментарий. Хорошо, так что дело в пролетах в том, что я сделал их так, чтобы, если пролет прошел с 2020-01-01 до 2020-01-08, а второй с 2020-01-08 до 2020-01-15, где должен работать часы 2020-01-08 go до недели 1 или недели 2? Если вы исправили $ entry_time <$ future_due ['end'] в $ entry_time <= $ future_due ['end'], это означает, что счет добавляется к 1-й неделе, тогда как исходное решение добавило бы его к 2-й неделе в качестве начального. свидание. </p>
Вы можете попытаться добавить 8 дней, а затем вычесть один, если вы хотите, чтобы контейнеры проходили между 2020-01-01 и 2020-01-08 и 2020-01-09 и 2020-01-16 и имели оба окончания должны быть включены. Теперь я не собираюсь писать эту часть, поскольку она действительно зависит от того, как ВЫ хотите определить свои окончания.
И ваш вопрос, можете ли вы изменить время на другое, отличное от текущего? Конечно, просто измените эту строку.
$time=strtotime(date('Y-m-d'));
//to
$time=__TIME__YOU_WANT_IN_SECONDS__;
//or
$time = strtotime(__THE_DATE_YOU_WANT__); // eg. 01/01/2020
// now this is the time to compare all other dates to