PHP « php алгоритм нахождения пересечений дат
есть 2 даты
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }
$start = '2010-08-11 11:13:33';
$end = '2010-08-13 14:12:11';
За каждый час платят 100 рублей, но есть бонусные часы, например во вторник и среду с 22.00 - 06.00 в который платят 200 рублей.
В общем на основании этих дат(start и end) нужно посчитать зарплату за смену.
p.s. не прощу прям кода, можно словами как находить бонусные пересечения.
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }
$start = '2010-08-11 11:13:33';
$end = '2010-08-13 14:12:11';
За каждый час платят 100 рублей, но есть бонусные часы, например во вторник и среду с 22.00 - 06.00 в который платят 200 рублей.
В общем на основании этих дат(start и end) нужно посчитать зарплату за смену.
p.s. не прощу прям кода, можно словами как находить бонусные пересечения.
1 ответов
<?php
$start = '2010-08-10 21:13:33';
$end = '2010-08-13 22:12:11';
//задаем массив бонусных часов
//WARNING: периоды содержащие полночь задавать так : с 00:00 до 02:00 и с 23:00 до 24:00
$days_find = array(
array(2, 20, 22),//вторник, с 20:00 до 22:00
array(4, 19, 20),//четверг, с 19:00 до 20:00
array(5, 19, 20) //пятница, с 19:00 до 20:00
);
$result_days = 0; //найдено бонусных дней
$result_hours = 0; //найдено бонусных часов
$timestamp_start = strtotime($start);
$timestamp_end = strtotime($end);
$day_start = date('N', $timestamp_start);//определяем день недели по дате (1-Пн, 2-Вт.....7-Вс)
$day_end = date('N', $timestamp_end);
$hour_start = date('G', $timestamp_start);//определяем часы
$hour_end = date('G', $timestamp_end);
//проверяем содержат ли первый и последний дни бонусные часы
foreach($days_find as $day)
{
if($day_end == $day[0])
{
$result_days++;
//если 22:12:11 попадает в бонусные часы
if($hour_end < $day[2] && $hour_end > $day[1])
$result_hours += $day[2]-$hour_end;
//если 22:12:11 полностью включает в себя бонусные часы
elseif($hour_end >= $day[2])
$result_hours += $day[2]-$day[1];
}
if($day_start == $day[0] && $day_start != $day_end)
{
$result_days++;
if($hour_start < $day[2] && $hour_start > $day[1])
$result_hours += $day[2]-$hour_start;
elseif($hour_start <= $day[1])
$result_hours += $day[2]-$day[1];
}
}
//считаем кол-во дней в заданном периоде
$all_days = floor(($timestamp_end - $timestamp_start)/(24*60*60));
//период больше недели
if($all_days > 7)
{
foreach($days_find as $day)
{
if($day_start < $day[0] && $day_end > $day[0])
{
$result_hours += $day[2]-$day[1];
$result_days++;
}
$hour += $day[2]-$day[1]; //подсчитываем все бонусные часы, дабы потом их умножить на кол-во полных недель
}
$result_hours += floor($all_days/7)*$hour;
$result_days += floor($all_days/7)*count($days_find);
}
//период меньше недели
elseif($all_days != 0)
{
//период состоит из 2х недель
if($day_end <= $day_start)
{
foreach ($days_find as $day)
if($day[0] > $day_start)
{
$result_days++;
$result_hours += $day[2]-$day[1];
}
}
//период состоит из одной недели
else
{
foreach($days_find as $day)
if($day[0] < $day_end && $day[0] > $day_start)
{
$result_days++;
$result_hours += $day[2]-$day[1];
}
}
}
echo 'day_start = '.$day_start.'
';
echo 'day_end = '.$day_end.'
';
echo 'all_days = '.$all_days.'
';
echo 'result_days = '.$result_days.'
';
echo 'result_hours = '.$result_hours.'
';
?>