#yyphp-quiz
No.2: 月間カレンダーの表を作ろう<?php
/**
* 月間カレンダーの表を生成して返す
* @param int $first その月の1日の曜日番号。日=0、月=1、火=2、水=3、木=4、金=5、土=6
* @param int $days その月の日数。30、31、28もしくは29
* @return array 下記のような月間カレンダーを配列で返す
* - 週ごとにひとつの配列にする。
* - 週の配列は日曜日から土曜日の7要素が必ずある。
* - 週の配列の中身は日付。
* - 週の配列の中で中で前月や次月の日付になる日は0で埋める。
* 例:
* $calendar = getCalendarTable(1, 30);
* この場合、$calendarの値は次のようになる:
* [
* [ 0, 1, 2, 3, 4, 5, 6],
* [ 7, 8, 9, 10, 11, 12, 13],
* [14, 15, 16, 17, 18, 19, 20],
* [21, 22, 23, 24, 25, 26, 27],
* [28, 29, 30, 0, 0, 0, 0],
* ]
*/
function getCalendarTable(int $first, int $days): array
{
// todo: 日付関係の関数、クラス、ライブラリを使わずに実装してみて
}
// テストコード
assert(
getCalendarTable(0, 28) === [
[ 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14],
[15, 16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27, 28],
],
'1日が日曜日で28日間ある月'
);
assert(
getCalendarTable(0, 31) === [
[ 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14],
[15, 16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27, 28],
[29, 30, 31, 0, 0, 0, 0],
],
'1日が日曜日で31日間ある月'
);
assert(
getCalendarTable(1, 30) === [
[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 0, 0, 0, 0],
],
'1日が月曜日で30日間ある月'
);
assert(
getCalendarTable(4, 30) === [
[ 0, 0, 0, 0, 1, 2, 3],
[ 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30, 0],
],
'1日が木曜日で30日間ある月'
);
assert(
getCalendarTable(4, 31) === [
[ 0, 0, 0, 0, 1, 2, 3],
[ 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30, 31],
],
'1日が木曜日で31日間ある月'
);
assert(
getCalendarTable(5, 31) === [
[ 0, 0, 0, 0, 0, 1, 2],
[ 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16],
[17, 18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29, 30],
[31, 0, 0, 0, 0, 0, 0],
],
'1日が金曜日で31日ある月'
);
function getCalendarTable(int $first, int $days): array
{
$calendar = [];
$numberOfWeeks = ceil(($first + $days) / 7);
$date = 1 - $first;
for ($y = 0; $y < $numberOfWeeks; $y++) {
for ($x = 0; $x < 7; $x++, $date++) {
$calendar[$y][$x] = 1 <= $date && $date <= $days ? $date : 0;
}
}
return $calendar;
}
function getCalendarTable(int $first, int $days): array
{
return array_chunk(
array_merge(
array_fill(0, $first, 0),
range(1, $days),
array_fill(0, (7 - (($first + $days) % 7)) % 7, 0)
),
7
);
}
function getCalendarTable(int $first, int $days): array
{
return array_chunk(
array_map(
function (int $date) use ($days): int {
return 1 <= $date && $date <= $days ? $date : 0;
},
range(1 - $first, (ceil(($first + $days) / 7) * 7) - $first)
)
, 7
);
}
function getCalendarTable(int $first, int $days): array
{
$lastMonthDaysCount = $first;
$nextMonthDaysCount = ($first + $days) % 7 === 0 ? 0 : 7 - (($first + $days) % 7);
$lastMonthDays = [];
for ($i = 1; $i <= $lastMonthDaysCount; $i++) {
$lastMonthDays[] = 0;
}
$thisMonthDays = [];
for ($day = 1; $day <= $days; $day++) {
$thisMonthDays[] = $day;
}
$nextMonthDays = [];
for ($i = 1; $i <= $nextMonthDaysCount; $i++) {
$nextMonthDays[] = 0;
}
$flatCalendar = [];
foreach ($lastMonthDays as $day) $flatCalendar[] = $day;
foreach ($thisMonthDays as $day) $flatCalendar[] = $day;
foreach ($nextMonthDays as $day) $flatCalendar[] = $day;
$calendar = [];
$week = [];
for ($i = 0; $i < count($flatCalendar); $i++) {
$week[] = $flatCalendar[$i];
if (($i + 1) % 7 === 0) {
$calendar[] = $week;
$week = [];
}
}
return $calendar;
}
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing