查找一个月的每周周期(从星期一开始)

wat*_*att 1 php time duration period week-number

我正在尝试查找给定月份和年份的每周周期。日期应从星期一开始,到星期日结束。如果该月的 1 号是星期日(2011 年 5 月之前),则它应该是第一个元素。

\n\n

2011年5月

\n\n
    \n
  • 5月1日(星期日)
  • \n
  • 5月2日至5月8日(周一至周日)
  • \n
  • 5月9日至5月15日(周一至周日)
  • \n
  • 5 月 17 日 - 5 月 22 日(星期一 - 星期日)
  • \n
  • 5月23日至5月29日(周一至周日)
  • \n
  • 5月30日至5月31日(周一至周二)
  • \n
\n\n

2012年9月

\n\n
    \n
  • 9 月 1 日至 9 月 2 日
  • \n
  • 9 月 3 日至 9 月 9 日
  • \n
  • 9月10日 - 9月16日
  • \n
  • 9月17日 - 9月23日
  • \n
  • 9月24日 - 9月30日
  • \n
\n\n

我使用此函数来计算两个日期的周数 - 即该月的第一天和该月的最后一天。

\n\n
public function getWeekNumbers($startDate, $endDate)\n{\n    $p = new DatePeriod(\n            new DateTime($startDate),\n            new DateInterval(\'P1W\'),\n            new DateTime($endDate)\n    );\n\n    $weekNumberList = array();\n\n    foreach ($p as $w)\n    {\n        $weekNumber = $w->format(\'W\');\n        $weekNumberList[] = ltrim($weekNumber, \'0\');\n    }\n\n    return $weekNumberList;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

奇怪的是,对于一月份,当我期望 [1, 2, 3, 4, 5] 时,它返回周数 [52, 1, 2, 3, 4]。

\n\n

一旦我有了周数,我就会像这样使用它们:

\n\n
//The following loop will populate the dataset with the entire month\'s durations - regardless if hours were worked or not.\n    $firstDayOfMonth = date(\'Y-m-d\', strtotime("first day of {$this->year}-{$monthName}"));\n    $lastDayOfMonth = date(\'Y-m-d\', strtotime("last day of {$this->year}-{$monthName}"));\n\n    foreach ($this->getWeekNumbers($firstDayOfMonth, $lastDayOfMonth) as $key => $weekId)\n    {\n        // find first m\xd0\xbenday of the year\n        $firstMon = strtotime("mon jan {$this->year}");\n\n        // calculate how many weeks to add\n        $weeksOffset = $weekId - date(\'W\', $firstMon);\n\n        $beginDays = $weeksOffset * 7;\n        $endDays = ($weeksOffset * 7) + 6;\n\n        $searchedMon = strtotime(date(\'Y-m-d\', $firstMon) . " +{$beginDays} days");\n        $searchedSun = strtotime(date(\'Y-m-d\', $firstMon) . " +{$endDays} days");\n\n        echo date("M d", $searchedMon) . " - " . date("M d", $searchedSun);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于 getWeekNumbers 函数没有返回我期望的周数,因此上述函数的输出为

\n\n
    \n
  • 12月24日 - 12月30日 (2012年)
  • \n
  • 1 月 2 日 - 1 月 8 日 (2012)
  • \n
  • 1 月 9 日 - 1 月 15 日 (2012)
  • \n
  • 1 月 16 日 - 1 月 22 日 (2012)
  • \n
  • 1 月 23 日 - 1 月 29 日 (2012)
  • \n
\n\n

请注意,第一行(12 月 24 日至 12 月 30 日)是本年度 (2012 年) 的年底,而不是去年 (2011 年) 的年底。

\n\n

理想情况下,我希望它看起来像在此输入图像描述

\n\n

有任何想法吗?谢谢!!

\n

Gla*_*vić 5

如果您需要所选月份的所有周以及所选周的所有日期,那么这就是您所需要的:

function getWeekDays($month, $year)
{
    $p = new DatePeriod(
        DateTime::createFromFormat('!Y-n-d', "$year-$month-01"),
        new DateInterval('P1D'),
        DateTime::createFromFormat('!Y-n-d', "$year-$month-01")->add(new DateInterval('P1M'))
    );

    $datesByWeek = array();
    foreach ($p as $d) {
        $dateByWeek[ $d->format('W') ][] = $d;
    }
    return $dateByWeek;
}
Run Code Online (Sandbox Code Playgroud)

getWeekDays() 函数返回多维数组。第一个键是周数。2 级是数组,将日期保存为 DateTime 对象。

获取示例:

print_r( getWeekDays(5, 2011) ); # May 2011
print_r( getWeekDays(9, 2012) ); # Sep 2012
Run Code Online (Sandbox Code Playgroud)

我有一点额外的时间,所以我写了一个例子;-)

$datesByWeek = getWeekDays(8, 2012);
$o = '<table border="1">';
$o.= '<tr><th>Week</th><th>Monday</th><th>Tuesday</th><th>Wednesday</th><th>Thursday</th><th>Friday</th><th>Saturday</th><th>Sunday</th></tr>';
foreach ($datesByWeek as $week => $dates) {
    $firstD = $dates[0];
    $lastD = $dates[count($dates)-1];

    $o.= "<tr>";
    $o.= "<td>" . $firstD->format('M d') . ' - ' . $lastD->format('M d') . "</td>";
    $N = $firstD->format('N');
    for ($i = 1; $i < $N; $i++) {
        $o.= "<td>-</td>";
    }
    foreach ($dates as $d) {
        $o.= "<td>" . $d->format('d.') . " / 0.00</td>";
            # for selected date do you magic
    }
    $N = $lastD->format('N');
    for ($i = $N; $i < 7; $i++) {
        $o.= "<td>-</td>";
    }
    $o.= "</tr>";
}
$o.= '</table>';
echo $o;
Run Code Online (Sandbox Code Playgroud)

输出看起来像: 在此输入图像描述

  • 哇——这太完美了!非常感谢您的时间和精力。 (2认同)