Robson » Little Red Book » Calendar

Chapter 7 - Question 15

Given that January 1st, 1900 was a Monday, design a program that will accept as input any year between 1900 and 2100 and output a calendar for that year.

Solution 1

I've decided to restrict the years to 1971 to 2038 so I can use the Unix timestamp functions.

`<?`
`    // choose a random year for the calendar`
`    \$year = mt_rand(1971, 2037);`
` `
`    // loop through each month`
`    for (\$m = 1; \$m <= 12; \$m++)`
`    {`
`        // output the start of the table showing the month and the first letter of each day`
`        \$month_html[\$m] = '<td style="border:0;vertical-align:top">`
`        <table><tr><th colspan="7">' . date(F, mktime(1, 1, 1, \$m, 1, \$year)) .`
`        '</th></tr><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>';`
` `
`        // check if the first day of the month wasn't a monday`
`        if (date(D, mktime(1, 1, 1, \$m, 1, \$year)) <> 'Mon')`
`            // if not, add in a blank cell to occupy the days of the week before the first day`
`            \$month_html[\$m] .= '<td colspan="' . date(w, mktime(1, 1, 1, \$m, 0, \$year)) . '"></td>';            `
`            `
`        // loop through each day`
`        for (\$d = 1; \$d <= date(t, mktime(1, 1, 1, \$m, 1, \$year)); \$d++)`
`        {`
`            // check if this is not the first day, but is a monday`
`            if (\$d > 1 && date(D, mktime(1, 1, 1, \$m, \$d, \$year)) == 'Mon')`
`                // output a new row`
`                \$month_html[\$m] .= '</tr><tr>';`
`                `
`            // output the day number in a cell`
`            \$month_html[\$m] .= '<td>' . \$d . '</td>';`
`        }`
`        // finish off the table for this month    `
`        \$month_html[\$m] .= '</tr></table></td>';`
`    }`
`    `
`    // output the calendar with each month (4x3)`
`    echo '<table><caption>Calendar for ' . \$year . '</caption>`
`<tr>' . \$month_html[1] . \$month_html[2] . \$month_html[3] . \$month_html[4] . '</tr>`
`<tr>' . \$month_html[5] . \$month_html[6] . \$month_html[7] . \$month_html[8] . '</tr>`
`<tr>' . \$month_html[9] . \$month_html[10] . \$month_html[11] . \$month_html[12] . '</tr>`
`</table>';`
`?>`

Which produces:

Calendar for 2027
January
MTWTFSS
123
45678910
11121314151617
18192021222324
25262728293031
February
MTWTFSS
1234567
891011121314
15161718192021
22232425262728
March
MTWTFSS
1234567
891011121314
15161718192021
22232425262728
293031
April
MTWTFSS
1234
567891011
12131415161718
19202122232425
2627282930
May
MTWTFSS
12
3456789
10111213141516
17181920212223
24252627282930
31
June
MTWTFSS
123456
78910111213
14151617181920
21222324252627
282930
July
MTWTFSS
1234
567891011
12131415161718
19202122232425
262728293031
August
MTWTFSS
1
2345678
9101112131415
16171819202122
23242526272829
3031
September
MTWTFSS
12345
6789101112
13141516171819
20212223242526
27282930
October
MTWTFSS
123
45678910
11121314151617
18192021222324
25262728293031
November
MTWTFSS
1234567
891011121314
15161718192021
22232425262728
2930
December
MTWTFSS
12345
6789101112
13141516171819
20212223242526
2728293031

Solution 2

Here's an alternative version which displays the current month.

`<?`
`    // output rhe start of the calendar`
`    echo '<table><tr><th colspan="7">' . date('F Y') .`
`         '</th></tr><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>';`
`         `
`    // check if the first day of the month wasn't a monday`
`    if (date(D, strtotime(date(F) . ' 1')) <> 'Mon')`
`        // if not, add in a blank cell to occupy the days of the week before the first day`
`        echo '<td colspan="' . (date(w, strtotime(date(F) . ' 1'))-1) . '"></td>';            `
`        `
`    // loop through each day`
`    for (\$d = 1; \$d <= date(t); \$d++)`
`    {`
`        // check if this is not the first day, but is a monday`
`        if (\$d > 1 && date(D, strtotime(date(F) . ' ' . \$d)) == 'Mon')`
`            // output a new row`
`            echo '</tr><tr>';`
`            `
`        // check if this is today`
`        if (\$d == date(d))`
`            // emphasis the number`
`            echo '<td><em>' . \$d . '</em></td>';`
`        else`
`            // show normal number`
`            echo '<td>' . \$d . '</td>';`
`    }`
`    // finish off the table for this month    `
`    echo '</tr></table>';`
`?>`

Log

• April 3, 2005 - Added solution 1 and 2.
© 2004-19 robson | cc unless stated