如果我算对的话,2013 年你需要考虑 53 周:
- 第 1 周 --> 从:2013 年 1 月 1 日(星期二)到:2013 年 1 月 4 日(星期五)
- 第 2 周 --> 从:2013 年 1 月 7 日(星期一)到:2013 年 1 月 11 日(星期五)
- 第 3 周 --> 从:2013 年 1 月 14 日(星期一)到:2013 年 1 月 18 日(星期五)
- 第 4 周 --> 从:2013 年 1 月 21 日(星期一)到:2013 年 1 月 25 日(星期五)
- 第 5 周 --> 从:2013-01-28(星期一)到:2013-02-01(星期五)
- 第 6 周 --> 从:2013 年 2 月 4 日(星期一)到:2013 年 2 月 8 日(星期五)
- 第 7 周 --> 从:2013 年 2 月 11 日(星期一)到:2013 年 2 月 15 日(星期五)
- 第 8 周 --> 从:2013 年 2 月 18 日(星期一)到:2013 年 2 月 22 日(星期五)
- 第 9 周 --> 从:2013 年 2 月 25 日(星期一)到:2013 年 3 月 1 日(星期五)
- 第 10 周 --> 从:2013-03-04(星期一)到:2013-03-08(星期五)
- 第 11 周 --> 从:2013-03-11(星期一)到:2013-03-15(星期五)
- 第 12 周 --> 从:2013-03-18(星期一)到:2013-03-22(星期五)
- 第 13 周 --> 从:2013 年 3 月 25 日(星期一)到:2013 年 3 月 29 日(星期五)
- 第 14 周 --> 从:2013-04-01(星期一)到:2013-04-05(星期五)
- 第 15 周 --> 从:2013-04-08(星期一)到:2013-04-12(星期五)
- 第 16 周 --> 从:2013-04-15(星期一)到:2013-04-19(星期五)
- 第 17 周 --> 从:2013-04-22(星期一)到:2013-04-26(星期五)
- 第 18 周 --> 从:2013 年 4 月 29 日(星期一)到:2013 年 5 月 3 日(星期五)
- 第 19 周 --> 从:2013-05-06(星期一)到:2013-05-10(星期五)
- 第 20 周 --> 从:2013-05-13(星期一)到:2013-05-17(星期五)
- 第 21 周 --> 从:2013 年 5 月 20 日(星期一)到:2013 年 5 月 24 日(星期五)
- 第 22 周 --> 从:2013-05-27(星期一)到:2013-05-31(星期五)
- 第 23 周 --> 从:2013-06-03(星期一)到:2013-06-07(星期五)
- 第 24 周 --> 从:2013 年 6 月 10 日(星期一)到:2013 年 6 月 14 日(星期五)
- 第 25 周 --> 从:2013-06-17(星期一)到:2013-06-21(星期五)
- 第 26 周 --> 从:2013 年 6 月 24 日(星期一)到:2013 年 6 月 28 日(星期五)
- 第 27 周 --> 从:2013-07-01(星期一)到:2013-07-05(星期五)
- 第 28 周 --> 从:2013-07-08(星期一)到:2013-07-12(星期五)
- 第 29 周 --> 从:2013-07-15(星期一)到:2013-07-19(星期五)
- 第 30 周 --> 从:2013 年 7 月 22 日(星期一)到:2013 年 7 月 26 日(星期五)
- 第 31 周 --> 从:2013 年 7 月 29 日(星期一)到:2013 年 8 月 2 日(星期五)
- 第 32 周 --> 从:2013-08-05(星期一)到:2013-08-09(星期五)
- 第 33 周 --> 从:2013-08-12(星期一)到:2013-08-16(星期五)
- 第 34 周 --> 从:2013 年 8 月 19 日(星期一)到:2013 年 8 月 23 日(星期五)
- 第 35 周 --> 从:2013 年 8 月 26 日(星期一)到:2013 年 8 月 30 日(星期五)
- 第 36 周 --> 从:2013-09-02(星期一)到:2013-09-06(星期五)
- 第 37 周 --> 从:2013 年 9 月 9 日(星期一)到:2013 年 9 月 13 日(星期五)
- 第 38 周 --> 从:2013 年 9 月 16 日(星期一)到:2013 年 9 月 20 日(星期五)
- 第 39 周 --> 从:2013 年 9 月 23 日(星期一)到:2013 年 9 月 27 日(星期五)
- 第 40 周 --> 从:2013 年 9 月 30 日(星期一)到:2013 年 10 月 4 日(星期五)
- 第 41 周 --> 从:2013 年 10 月 7 日(星期一)到:2013 年 10 月 11 日(星期五)
- 第 42 周 --> 从:2013 年 10 月 14 日(星期一)到:2013 年 10 月 18 日(星期五)
- 第 43 周 --> 从:2013 年 10 月 21 日(星期一)到:2013 年 10 月 25 日(星期五)
- 第 44 周 --> 从:2013 年 10 月 28 日(星期一)到:2013 年 11 月 1 日(星期五)
- 第 45 周 --> 从:2013 年 11 月 4 日(星期一)到:2013 年 11 月 8 日(星期五)
- 第 46 周 --> 从:2013 年 11 月 11 日(星期一)到:2013 年 11 月 15 日(星期五)
- 第 47 周 --> 从:2013-11-18(星期一)到:2013-11-22(星期五)
- 第 48 周 --> 从:2013 年 11 月 25 日(星期一)到:2013 年 11 月 29 日(星期五)
- 第 49 周 --> 从:2013 年 12 月 2 日(星期一)到:2013 年 12 月 6 日(星期五)
- 第 50 周 --> 从:2013 年 12 月 9 日(星期一)到:2013 年 12 月 13 日(星期五)
- 第 51 周 --> 从:2013 年 12 月 16 日(星期一)到:2013 年 12 月 20 日(星期五)
- 第 52 周 --> 从:2013 年 12 月 23 日(星期一)到:2013 年 12 月 27 日(星期五)
- 第 1 周 --> 从:2013 年 12 月 30 日(星期一)到:2013 年 12 月 31 日(星期二)
您可以通过使用DatePeriod
该类来获得这样的列表,它非常灵活。
我做了以下(伪代码):
for each $monday [
in the period starting from the first day of the first week of 2013
with an interval of one week
until 2013-12-31 23:59:59
] do: {
output "X. Week XX --> "
for each $day [
in the period starting from $monday
with an interval of one day
repeated four times
] | [
filter all days not having the year
] | [
filter out the first and last
] {
output
"FROM" if has next "TO" otherwise
": " format($date, "Y-m-d (l)")
}
}
正如这段代码所示,我已经使用迭代器解决了这个问题。DatePeriod
已经是可遍历的,但我还需要一个DatePeriodYearFilter
来过滤特定年份的日期(请参阅FilterIterator
所需的FirstAndLastIterator
,这基本上是CachingIterator
.
示例代码:
$year = 2013;
$weeksPeriod = new DatePeriod(
new DateTime("$year-W01-1"),
new DateInterval('P1W'),
new DateTime("$year-12-31T23:59:59Z")
);
foreach ($weeksPeriod as $week => $monday) {
$daysPeriod = new DatePeriod($monday, new DateInterval('P1D'), 4);
$daysFiltered = new DatePeriodYearFilter($daysPeriod, $year);
$days = new FirstAndLastIterator($daysFiltered);
printf(" 1. Week %s --> ", $monday->format('W'));
foreach ($days as $day => $date) {
$label = $days->hasNext() ? 'FROM' : 'TO';
printf("%s: %s ", $label, $date->format('Y-m-d (l)'));
}
echo "\n";
}
利用 PHP 5.5 的 upcomming 生成器功能,甚至可以很容易地过滤掉没有的周以及以迭代方式开始和结束日期,因此将所有这些包装到一个迭代器中,该迭代器每周只返回 FROM(如果可用)和 TO 日期。
在 PHP 5.4 中,这可以模拟为进行一些数组转换,这似乎也可以,因为这大约没有那么多条目。这里的示例代码:
$workdaysOfWeekForMonday = function(DateTime $monday) use ($year) {
$daysPeriod = new DatePeriod($monday, new DateInterval('P1D'), 4);
$daysFiltered = new DatePeriodYearFilter($daysPeriod, $year);
$days = new FirstAndLastIterator($daysFiltered);
return array_map(function(DateTime $date) {return $date->format('Y-m-d (l)');}, iterator_to_array($days, false));
};
$result = array_filter(array_map($workdaysOfWeekForMonday, iterator_to_array($weeksPeriod)));
print_r($result);
结果(缩短,这里是 2017 年的典范,上周是真实的,没有工作日,现在经过适当过滤):
Array
(
[0] => Array
(
[0] => 2017-01-02 (Monday)
[1] => 2017-01-06 (Friday)
)
[1] => Array
(
[0] => 2017-01-09 (Monday)
[1] => 2017-01-13 (Friday)
)
[2] => Array
(
[0] => 2017-01-16 (Monday)
[1] => 2017-01-20 (Friday)
)
...
[49] => Array
(
[0] => 2017-12-11 (Monday)
[1] => 2017-12-15 (Friday)
)
[50] => Array
(
[0] => 2017-12-18 (Monday)
[1] => 2017-12-22 (Friday)
)
[51] => Array
(
[0] => 2017-12-25 (Monday)
[1] => 2017-12-29 (Friday)
)
)
这里是我为这些示例添加的迭代器代码:Gist。