がるの健忘録 このページをアンテナに追加 RSSフィード

2009-01-12

[][]カレンダーの作り方

お題はこんな感じで。

「年月を入力するとその月のカレンダーを表示するプログラムを作成」

どげんかせんといかん事を一個づつ分解していきませう。


まず

1.年と月の入力を受け取る。

シンプルですね簡単ですね。このレベルで躓くなら、対象言語の入門書あたりを確認してください。

で…


1-1.入力がない、もしくは入力が無効の場合、デフォルトを「今」にする

こんなちょっとした小技がステキだったりします。小枝は美味しいのですが。


つぎ。ここらあたりから微妙に本題。

2.対象年月の「末日」を求める

ここで「ふふん簡単」とか思うと、閏年問題に引っかかりますのでご注意を。


んで。

3.1日から「末日」までの数字をとりあえず出力する

いったんは「数字だけ」。その後で、テーブルタグだのcssだのを使って「縦に」出力したり「横に」出力したりして遊んでおくと後々便利です。


そろそろ面白く。

4.3番の日付に「曜日」を付け足して表示する

曜日の算出方法は色々ありますが。言語が持ってるなんらかのお便利なclassがない場合とか頑張ってみたいとかいう場合、「ツェラーの公式(Zeller's congruence)」を用いてみるとよいでせう。

ここでも、すこ〜し表示で遊んでみると面白いです。


ちなみに、ここで最低限の「カレンダー」は完成だったりしますw

でもまぁせっかくなので、いわゆる「四角いの」を考えて見ませう。

四角いカレンダーを作る場合。最大のポイントは「どこで改行するか?」に尽きます。

とりあえず、多分一般的だと思う「日〜土」の並びで考えてみますが。


回答を書いてしまうと

for(day = 1; day >= 末日; day ++;) {
 日付の出力処理
 if (true == is土曜日(day)) {
  改行処理
 }
}

概ねこんな感じです…でだまされると酷い事になりますw

第一週が変に左よりになっちゃうんですね。

なので。ループの前に、こんな処理を入れてあげます。

if (1日が月曜日なら) {
 空白を1つ
} else
if (1日が火曜日なら) {
 空白を2つ
} else
if (1日が水曜日なら) {
 空白を3つ
} else
if (1日が木曜日なら) {
 空白を4つ
} else
if (1日が金曜日なら) {
 空白を5つ
} else
if (1日が土曜日なら) {
 空白を6つ
}

for(day = 1; day >= 末日; day ++;) {
 日付の出力処理
 if (true == is土曜日(day)) {
  改行処理
 }
}

とりあえず出来ますが…うんぶっちゃけ「うざい」。

ここで。曜日の数値に注目します。多くのツェラーの公式では、0が日曜日〜6が土曜日になります*1

あれ?

ほら冷静に、上のプログラムをもう一度。

ツェラーの公式では、1なら月曜日、2なら火曜日、3なら水曜日、以下略。

…なんか共通点見えてきません?


ってなわけで、改造。

n = ツェラーの公式(1日)
空白をnつ

for(day = 1; day >= 末日; day ++;) {
 日付の出力処理
 if (true == is土曜日(day)) {
  改行処理
 }
}

ほぉらシンプル。

これで概ねカレンダーができあがります。

OKざましょか?


余談

多分、やると怒られるか、或いは怒ってすら貰えない別解。とりあえずPHPで。

$y、$mに年と月が入ってるとします。

$s = `cal $m $y`;
print $s ;

おそまつ。

*1wikiのだと0が土曜日なんですよねぇ…くまったことに

MeymeyMeymey 2009/01/13 03:28 ツェラーの公式とか知らなかったですw
簡単なものに分解して、一歩一歩上に上っていくのは基本だと思うのですが、なかなかできませんね、こころがけたいものです。
あと、なんつーか、一応仕事でPGしてる私がいうのもなんですが、ツェラーの公式はこうなってるから、こういう感じでプログラム組んでと、条件が決まってるものをコードに落とすことはできるんですが、カレンダーを作るから、ツェラーの公式引っ張ってきたりとか、祝日のために、ハッピーマンデー制度どうするんだとか、春分の日とか秋分の日どうするんだとかで、頭いたくなって、仕様を決めるのができなかったりします、なのでカレンダーは嫌いです・・・。
両方できないとまずいのですが、仕様に落とすのと、仕様からコード作るのって違うよねと。
n = ツェラーの公式(1日)
がんばって実装して
n = date (N,int $timestamp ] )
な関数があるこしって、へこむんだろうな・・とか。
自分で考えて、仕様決めて、がりがりコード書ける人は、勝手に変態になっていくとおもうので、いやでしょうがないけど、仕事だし、プログラムかかなきゃいけないとか、優柔不断でびしっときめれないひとのために、最初のうちは、仕様ががっちりきまったものを与えて、手を動かさせるのも大事かなと思ったりします、つまんないかもしれないですけどね、私が後者だったので、こうしてほしいなと思っただけですけど。

gallugallu 2009/01/14 03:21 やほり。ツェラーはしっとくと、何かと便利よん。式の意味っつか考察は、コードランクたんのBlogで展開式やってたはず。
まぁ…うん初めの頃は「手を動かしたら動く」って楽しさも絶対にあるよね。おいらもそうだったもんw
で、だんだんそれじゃ我慢が出来なくなって「もっとここがこうなればいいのに」って思ってはまるのは、プログラムもゲームも一緒w

wiz-zilwiz-zil 2009/01/26 18:39 http://d.hatena.ne.jp/wiz-zil/20060918

いちおうw

wiz-zilwiz-zil 2009/02/03 17:57 あ。追記。
ハテナでは違う名前で出てるらしいですw

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/gallu/20090112/p2