TOP Column Menu 戻る
WideStudio かんどころ(4)
WideStudioによる無作法なC++  2003/05/03

第四回 本格的カレンダーのプログラムを作る
カレンダーの論理(1)

さて、前回で画面が完成したことになりました。
のデザインをするにはどうしたらよいのでしょうか。

今回作成するプログラムは以下の区分にわかれます。
部品操作のプログラム
前回の部品の5つの分けを思い出してください

  ①年月日表示ラベル
  ②年移動ボタン
  ③月移動ボタン
  ④曜日表示ラベル
  ⑤日操作ボタン

プログラム起動して初期カレンダーが表示されて以後
操作による変化(↓)  部品グループ(→)
表示文字列が変わる × × × ×
①の年月日表示ラベルの変更が出来る × ×
⑤の日操作ボタンの位置や数を変更出来る × × ×

プログラム起動前では全ての部品の位置や表示文字列は画面の状態でした。それが本日が2003年の5月3日ならの画面になります。
ボタン操作によっての画面の状態にもなります。
上の表のように
 移動したり部品の数が変わったのは⑤の日操作ボタンです。
 また、表示文字列の変わったのは①の年月日表示ラベルです。
 Ⅱ(2003年5月)と(2003年6月)のカレンダー画面を見てください。5月の31日は土曜日ですので31のボタンは土曜の位置にあり、6月1日は当然日曜日になるわけですから、6月のカレンダーは日曜の位置から始まっています。
のカレンダー画面(2003年8月)では1日は金曜から始まっています。そうすると日のボタンは6行となります。
カレンダーの日は4行から6行まで変化します。最も4行は1日が日曜日で閏年以外の2月のカレンダーだけです。
つまり、先ほどの表に付け加えなければならないのはカレンダーの縦の大きさも変化するということです。

0列目 1列目 2列目 3列目 4列目 5列目 6列目
0行目 0 0 0 1 0 2 0 3 0 4 0 5 0 6
1行目 1 0 1 1 1 2 1 3 1 4 1 5 1 6
2行目 2 0 2 1 2 2 2 3 2 4 2 5 2 6
3行目 3 0 3 1 3 2 3 3 3 4 3 5 3 6
4行目 4 0 4 1 4 2 4 3 4 4 4 5 4 6
5行目 5 0 5 1 5 2 5 3 5 4 5 5 5 6

では、この最も複雑な日ボタン移動の論理はどんなものなのでしょう。
次の表で日ボタン移動の場所を地図化してみましょう。つまり、左の数字は行(0〜5)をあらわし右の数字は列(0〜6又は日曜〜土曜)をあらわします。

もし、2003年6月みたいに1日が日曜なら8日も15日も22日も日曜日ですし、2日、9日、16日、23日は月曜日となります。つまり、7日後は同じ曜日なわけですね。(おぉ〜い!どうぜんじゃろ!)

2003年6月のカレンダーの論理
この場合(1日が日曜日)はその(日付−1)を7で割った余りが曜日に対応するわけです。
VisualBasicの場合は mod 関数が余りを計算し CやC++では % が余りを計算します。 となりますね。
ところで、前回の画面作成の時にオブジェクトの配列の名称は[0]からはじまっていました。曜日も月も日も配列は全て[0]からはじめました。
つまり日移動のボタンの最初は ddbtn[0] は1日とすればよいわけです。また曜日ラベルは yb[0]〜yb[6]を日月火水木金土にたいおうさせましょうね。日付に対応する配列番号は日付−1ということです。
そこで先ほどの曜日の計算式は
だから14日は配列番号は13番です。従って曜日は13÷7での余り、即ち6ということになります。曜日配列番号の6は土曜日ということですね。6月14日は娘の誕生日なのですが、それが土曜日であることはこうして検証できるのですね。

では、はどうなのでしょう。
行は配列番号を7で切り捨てで割った数字となります。

1日〜7日は配列番号で0〜6ですので7で切捨てで割れば0と言うことになります。当然8日から14日は配列番号で[7]〜[13]なので7で割り切れば1になりますので1行目となります。

全ての月に通じるカレンダーの論理
では2003年の8月のカレンダーはどうなっているのでしょうか。8月の1日は金曜日です。3日は2行目の日曜日となります。
そこで先ほどの曜日の計算式に1日の曜日配列番号を補正値としていれてやればいいのです。
1日が金曜日ですので、金曜日の曜日配列番号は5です。
となり行番号は

もしも月の1日の曜日がわかればその月のカレンダーをつくる論路はこれで出来るわけです。あとはその月の最大の日が30日なのか31日なのか28日なのか4年に1度の29日なのかだけですね。