查找给定日期之前的三个工作日

Tat*_*nen 6 php date

我需要在给定日期找到前三个工作日,省略周末和假日.这本身并不是一项艰巨的任务,但似乎我要做的事情会过于复杂,所以我想我先问你的意见.

为了让事情变得更有趣,让我们把它作为一个比赛.我提供300作为赏金,无论谁提出符合此规范的最短,最干净的解决方案:

  • 编写一个函数,返回给定日期之前的三个工作日
  • 工作日定义为星期六或星期日并且不是假日的任何一天
  • 该函数知道给定日期年份的假期,并可以考虑这些假期
  • 该函数以Y-m-d格式接受一个参数,即日期
  • 该函数返回一个Y-m-d格式为三个日期的数组,从最旧到最新排序.

额外:

  • 除了前三个工作日之外,该功能还可以找到接下来的三个工作日

假期数组的一个例子:

$holidays = array(
    '2010-01-01',
    '2010-01-06',
    '2010-04-02',
    '2010-04-04',
    '2010-04-05',
    '2010-05-01',
    '2010-05-13',
    '2010-05-23',
    '2010-06-26',
    '2010-11-06',
    '2010-12-06',
    '2010-12-25',
    '2010-12-26'
);
Run Code Online (Sandbox Code Playgroud)

请注意,在实际场景中,假期不是硬编码,而是来自get_holidays($year)功能.如果您愿意,可以在答案中包含/使用它.

因为我正在提供赏金,这意味着至少还有三天我可以将答案标记为已接受(2天可以加上赏金,1天直到我可以接受).


注意

如果你使用固定的日长度(如86400秒)从白天跳到另一个,那么夏令时会遇到问题.请strtotime('-1 day', $timestamp)改用.

这个问题的一个例子:

http://codepad.org/uSYiIu5w


最终解决方案

下面是最终的解决方案,我结束了使用,改编自使用的基思·明克勒的想法strtotimelast weekday.检测通过计数的方向,如果为负,则向后搜索,并向前搜索:

function working_days($date, $count) {

    $working_days = array();
    $direction    = $count < 0 ? 'last' : 'next';
    $holidays     = get_holidays(date("Y", strtotime($date)));

    while(count($working_days) < abs($count)) {
        $date = date("Y-m-d", strtotime("$direction weekday", strtotime($date)));
        if(!in_array($date, $holidays)) {
            $working_days[] = $date;
        }
    }

    sort($working_days);
    return $working_days;
}
Run Code Online (Sandbox Code Playgroud)

Wir*_*lue 10

这应该做的伎俩:

    // Start Date must be in "Y-m-d" Format
    function LastThreeWorkdays($start_date) {
        $current_date = strtotime($start_date);
        $workdays = array();
        $holidays = get_holidays('2010');

        while (count($workdays) < 3) {
            $current_date = strtotime('-1 day', $current_date);

            if (in_array(date('Y-m-d', $current_date), $holidays)) {    
                // Public Holiday, Ignore.
                continue;
            }

            if (date('N', $current_date) < 6) {
                // Weekday. Add to Array.
                $workdays[] = date('Y-m-d', $current_date);
            }
        }

        return array_reverse($workdays);
    }
Run Code Online (Sandbox Code Playgroud)

我在get_holidays()函数中进行了硬编码,但我确信你会得到这个想法并调整它以适应.其余的都是工作代码.


小智 8

您可以在strtotime中使用"last weekday"或"next thursday"等表达式,例如:

function last_working_days($date, $backwards = true)
{
    $holidays = get_holidays(date("Y", strtotime($date)));

    $working_days = array();

    do
    {
        $direction = $backwards ? 'last' : 'next';
        $date = date("Y-m-d", strtotime("$direction weekday", strtotime($date)));
        if (!in_array($date, $holidays))
        {
            $working_days[] = $date;
        }
    }
    while (count($working_days) < 3);

    return $working_days;
}
Run Code Online (Sandbox Code Playgroud)