2015-05-19 5 views
-1

У меня есть следующий код для расчета 10 рабочих дней с этого момента, этот код был изменен из ранее ответного ответа, который показал 3 предыдущих рабочих дня, однако мой предположительно должен показать 10 рабочих дней с этого момента , он, однако, не возвращает правильную дату, пожалуйста, я с просьбой о какой-то помощиPHP Функция не возвращается 10 рабочих дней

function working_days($days) { 
    $count = 0; 
$day = strtotime('now'); 
while ($count < 10 || date('N', $day) > 5) { 
    $count++; 
    $day = strtotime('1 day', $day); 
} 
    return date('F d Y', $day); 
} 

$ten_days = working_days('10'); 

echo ($ten_days); 
+0

'StrToTime ('п ow ') 'является массово неэффективным. почему не просто 'time()'? –

+0

@MarcB ok, но все остальное код правильный? – dames

+0

выглядит так, как будто он должен работать, но вы, возможно, могли бы сделать это без петли вообще. –

ответ

0

Вы можете использовать встроенную функцию РНР mktime для расчета дней в прошлом или будущем.

<?php 

$ten_days = date("F d Y", mktime(0, 0, 0, date("m"), date("d") + 10, date("Y"))); 

mktime принимает:

  • час
  • минуту
  • Второй
  • Месяц
  • день
  • Год

Затем вы можете добавить или вычесть время из любого элемента. Здесь, установив Hour, Minute и Second на нули и используя значения для текущего месяца, дня и года. Наконец, я добавляю 10 дней к текущему дню с + 10.


EDIT: Я просто понял, что ОП просят рабочих дней. Если рабочие дни означают понедельник-пятницу, вы можете просто выйти 2 недели на любой текущий день, который уже с понедельника по пятницу. В субботу и воскресенье вы можете просто использовать следующие предстоящие 10 понедельника-пятницы.

<?php 

if (date("w") == 0) { // SUNDAY 
    $date_add = 12; 
} 
elseif (date("w") == 6) { // SATURDAY 
    $date_add = 13; 
} 
else { 
    $date_add = 14; 
} 

$ten_days = date("F d Y", mktime(0, 0, 0, date("m"), date("d") + $date_add, date("Y"))); 

print $ten_days; 
+1

На самом деле, я не уверен, что это сработает. Предположим, что M = 2, D = 20, Y = 2015. Теперь вы добавляете 10 к «D.» Однако: «В феврале 28 дней ясно». Поэтому дата будет неправильной. –

+0

Однако, * в принципе, * Я думаю, что ваши рассуждения на правильном пути. Я думаю, что OP сначала захочет создать дату-серийное значение (как будет действовать «mktime»). Теперь дата - «просто (один) номер». Итак, используйте другую функцию, чтобы добавить к ней «10 дней». Наконец, при необходимости, декодируйте эту дату в месяц/день/год («печатать ...»). Теперь переход на месяц будет автоматически обрабатываться. –

+0

Привет, Майк, я не уверен, что вы говорите. PHP знает, что нет 30 февраля и делает его 2 марта. Кроме того, я не уверен, почему вам нужно пройти дополнительные шаги, о которых вы упоминаете, конвертируя их в одну сторону, а затем обратно. – Quixrick

0
function working_days($days) { 
    $count = 0; 
    $day = time(); 

    while (true) { 
     if(date('N', $day) < 6) $count++;  
     $day = strtotime('+ 1 days', $day); 
     if($count >= $days) break; 
    } 
    return date('F d Y', $day); 
} 

$ten_days = working_days(10); 

echo ($ten_days); 

Попробуйте это, надеюсь, что это поможет

1

CALCulate трудодни между двумя датами, включая праздники и таможенной рабочей недели

Ответ не так тривиально - таким образом, мое предложение было бы использовать класс, в котором вы можете настроить больше, чем полагаться на упрощенную функцию (или предполагать фиксированный язык и культуру). Для того, чтобы получить дату после определенного количества рабочих дней вы будете:

  1. необходимо указать, какие дни недели вы будете работать (по умолчанию для MON-FRI) - класс позволяет включить или отключить каждый будний день по отдельности.
  2. необходимо знать, что вам необходимо учитывать праздничные дни (страна и штат), чтобы быть точным

Функциональный подход

/** 
* @param days, int 
* @param $format, string: dateformat (if format defined OTHERWISE int: timestamp) 
* @param start, int: timestamp (mktime) default: time() //now 
* @param $wk, bit[]: flags for each workday (0=SUN, 6=SAT) 1=workday, 0=day off 
* @param $holiday, string[]: list of dates, YYYY-MM-DD, MM-DD 
*/ 
function working_days($days, $format='', $start=null, $week=[0,1,1,1,1,1,0], $holiday=[]) 
{ 
    if(is_null($start)) $start = time(); 
    if($days <= 0) return $start; 
    if(count($week) != 7) trigger_error('workweek must contain bit-flags for 7 days'); 
    if(array_sum($week) == 0) trigger_error('workweek must contain at least one workday'); 
    $wd = date('w', $start);//0=sun, 6=sat 
    $time = $start; 
    while($days) 
    { 
     if(
     $week[$wd] 
     && !in_array(date('Y-m-d', $time), $holiday) 
     && !in_array(date('m-d', $time), $holiday) 
     ) --$days; //decrement on workdays 
     $wd = date('w', $time += 86400); //add one day in seconds 
    } 
    $time -= 86400;//include today 
    return $format ? date($format, $time): $time; 
} 

//simple usage 
$ten_days = working_days(10, 'D F d Y'); 
echo '<br>ten workingdays (MON-FRI) disregarding holidays: ',$ten_days; 

//work on saturdays 
$ten_days = working_days(10, 'D F d Y', null, [0,1,1,1,1,1,1]); 
echo '<br>ten workingdays (MON-SAT) disregarding holidays: ',$ten_days; 

//only work on weekends and specify some days off (e.g. tomorrow) 
$ten_days = working_days(10, 'D F d Y', null, [1,0,0,0,0,0,1], ['01-01', date('Y-m-d', time()+86400), '12-25']); 
echo '<br>ten workingdays (MON-FRI) excluding tomorrow and specifying with some holidays: ',$ten_days; 

OO Подход

// usage after including the WorkingDays class below 
// (you can specify holidays, vacation and customize workweeks) 
// WorkingDays::$holiday[] = '12-25'; //add Dec 25th as day off 
// WorkingDays::$sat = 1; //enable working on Saturday 
$date_after_workdays = WorkingDays::fromNow(10); 
echo 'after ten working days it will be ', date('D F d Y', $date_after_workdays); 




/** 
* class to calculate date after certain amount of working days. 
* Depending on location and contract "working days" is very relative. 
* By default this class is assuming standard western office hours. 
* 
* @see http://en.wikipedia.org/wiki/Workweek_and_weekend 
* @see e.g. http://www.timeanddate.com/holidays/ 
* @see e.g. http://www.officeholidays.com/ 
* 
* @usage 
* WorkingDays::$holiday[] = '12-25'; //add Dec 25th as day off 
* WorkingDays::$sat = 1; //enable working on Saturday 
* $date_done = date('F d Y', WorkingDays::fromNow(10)); 
*/ 
class WorkingDays 
{ 
    //workweek definition 
    public static $mon = 1; 
    public static $tue = 1; 
    public static $wed = 1; 
    public static $thu = 1; 
    public static $fri = 1; 
    public static $sat = 0; 
    public static $sun = 0; 

    //use format MM-DD to define non-workingdays (holidays, vacation, etc.) 
    public static $holiday = ['01-01', /* ... */]; 

    /** 
    * @param $start, int: timestamp (time or mktime) 
    * @param $days, int: workingdays from date 
    * @return int: timestamp of date 
    */ 
    public static function from($start, $days) 
    { 
     if($days <= 0) return $start; 
     $wk = [self::$sun, self::$mon, self::$tue, self::$wed, self::$thu, self::$fri, self::$sat]; 
     if(array_sum($wk) == 0) trigger_error('workweek must contain at least one workday'); 
     $wd = date('w', $start);//0=sun, 6=sat 
     $time = $start; 
     while($days) 
     { 
      if($wk[$wd] && !in_array(date('m-d', $time), self::$holiday)) --$days; //decrement on workdays 
      $wd = date('w', $time += 86400); //add one day in seconds 
     } 
     $time -= 86400;//include today 
     return $time; 
    } 

    /** 
    * "today" is included (if it is a workday) 
    */ 
    public static function fromNow($days) 
    { 
     return self::from(time(), $days); 
    } 
} 
+1

Пожалуйста, добавьте объяснение в свой ответ. – MChaker

Смежные вопросы