目次へ戻ります
イヌでもわかるJavaScript講座


月間カレンダーに挑戦

いままでのステップの知識でこのような月間カレンダー表も作れてしまいます。お部屋(ホームページ)のインテリアにどうぞ。(^^;
難易度:★★★★☆☆☆☆☆☆
【実行例】

【リスト】
<script language="JavaScript"><!--
// ****************
// **   下準備   **
// ****************
myDate    = new Date();                                    // 今日の日付データ取得
myWeekTbl = new Array("日","月","火","水","木","金","土");  // 曜日テーブル定義
myMonthTbl= new Array(31,28,31,30,31,30,31,31,30,31,30,31);// 月テーブル定義
myYear = myDate.getYear();                                 // 下2桁の西暦取得
myYear = (myYear<2000) ? (1900+myYear) : (myYear);         // 4桁の西暦に変換
if (((myYear%4)==0 && (myYear%100)!=0) || (myYear%400)==0) // うるう年だったら...
   myMonthTbl[1] = 29;                                     //  2月を29日とする
myMonth = myDate.getMonth();                               // 月を取得(0月〜11月)
myToday = myDate.getDate();                                // 今日の'日'を退避
myDate.setDate(1);                                         // 日付を'1日'に変えて、
myWeek = myDate.getDay();                                  //  '1日'の曜日を取得
myTblLine = Math.ceil((myWeek+myMonthTbl[myMonth])/7);     // カレンダーの行数
myTable   = new Array(7*myTblLine);                        // 表のセル数分定義

for(i=0; i<7*myTblLine; i++) myTable[i]=" ";              // myTableを掃除する
for(i=0; i<myMonthTbl[myMonth]; i++)myTable[i+myWeek]=i+1; // 日付を埋め込む

// ***********************
// **  カレンダーの表示  **
// ***********************
document.write("<table border='1' cellspacing='0' ");      // 表の作成開始
document.write("bordercolor='#808080' ");
document.write("bordercolordark='#000000' ");
document.write("bordercolorlight='#C0C0C0'>");

document.write("<tr><td colspan='7' bgcolor='#7fffd4'>");  // 見出し行セット
document.write("<strong>",myYear, "年", (myMonth+1), "月カレンダー</strong>");
document.write("</td></tr>");

document.write("<tr>");                                    // 曜日見出しセット
for(i=0; i<7; i++){                                        // 一行(1週間)ループ
   document.write("<td align='center' ");
   if(i==0)document.write("bgcolor='#fa8072'>");           // 日曜のセルの色
   else    document.write("bgcolor='#ffebcd'>");           // 月〜土のセルの色
   document.write("<strong>",myWeekTbl[i],"</strong>");    // '日'から'土'の表示
   document.write("</td>");
}
document.write("</tr>");

for(i=0; i<myTblLine; i++){                                // 表の「行」のループ
   document.write("<tr>");                                 // 行の開始
   for(j=0; j<7; j++){                                     // 表の「列」のループ
      document.write("<td align='center' ");               // 列(セル)の作成
      myDat = myTable[j+(i*7)];                            // 書きこむ内容の取得
      if (myDat==myToday)document.write("bgcolor='#00ffff'>"); // 今日のセルの色
      else if(j==0)      document.write("bgcolor='#ffb6c1'>"); // 日曜のセルの色
      else               document.write("bgcolor='#ffffe0'>"); // 平日のセルの色
      document.write("<strong>",myDat,"</strong>");        // 日付セット
      document.write("</td>");                             // 列(セル)の終わり
   }
   document.write("</tr>");                                // 行の終わり
}
document.write("</table>");                                // 表の終わり
// --></script>

サンプルだけのHTMLは こちらへ
【説明】

リストの長さを見て、「ダメだこりゃ!」と思わないでください。中身はたいしたことはしていません。ただ、長いだけです。コメントもふんだんに入れました。(^^;

このカレンダーも星の数ほどやり方、考え方があります。リストを見ていて、私のやり方に自分をあわせる必要はありません。「どうしてこんなことをやるんだ?こうじゃいけないのかな?」と思ったりするようでしたら、もうプログラマーです。自分のやり方に変更してみましょう。「これおかし〜んとちゃうか?はい、間違ってます。メールで教えてあげましょう。(^^;


さて、このカレンダーの考え方を説明します。

カレンダーといっても、縦と横、つまり、行と列の2次元の「表」です。表の内容も連続した数字(1から31)を埋めていくだけですから、なんとなくイケそうな気がします。はい、やることはそれだけです。(^^;

まず問題になるのは、月のはじめは日曜日から始まるわけではないこと。初日の曜日によって、左に空きのセル(つまり先月)ができます。ということは、月末の右にも空きのセル(つまり来月)ができます。そして、その月によって、行の数が可変になります(初日が土曜日で月が30日まであれば6行、初日が日曜日の2月(28日)であれば4行になります)。

当たり前じゃん」と思うでしょう。はい、当たり前です。しかし、この当たり前の文章をそのままプログラムに翻訳しないといけません。(^^;

前回のステップで、固定テーブルをただ、ループを使って表にしました。今回もそれでいきます。つまり、今月の固定テーブルをあらかじめ作成して、あとは前回のステップ同様、ループで表示させていきます。

なんだ、簡単そうじゃん!はい、簡単です。(^^;

今回はうるう年処理をあえてコンピュータにまかせず、自力で解決する方法をとります。な〜に、簡単なことです。
myMonthTbl = new Array( 31,28,31,30,31,30,31,31,30,31,30,31 );
月の終わりのテーブル(配列)です。とりあえず、2月は28日をセットします。
4で割り切れる年がうるう年です。しかし、100で割り切れるとうるう年ではありません。ところが、400で割り切れるとうるう年なんです。知ってましたか?(^^; では、翻訳しましょう。
i
f (((myYear%4)==0 && (myYear%100)!=0) || (myYear%400)==0) myMonthTbl[1] = 29;

今月の初日(1日)の曜日を取得します。
myDate.setDate(1);
getDate() があるのですから、setDate() もあります。これは、コンピュータのシステム時計を変えるわけではありません。myDate の日付情報をパラメータの日付に変更するだけです。これで初日の日付情報に変わるので、曜日の取得は楽勝です。カレンダーに今日の日付を違う色でマークしたいので、初日に情報を変える前に、今日を退避させておきます。
myToday = myDate.getDate();

さて、下準備が終われば、
今月の固定テーブルの作成に取り掛かりましょう。

まず、気になる行の数を計算します。
myTblLine = Math.ceil ( ( myWeek+myMonthTbl[myMonth] ) / 7 ) ;
            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          

これは、6行のパターンです。myWeek は初日の曜日、つまり、土曜日ですから 6 です。 この表を1月としますと、myMonth は 0、myMonthTbl[0] は、31 です。 (6+31)/7 の小数点切り上げ、つまり、6行です。忘れないうちに myTblLine に退避させます。(^^;

このカレンダーだと、7*6 つまり、42個のセル(
今月の固定テーブル)が必要です。作りましょう。
myTable = new Array( 7*myTblLine ) ;

先月と来月の空きセルはスペース(空白)を表示します。
for (i=0; i<7*myTblLine; i++) myTable[ i ] = " ";
めんどくさいから、全部、空白を入れました。(^^; 本当に血液型A型か? (-o-?)

さて、今月の日付を埋め込みましょうか。
for (i=0; i<myMonthTbl[myMonth]; i++) myTable[ i+myWeek ] = i+1;

上の1月のパターンで考えると、
for (i=0; i<31; i++) myTable[ i+6 ] = i+1;

表の行をなくし、横に一直線に考えると、ちゃんと myTable に表のイメージ通り、日付がセットされましたね。


それでは、カレンダーを表示しましょう。

前回の表作成と違うのは、今回は「列」がある点です。横に7個表示したら、改行?しないといけません。
上のパターンで言うと、7個、列を表示するのを、6行、繰り返せば良いのです。つまり、7回のループを6回ループするんです。(^^;
あ、あたまが (-o-;

イメージでプログラムすると、
for ( i = 0; i < 6; i++ ) {
  for ( j = 0; j < 7; j++ ) {
    document.write ( 1個のセル表示 );
  }
}
ループの中にループ。2重ループです。 1個目のループに i を使ったので、2個目のループは、j です。「郷に入っては郷に従え」 (^^;

どうして、カレンダー表示のルーチンがこんなに長いの?ひょっとして、複雑なのでは?

いえ、見出しとセルに色をつけたから、こんなに長くなりました。見出しと色がなければ、短いものです。
だったら、つけるな、バカタレが! (-o-メ (T_T) どうせなら・・・

document.write("<table border='1' cellspacing='0' ");     // 表の作成開始
document.write("bordercolor='#808080' ");
document.write("bordercolordark='#000000' ");
document.write("bordercolorlight='#C0C0C0'>");
document.write("<tr><td colspan='7' bgcolor='#7fffd4'>"); // 見出し行セット
document.write("<strong>",myYear, "年", (myMonth+1), "月カレンダー</strong>");
document.write("</td></tr>");

普通に書けば、

<table border="1" cellspacing="0" bordercolor="#808080"
bordercolordark="#000000" bordercolorlight="#C0C0C0">
<tr>
<td colspan="7" bgcolor="#7FFFD4"><strong>1999年1月カレンダー</strong></td>
</tr>
1999年1月カレンダー
が、作りたかったわけです。
document.write("<tr>");                                // 曜日見出しセット
for(i=0; i<7; i++){                                    // 一行(1週間)ループ
  document.write("<td align='center' ");
  if(i==0)document.write("bgcolor='#fa8072'>");        // 日曜のセルの色
  else document.write("bgcolor='#ffebcd'>");           // 月〜土のセルの色
  document.write("<strong>",myWeekTbl[i],"</strong>"); // '日'から'土'の表示
  document.write("</td>");
}
document.write("</tr>");


普通に書けば、

<tr>
   <td align="center" bgcolor="#FA8072"><strong>日</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>月</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>火</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>水</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>木</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>金</strong></td>
   <td align="center" bgcolor="#FFEBCD"><strong>土</strong></td>
</tr>
が、作りたかったわけです。
for(i=0; i<myTblLine; i++){                                // 表の「行」のループ
   document.write("<tr>");                                 // 行の開始
   for(j=0; j<7; j++){                                     // 表の「列」のループ
      document.write("<td align='center' ");               // 列(セル)の作成
      myDat = myTable[j+(i*7)];                            // 書きこむ内容の取得
      if (myDat==myToday)document.write("bgcolor='#00ffff'>"); // 今日のセルの色
      else if(j==0)      document.write("bgcolor='#ffb6c1'>"); // 日曜のセルの色
      else               document.write("bgcolor='#ffffe0'>"); // 平日のセルの色
      document.write("<strong>",myDat,"</strong>");        // 日付セット
      document.write("</td>");                             // 列(セル)の終わり
   }
   document.write("</tr>");                                // 行の終わり
}
document.write("</table>");                                // 表の終わり
メインはこれです。なんだ、これだけか。(-o-メ

j+(i*7) これで、今のセルに書くべきデータのテーブル番号が割り出せます。


お疲れ様でした。 (^^;

目次へ戻ります