pro*_*out 2 php algorithm date
我目前正在生成一个 html 表,其中包含标题中的日期
这些日期据称是全年每周的第一天(显示的年份可能会根据过滤器发生变化),它们是由以下代码生成的
<?php $firstDay = strtotime($year . 'W' . str_pad($week, 2, '0', STR_PAD_LEFT)); ?>
<td><?= date('d/m/Y', $firstDay) ?></td>
Run Code Online (Sandbox Code Playgroud)
这是一个for循环,它使$week从 变为1全年的周数。
我注意到,有些年来,前一年 12 月的最后一个星期一也包含在其中,例如29/12/2014当我2015在过滤器中选择时。
到目前为止,为了确定一个月中的周数,我曾经以编程方式计算该月中星期一的数量,并将其用作日期行上方行的 colspan,因此,一月有无数周多年来,这使得桌子发生了变化。
今年渲染的 html2015看起来像这样
<table>
<thead>
<tr>
<th colspan="4">January</th>
<th colspan="4">February</th>
[...]
</tr>
<tr>
<!-- Under January cell -->
<th>29/12/2014</th>
<th>05/01/2015</th>
<th>12/01/2015</th>
<th>19/01/2015</th>
<!-- Under February cell -->
<th>26/01/2015</th>
<th>02/02/2015</th>
[...]
</tr>
</thead>
[...]
Run Code Online (Sandbox Code Playgroud)
在搜索和测试了很多周每月计数器之后,我发现的这些计数器似乎都不包括上一年的上周一。
谁能找出如何计算周数,包括上一年发生的额外一周?
给定月份中的周数基本上是一个月中的天数,加上取决于该月开始于一周中的哪一天的偏移量,除以 7。以下是使用 DateInterval 和 DatePeriod的解决方案:
/**
* Get number of weeks starting *Monday*, occuring in a given month.
* A week occurs in a month if any day from that week falls in the month.
* @param $month_date is expected to be DateTime.
* @param $count_last count partial week at the end of month as part of month.
*/
function weeks_in_month($month_date, $count_last=true) {
$fn = $count_last ? 'ceil' : 'floor';
$start = new DateTime($month_date->format('Y-m'));
$days = (clone $start)->add(new DateInterval('P1M'))->diff($start)->days;
$offset = $month_date->format('N') - 1;
return $fn(($days + $offset)/7);
}
/**
* Wrapper over weeks_in_month() to get weeks in month for each month of a given year.
* @param $year_date is expected to be a DateTime.
*/
function year_month_weeks($year_date, $count_last=true) {
$start = new DateTime($year_date->format('Y') . '-01');
$year_month_weeks = [];
foreach(new DatePeriod($start, new DateInterval('P1M'), 11) as $month) {
$year_month_weeks[] += weeks_in_month($month, $count_last);
}
return $year_month_weeks;
}
print_r(year_month_weeks(new DateTime('2008-01'), true));
Run Code Online (Sandbox Code Playgroud)
给出:
Array
(
[0] => 5
[1] => 5
[2] => 6
[3] => 5
[4] => 5
[5] => 6
[6] => 5
[7] => 5
[8] => 5
[9] => 5
[10] => 5
[11] => 5
)
Run Code Online (Sandbox Code Playgroud)
这可以根据 的输出进行验证cal。2008 年前 6 个月,3 月、6 月应有 6 周,其余 5 周:
>ncal -Mb -m 1 -A 5 2008
2008
January February March
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 1 2 3 1 2
7 8 9 10 11 12 13 4 5 6 7 8 9 10 3 4 5 6 7 8 9
14 15 16 17 18 19 20 11 12 13 14 15 16 17 10 11 12 13 14 15 16
21 22 23 24 25 26 27 18 19 20 21 22 23 24 17 18 19 20 21 22 23
28 29 30 31 25 26 27 28 29 24 25 26 27 28 29 30
31
April May June
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 1 2 3 4 1
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
30
Run Code Online (Sandbox Code Playgroud)