如何找到本月的最后一个星期一

时间:2011-06-25 15:47:12

标签: php

我不知道该如何解决这个问题。我正在使用PHP构建日历,并且需要用户能够添加遵循以下规则的重复事件:

本月的最后[DOW](所以最后一周[周一/周二/周三/周])

我已经存储了规则本身,我只是不确定如何最好地推断PHP中当月的最后一个周一/周二/周三?我觉得这让它变得比它需要的更复杂。

假设您有$month=4$dow=3$year=2011的变量,我最好怎么做?

3 个答案:

答案 0 :(得分:25)

对于与日期相关的所有内容,您可以用正确的英语表达,但很难用数字表达,strtotime是您最好的朋友。

echo strtotime("last Monday of June 2011");

这将返回一个时间戳,您可以将其用作date的第二个参数,以及获得正确的,人类可读日期的喜欢。因为它是用C编写的内置函数,所以这个解决方案也比你用PHP编写的其他任何东西都要快得多(虽然我很确定它在现实场景中并不重要)。

假设您有$month=4$dow=3$year=2011,则需要将数组映射$month值映射到其英文文本表示形式,并将另一个数组映射{{1值到他们的文本表示。

答案 1 :(得分:0)

我有一个通用函数来计算一个月的第n天。希望这可以帮助您解决问题。

function get_Nth_dow($dow, $occurence, $m, $y)
{
    $numdays = date('t', mktime(0, 0, 0, $m, 1, $y));
    $add = 7 * ($occurence - 1);
    $firstdow = date('w', mktime(0, 0, 0, $m, 1, $y));
    $diff = $firstdow - $dow;

    $day_of_month = 1;
    if ($diff > 0)
    {
        $day_of_month += ($add - $diff);
    }
    elseif ($diff < $numdays)
    {
        $day_of_month -= ($diff - $add);
    }

    return $day_of_month;
}

$DOW =星期几(0 =星期日,6 =星期六)。

$X =出现(1 =第一,2 =第三等)。如果给定月份

没有发生,那么它将返回最后一个。例如,如果

你要求星期五发生第7次,它将返回最后一次

本月的星期五。 $M =月 $Y =年

示例,get_Nth_DOW(2,3,7,2009)将返回2009年第7个星期二。

答案 2 :(得分:0)

这是另一种选择:

<?
function lastDayOfMonth($month, $year) {
    switch ($month) {
        case 2:
            # if year is divisible by 4 and not divisible by 100
            if (($year % 4 == 0) && ($year % 100) > 0)
                return 29;
            # or if year is divisible by 400
            if ($year % 400 == 0)
                return 29;
            return 28;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30; 
        default:
            return 31;
    }
}

function lastDayOfWeek($month, $year, $dow) {
    $d = new DateTime();

    #Finding the last day of month
    $d = $d->setDate($year, $month, lastDayOfMonth($month, $year));

    #Getting the day of week of last day of month
    $date_parts = getdate($d->getTimestamp());

    $diff = 0;

    #if we can't find the $dow in this week... (cause it would lie on next month)
    if ($dow > $date_parts['wday']) {
        # ...we go back a week.
        $diff -= 7;
    }

    return $date_parts['mday'] + $diff + ($dow - $date_parts['wday']);  
}

# checking the algorithm for this month...
for ($i=0; $i < 7; $i++) {
    echo lastDayOfWeek(6,2011,$i) . "<br>";
}

?>