Поиск всех будних дней в месяце - PullRequest
1 голос
/ 15 июня 2011

Как мне получить все работу дней (пн-пт) за определенный период времени (скажем, с сегодняшнего дня до конца следующего месяца)? ​​

Ответы [ 7 ]

3 голосов
/ 15 июня 2011

Если вы используете PHP 5.2+, вы можете использовать библиотеку, которую я написал, для обработки рекурсии даты в PHP, которая называется When .

С библиотекой код будет выглядеть примерно так:

$r = new When();
$r->recur(<start date here>, 'weekly')
  ->until(<end date here>)
  ->wkst('SU')
  ->byday(array('MO', 'TU', 'WE', 'TH', 'FR'));

while($result = $r->next())
{
    echo $result->format('c') . '<br />';
}
2 голосов
/ 15 июня 2011

Этот образец делает именно то, что вам нужно, быстро и эффективно. Он не выполняет вложенные циклы и использует совершенно потрясающий DateTime объект.

$oDateTime = new DateTime();
$oDayIncrease = new DateInterval("P1D");

$aWeekDays = array();
$sStart = $oDateTime->format("m-Y");
while($oDateTime->format("m-Y") == $sStart) {
    $iDayInWeek = $oDateTime->format("w");
    if ($iDayInWeek > 0 && $iDayInWeek < 6) {
        $aWeekDays[] = clone $oDateTime;

    }
    $oDateTime->add($oDayIncrease);
}
2 голосов
/ 15 июня 2011

Попробуйте здесь: http://codepad.org/wuAyAqnF

Чтобы использовать его, просто передайте метку времени в get_weekdays.Вы вернете массив всех будних дней в виде меток времени до конца текущего месяца.При желании вы можете передать аргумент $to - вы получите все дни недели от $from до $to.

function get_weekdays ($from, $to=false) {
    if ($to == false)
        $to = last_day_of_month($from);

    $days = array();

    for ($x = $from; $x < $to; $x+=86400 ) {
        if (date('w', $x) > 0 && date('w', $x) < 6)
            $days[] = $x;
    }
    return $days;       
}

function last_day_of_month($ts=false) {
    $m = date('m', $ts);
    $y = date('y', $ts);
    return mktime(23, 59, 59, ($m+1), 0, $y);
}
1 голос
/ 15 июня 2011
// Find today's day of the month (i.e. 15)
$today = intval(date('d'));

// Define the array that will hold the work days.
$work_days = array()

// Find this month's last day. (i.e. 30)
$last = intval(date('d', strtotime('last day of this month')));

// Loop through all of the days between today and the last day of the month (i.e. 15 through 30)
for ( $i = $today; $i <= $last; $i++ )
{
  // Create a timestamp.
  $timestamp = mktime(null, null, null, null, $i);

  // If the day of the week is greater than Sunday (0) but less than Saturday (6), add the timestamp to an array.
  if ( intval(date('w', $timestamp)) > 0 && intval(date('w', $timestamp)) < 6 )
    $work_days[] = mktime($timestamp);
}

Массив $work_days будет содержать метки времени, которые вы можете использовать следующим образом:

echo date('Y-m-d', $work_days[0]);

Приведенный выше код работает как в PHP 4, так и в PHP 5. Он не зависитфункциональность класса DateTime, которая была недоступна до PHP 5.2 и не требует использования «библиотек», созданных другими людьми.

1 голос
/ 15 июня 2011

Этот код выполняет как минимум одну часть, которую вы запрашиваете. Вместо «конец следующего месяца» он просто работает с заданным количеством дней.

$dfrom = time();
$fourweeks = 7 * 4;

for ($i = 0; $i < $fourweeks; $i ++) {
    $stamp = $dfrom + ($i * 24 * 60 * 60);
    $weekday = date("D", $stamp);
    if (in_array($weekday, array("Mon", "Tue", "Wed", "Thu", "Fri"))) {
        print date(DATE_RSS, $stamp) . "\n";
    }
}
1 голос
/ 15 июня 2011

Псевдокод подходит к вам:

Рассчитать количество дней между настоящим и последним днем ​​месяца. Получить текущий день недели (т.е. среда) Основываясь на текущем дне недели и количестве дней, оставшихся в месяце, можно легко рассчитать, сколько дней выходных осталось в месяце - это будет количество дней, оставшихся в месяце, за вычетом количество воскресений / суббот, оставшихся в месяце.

Я бы написал функцию, что-то вроде:

daysLeftInMonth(daysLeftInMonth, startingDayOfWeek, dayOfWeekToCalculate)

где:

  • daysLeftInMonth - последний день месяца (30), минус текущая дата (15)
  • startDayOfWeek - это день недели, с которого вы хотите начать (на сегодня это будет среда)
  • dayOfWeekToCalculate - это день недели, который вы хотите посчитать, например, Суббота или воскресенье. В июне 2011 года 2 воскресенья и 2 субботы до конца месяца

Итак, ваш алгоритм становится примерно таким:

getWeekdaysLeft(todaysDate)

... getWeekdaysLeft - это что-то вроде:

sundaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Sunday");
saturdaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Saturday");
return ((lastDayOfMonth - todaysDate) - (sundaysLeft + saturdaysLeft));
1 голос
/ 15 июня 2011

Полагаю, вы могли бы перебрать даты и проверить день для каждого и увеличить счетчик.

Не могу думать ни о чем другом на макушке моей головы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...