私が正しく数えれば、2013年には53週間を考慮する必要があります。
- 01週目->FROM:2013-01-01(火曜日)TO:2013-01-04(金曜日)
- 02週目->FROM:2013-01-07(月曜日)TO:2013-01-11(金曜日)
- 03週目->FROM:2013-01-14(月曜日)TO:2013-01-18(金曜日)
- 04週目->FROM:2013-01-21(月曜日)TO:2013-01-25(金曜日)
- 05週目->FROM:2013-01-28(月曜日)TO:2013-02-01(金曜日)
- 06週目->FROM:2013-02-04(月曜日)TO:2013-02-08(金曜日)
- 07週目->FROM:2013-02-11(月曜日)TO:2013-02-15(金曜日)
- 08週目->FROM:2013-02-18(月曜日)TO:2013-02-22(金曜日)
- 09週目->FROM:2013-02-25(月)TO:2013-03-01(金)
- 10週目->FROM:2013-03-04(月曜日)TO:2013-03-08(金曜日)
- 11週目->FROM:2013-03-11(月曜日)TO:2013-03-15(金曜日)
- 12週目->FROM:2013-03-18(月曜日)TO:2013-03-22(金曜日)
- 13週目->FROM:2013-03-25(月曜日)TO:2013-03-29(金曜日)
- 14週目->FROM:2013-04-01(月曜日)TO:2013-04-05(金曜日)
- 15週目->FROM:2013-04-08(月曜日)TO:2013-04-12(金曜日)
- 16週目->FROM:2013-04-15(月曜日)TO:2013-04-19(金曜日)
- 17週目->FROM:2013-04-22(月曜日)TO:2013-04-26(金曜日)
- 18週目->FROM:2013-04-29(月曜日)TO:2013-05-03(金曜日)
- 19週目->FROM:2013-05-06(月曜日)TO:2013-05-10(金曜日)
- 20週目->FROM:2013-05-13(月曜日)TO:2013-05-17(金曜日)
- 21週目->FROM:2013-05-20(月曜日)TO:2013-05-24(金曜日)
- 22週目->FROM:2013-05-27(月曜日)TO:2013-05-31(金曜日)
- 23週目->FROM:2013-06-03(月曜日)TO:2013-06-07(金曜日)
- 24週目->FROM:2013-06-10(月曜日)TO:2013-06-14(金曜日)
- 25週目->FROM:2013-06-17(月曜日)TO:2013-06-21(金曜日)
- 26週目->FROM:2013-06-24(月曜日)TO:2013-06-28(金曜日)
- 27週目->FROM:2013-07-01(月曜日)TO:2013-07-05(金曜日)
- 28週目->FROM:2013-07-08(月曜日)TO:2013-07-12(金曜日)
- 29週目->FROM:2013-07-15(月曜日)TO:2013-07-19(金曜日)
- 30週目->FROM:2013-07-22(月曜日)TO:2013-07-26(金曜日)
- 31週目->FROM:2013-07-29(月曜日)TO:2013-08-02(金曜日)
- 32週目->FROM:2013-08-05(月曜日)TO:2013-08-09(金曜日)
- 33週目->FROM:2013-08-12(月曜日)TO:2013-08-16(金曜日)
- 34週目->FROM:2013-08-19(月曜日)TO:2013-08-23(金曜日)
- 35週目->FROM:2013-08-26(月曜日)TO:2013-08-30(金曜日)
- 36週目->FROM:2013-09-02(月曜日)TO:2013-09-06(金曜日)
- 37週目->FROM:2013-09-09(月曜日)TO:2013-09-13(金曜日)
- 38週目->FROM:2013-09-16(月曜日)TO:2013-09-20(金曜日)
- 39週目->FROM:2013-09-23(月曜日)TO:2013-09-27(金曜日)
- 40週目->FROM:2013-09-30(月曜日)TO:2013-10-04(金曜日)
- 41週目->FROM:2013-10-07(月曜日)TO:2013-10-11(金曜日)
- 42週目->FROM:2013-10-14(月曜日)TO:2013-10-18(金曜日)
- 43週目->FROM:2013-10-21(月曜日)TO:2013-10-25(金曜日)
- 44週目->FROM:2013-10-28(月曜日)TO:2013-11-01(金曜日)
- 45週目->FROM:2013-11-04(月曜日)TO:2013-11-08(金曜日)
- 46週目->FROM:2013-11-11(月曜日)TO:2013-11-15(金曜日)
- 47週目->FROM:2013-11-18(月曜日)TO:2013-11-22(金曜日)
- 48週目->FROM:2013-11-25(月曜日)TO:2013-11-29(金曜日)
- 49週目->FROM:2013-12-02(月曜日)TO:2013-12-06(金曜日)
- 50週目->FROM:2013-12-09(月曜日)TO:2013-12-13(金曜日)
- 51週目->FROM:2013-12-16(月曜日)TO:2013-12-20(金曜日)
- 52週目->FROM:2013-12-23(月曜日)TO:2013-12-27(金曜日)
- 01週目->FROM:2013-12-30(月曜日)TO: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の今後のジェネレーター機能を利用すると、開始日と終了日がない週を非常に簡単にフィルターで除外できるため、これらすべてを、毎週FROMでのみ返されるイテレーターにラップします(if利用可能)および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。