Я разрабатываю веб-приложение, которое вращается вокруг дат.
Мне нужно рассчитать числа, основанные на днях, например, – псевдокод
$count_only = array('monday', 'wednesday', 'friday'); //count only these days $start_date = 1298572294; // a day in the past $finish_date = 1314210695; //another day $var = number_of_days_between($start_date, $finish_date, $count_only);
Есть ли способ определить, сколько прошло много дней, а только подсчет определенных дней?
Вы можете создать цикл, который переходит на следующий день в массив $count_only
, начиная с $start_date
и останавливаясь (возвращаясь из функции) после достижения $end_date
.
function number_of_days_between($start_date, $finish_date, $count_only) { $count = 0; $start = new DateTime("@$start_date"); $end = new DateTime("@$finish_date"); $days = new InfiniteIterator(new ArrayIterator($count_only)); foreach ($days as $day) { $count++; $start->modify("next $day"); if ($start > $end) { return $count; } } }
Вы можете значительно упростить это, вычислив, сколько полных недель находится между двумя указанными датами, затем выполните некоторую математику для начальных / конечных частичных недель, чтобы учитывать даты свисания.
например
$start_date = 1298572294; // Tuesday $finish_date = 1314210695; // Wednesday $diff = 1314210695-1298572294 = 15638401 -> ~181 days -> 25.8 weeks -> 25 full weeks.
Тогда это просто вопрос проверки на свисающие даты:
Tuesday -> add 2 days for Wednesday+Friday to get to the end of the week Wednesday -> add 1 day for Monday to get to the beginning on the week Total countable days = (25 * 3) + 2 + 1 = 75 + 3 = 78 countable days
Конечно, есть способ 🙂
Прошедшие дни просто
$elapsed_days = floor(($finish_date-$start_date) / 86400);
Это не даст результата, который вам нужен. Что вы можете сделать, это следующий (pesudo) код:
$elapsed_days = floor(($finish_date-$start_date) / 86400); for(int $i=0;$i<$elapsed_days;$i++){ $act_day_name = strtolower(date('l',$start_date+$i*86400)); if(in_array($act_day_name,$count_only){ // found matching day } }
Что я делаю: я перебираю каждый день, который находится между обеими датами, получает день с датой ('l'); и проверьте, находится ли он в массиве. Возможно, потребуется тонкая настройка, но это должно заставить вас идти.
Совсем немного быстрее, чем «итерация через все дни»:
$count_only = array(1, 3, 5); // days numbers from getdate() function $start_date = 1298572294; $finish_date = 1314210695; function days($start_date, $finish_date, $count_only) { $cnt = 0; // iterate over 7 days for ($deltaDays = 0; $deltaDays < 7; $deltaDays++) { $rangeStart = $start_date + $deltaDays * 86400; // check the weekday of rangeStart $d = getDate($rangeStart); if (in_array($d['wday'], $count_only)) { $cnt += ceil(($finish_date - $rangeStart) / 604800); } } return $cnt; }
Идея состоит в том, чтобы подсчитать количество недель, используя некоторые дополнительные смещения в течение понедельника, понедельника, понедельника и т. Д.