2014年3月4日火曜日

年月日から曜日を計算

西暦と月日から曜日を計算する方法です

      1 #include <stdio.h>
      2
      3 int main(void) {
      4     const char str[] = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat";
      5     int y, m, d, Y, C, h;
      6
      7     y = 2014;
      8     m = 3;
      9     d = 4;
     10
     11     if (m == 1) { m = 13; y--; }
     12     if (m == 2) { m = 14; y--; }
     13
     14     C = y / 100;
     15     Y = y % 100;
     16
     17     h = (d + ((26 * (m + 1)) / 10) + Y + (Y / 4) + 5 * C + (C / 4)) % 7;
     18
     19     printf("%d\n", h);
     20     printf("%s\n", str + (((h + 6) % 7) * 4));
     21
     22     return(0);
     23 }

計算をしているのは7行目から17行目までです

strの文字列は曜日を表示するためのもので、ifやswitchを書くのが面倒なときに使う方法です

まずymdに年月日を代入します

そして1月と2月の場合は年をデクリメントしてから12を加算します
今回は1月と2月の判断をifで1個1個処理したので、加算ではなく代入で行いました

次に西暦を上2ケタと下2ケタに分割します
あとは計算式に代入するだけです

実はこの計算式 ページによって式が違っていたりします
結果が同じならどれを使ってもいいのですけども

最後にprintfで表示します
出力される値が土曜日を0として日曜が1 金曜が6 という感じなので少し扱いづらいので、hに6を加算してから7のあまりを取る という方法で日曜を0に移動しています
この曜日を移動するコードは17行目に追加するとスマートに実装できます


このコードを音声認識で起動してGoogle Glassに表示するアプリをかけばケンジ君ごっこができます
ちなみにこれはモジュラ演算ではなく ツェラーの公式という名前です
モジュラはおそらくModularのことで、これは合同式を意味します
これは17行目最後に出てくる%記号の演算処理のことで、あまりを計算しています


上の画像はWikipediaから拾ってきた式ですが
2つ目の式と3つ目の式のmodがModularの意味です
例えばyが2014だった場合 Y = y mod 100 つまりyを100で割ったあまりで、14が入ることになります

この計算式を何に使うのかは正直微妙なところですが、組み込みシステムなどで1秒に1回インクリメントするカウンタを前回のエントリで日付に直してからこの式で曜日を計算して液晶に表示  とかできるかもしれません(ちょっと苦しい)

0 件のコメント:

コメントを投稿