今回はまず上のようなカレンダーを作ってみます。毎月書き直す、という手もありますが、それじゃちょっと芸がありません。 それにごらんのように今日の日付が青色(日曜日なら紫色)で表示されるようになっている(Netscape では更に文字が点滅する)ので、毎日書き換えなくてはならなくなります。
ページが読み込まれると今月のカレンダーが表示され、今日の日付が強調表示されるプログラムを JavaScript で作ってみましょう。まず用意としては月の日数を割り出す関数 Nissu() をHTMLの </TITLE> と </HEAD> の間に定義しておく必要があります。
1年のうち4・6・9・11月は30日、2月を除くそれ以外は31日、2月は平年なら28日、うるう年なら29日あります。 西暦を表す4桁の数字が、もし4で割り切れないか、100で割り切れて400で割り切れなければ、うるう年ではないと言われていますので、アルゴリズムは次のようになります。 (a, b には、それぞれ西暦と月を表す数を代入します。)
- function Nissu(a, b) {
- if(b==2)
- {
- if(a % 4==0)
- {
- if(x % 100==0 && x % 400!=0) return 28;
- else return 29;
- }
- else return 28;
- }
- else if(b==4 || b==6 || b==9 || b==11) return 30;
- else return 31;
- }
次にカレンダーを表示するスクリプトは直接 <BODY> 内の該当個所に書きます。
- <SCRIPT Language="JavaScript">
- <!--
まず今年の西暦、今月、今日の日付と曜日を取得する変数を定義します。
- Now=new Date();
- with(Now)
- {
- YY = getYear();
- if(YY < 90) YY = "20"+YY;
- else if(YY < 99) YY = "19"+YY;
- else if(YY < 1900) YY = 1900+YY;
- MM=getMonth()+1;
- DD=getDate();
- WW=getDay();
- }
次にページへの記入の仕方です。
- with(document)
- {
曜日を表す配列を作っておき、それを for ループで TABLE 内に自動的に記入させるようにします。 (直接 TABLE 内に各曜日を記入してもいいのですが、面倒ですから。)このときフォントサイズと文字色も指定します。
- Yoobi=new Array("日","月","火","水","木","金","土");
- write("<FONT size=7>",YY,"年</FONT><BR><FONT size=6>",MM,"月</FONT><BR><BR><TABLE><TR>");
- for(i=0; i < 7; i++)
- {
- if(i==0) write("<TD><FONT size=6 color='Red'>",Yoobi [ i ],"</FONT></TD>");
- else write("<TD><FONT size=6>",Yoobi [ i ],"</FONT></TD>");
- }
- write("</TR>");
次にカレンダーを表示する方法ですが、その月の1日が何曜日であるかわかればカレンダーを作るのは簡単です。 これにはいろいろな方法が考えられますが、ここでは私の考えた方法でやってみます。(Zellar の公式については「カレンダーを作る(2)」で述べます。)
今日が何曜日かわかれば、その前後7日ごとの日付が同じ曜日であることは明らかです。getDay() メソッドの戻り値は0から6までの数字(例えば金曜日は5)で表されます。また、1週間は7日なので毎月8日は1日と同じ曜日です。 今日と同じ曜日の最初の日付を割り出し、8からこの数字を引いた数を今日の曜日の数字に足してやり、これを7で割った剰りが、1日の曜日の数字となります。
これを簡潔な式で表すと、次のようになります。
- 1日の曜日=(今日の曜日+8−今日の日付+7×(今日の日付を7で割った正数))を7で割った剰り
1日の曜日を表す数字を First という変数に代入させるとすると、
- First=(WW+8-DD+7*Math.floor(DD/7)) % 7;
となります。次はいよいよカレンダーの本体です。月の日付を入れる変数Pと TABLE 中の TD の数を入れる変数Q、それにカレンダーの始まり(日曜日)から終わりまでの数を入れる変数 Su を用意します。 Su は上述の Nissu() 関数で割り出した今月の日数に変数 First を足して求めます。
- var P=0;
- var Q=0;
- P-=First;
- Su=Nissu(YY, MM)+First;
ここでも for ループを使用します。
- for(i=0; i < Su; i++)
- {
- P++;
- Q++;
- //1日より前なら空白を入れる
- if(P<1) write("<TD> </TD>");
- //今日の日付に来たら、
- else if(P==DD)
- {
- //もし日曜日なら新しい列を初め、文字色を purple にし、(Netsape で)点滅させる。
- if(Q % 7==1) write("<TR><TD align=center><FONT size=6 color='purple'><blink>",P,"</blink></FONT></TD>");
- //もし土曜日なら文字色を blue にし、点滅させて列を終える
- else if(Q % 7==0) write("<TD align=center><FONT size=6 color='Blue'><blink>",P,"</blink></FONT></TD></TR>");
- //平日なら文字色を blue にして点滅させるだけ
- else write("<TD align=center><FONT size=6 color='Blue'><blink>",P,"</blink></FONT></TD>");
- }
- //今日以外の日は
- else
- {
- //日曜日なら文字色を red に、その他では色の指定をしない
- if(Q % 7==1) write("<TR><TD align=center><FONT size=6 color='red'>",P,"</FONT></TD>");
- else if(Q % 7==0) write("<TD align=center><FONT size=6>",P,"</FONT></TD></TR>");
- else write("<TD align=center><FONT size=6>",P,"</FONT></TD>");
- }
- //ループを抜けたらTABLE を終える
- write("</TR></TABLE>");
- }
このカレンダーでは、祝祭日(或いはその振替休日)の表示は設定していません。もしそれも表示させるなら、月・日を引数として入れて、指定した月・日なら真を返す関数を作っておき、ループの条件分の中でその関数が真なら文字色を red にするというような設定をしておけばよいでしょう。