challenge 年間カレンダー

nを入力としてn年の年間カレンダーを返すプログラムを作ってください
少なくとも日曜日と土曜日が判別出来るようにしてください
出力は標準出力でもファイルでも構いません
デザインは各自のお好みで

出力例1:
(y-calendar 2008)=>
#=Saturday, @=Sunday
2008/1 1 2 3 4 #5 @6 7 ...
2008/2 1 #2 @3 4 5 6 7 ...
...
2008/12 1 2 3 4 5 #6 @7 ...

出力例2:
(y-calendar 2008)=>
        M T W T F S S M
2008/ 1   1 2 3 4 5 6 7 ...
2008/ 2         1 2 3 4 ...
...
2008/12 1 2 3 4 5 6 7 8 ...

出力例3:
(y-calendar 2008)は2008.htmlを出力する
2008.htmlの中身
----
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
       "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>2008 calendar</title>
<style type="text/css">
* {font-family: monospace;}
span {margin: 0px 3px;}
span.sunday {color:red;font-weight:bold;}
span.saturday {color:blue;font-weight:bold;}
dd ul li{display:inline;}
</style>
</head>
<body>
<h1>2008 calendar</h1>
<dl>
<dt>2008/1</dt>
<dd><ul>
<li><span class="weekday">1</span></li>
<li><span class="weekday">2</span></li>
<li><span class="weekday">3</span></li>
<li><span class="weekday">4</span></li>
<li><span class="saturday">5</span></li>
<li><span class="sunday">6</span></li>
...
</ul></dd>
...
</dl>
</body>
</html>
----

Posted feedbacks - JavaScript

404 Blog Not Found:javascript - カレンダーを作るに実際に動くデモがありますので併せてご覧下さい。なるべく再利用しやすいよう書きました。

Dan the JavaScripter

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
function leap(year){
  return year % 4 ? 0 : year % 100 ? 1 : year % 400 ? 0 : 1;
}

function make_cal_array(year){
  var months = [31, 28 + leap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  var result = [];
  for (var m = 0; m < 12; m++){
    result[m] = [];
    var dofw1 = (new Date(year, m, 1, 0, 0, 0)).getDay();
    for (var d = 1; d <= months[m]; d++){
      result[m][d + dofw1 - 1] = d;
    }
  }
  return result;
}

var daynames = ['sun','mon','tue','wed','thr','fri','sat'];

function make_cal_yearly(year){
  var cal = make_cal_array(year);
  var tbody = document.createElement('tbody');
  for (var m = 0; m < 12; m++){
    var tr = document.createElement('tr');
    var th = document.createElement('th');
    th.innerHTML = m + 1;
    tr.appendChild(th);
    for (var d = 0, l = cal[m].length; d < l; d++){
      var td = document.createElement('td');
      if (cal[m][d]){
        td.innerHTML = cal[m][d];
        td.className = daynames[d % 7];
      }
      tr.appendChild(td);
    }
    tbody.appendChild(tr);
  }
  var table = document.createElement('table');
  table.className = 'ycal';
  var caption = document.createElement('caption');
  caption.innerHTML = year;
  table.appendChild(caption);
  table.appendChild(tbody);
  return table;
}

function make_cal_monthly(year, m){
  var cal = make_cal_array(year);
  var table = document.createElement('table');
  // header
  var tr = document.createElement('tr');
  for (var d = 0; d < 7; d++){
    var th = document.createElement('th');
    th.innerHTML = th.className = daynames[d];
    tr.appendChild(th);
  }
  var thead = document.createElement('thead');
  thead.appendChild(tr);
  table.appendChild(thead);
  // body;
  var tbody = document.createElement('tbody');
  for (var d = 0, l = cal[m].length; d < l; d++){
    if (d % 7 == 0) tr = document.createElement('tr');
    var td = document.createElement('td');
    if (cal[m][d]){
      td.innerHTML = cal[m][d];
      td.className = daynames[d % 7];
    }
    tr.appendChild(td);
    if (d % 7 == 6) tbody.appendChild(tr);
  }
  tbody.appendChild(tr);
  table.className = 'mcal';
  var caption = document.createElement('caption');
  caption.innerHTML = year + '.' + (m+1);
  table.appendChild(caption);
  table.appendChild(tbody);
  return table;
}

function make_calendars(year, p){
  p.innerHTML = '';
  p.appendChild(make_cal_yearly(year));
  for (var m = 0; m < 12; m++){
   var mcal = make_cal_monthly(year, m);
   p.appendChild(mcal);
   if (m % 3 == 2){
     var br = document.createElement('br');
     br.clear = 'all';
     p.appendChild(br);
   }
  };
}

すでに JavaScript + HTMLによる解が提出されていますが、 SVGで出力してみたかったの
で、 ECMA Script + SVGで書いてみました。

calendar.svgなどの名前でファイルを保存し、ブラウザにドラッグアンドドロップすれば、
以下の形式でカレンダーが表示されます。

  e.g.
    2008/ 1
    日 月 火 水 木 金 土
           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

Firefox 2.0.0.8, Internet Explorer 6, Opera 9.23で動作を確認しました。まだ試して
いませんが、Safari 3でも動作すると思います。

[注意]
  * IEで表示する場合は、プラグインとしてAdobe SVG Viewerがインストールされている
    必要があります。
  * IEで SVGファイルを実行するとスクロールバーが表示されないため、カレンダーを全
    て見ることができませんでした。スクロールバーを表示するには、別途HTMLファイル
    を用意し、 embed要素の src属性に SVGファイルを指定してあげる必要があるのかも
    しれません。
  * Calendarオブジェクトに何もかも詰め込んでいるので、ソースが汚い点はお許しを。
 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="new Calendar(2008).draw(10, 10)">
    <script type="text/ecmascript">
    <![CDATA[
        function $(i) { return document.getElementById(i); }

        function isNumber(v) { return typeof(v) == 'number' && isFinite(v); }

        var Calendar = function (y /* 年 */) {
            if (!isNumber(y)) return;

            this.y = y;
            this.f = 14; // フォントサイズ

            this.isLeapYear = function (y) { return y % 4 ? true : y % 100 ? false : y % 400 ? true : false; };
            this.draw = function (l /* 左部余白 */, t /* 上部余白 */) {
                var d = [ 31, (this.isLeapYear(this.y)) ? 28 : 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
                var w = [ '日', '月', '火', '水', '木', '金', '土' ];
                var i, m, o, s, x, y;

                s = this.f / 2 /* 余白 */; y = t;
                for (m = 0; m < 12; m++) {
                    // 年, 月
                    x = l; y += this.f + s;
                    o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                    o.setAttribute('x', x);
                    o.setAttribute('y', y);
                    o.setAttribute('font-family', 'MS Gothic');
                    o.setAttribute('font-size', this.f + 'px');
                    o.setAttribute('text-rendering', 'optimizeLegibility');
                    o.appendChild(document.createTextNode(this.y + '/' + ((m + 1 < 10) ? ' ' : '') + (m + 1)));
                    document.rootElement.appendChild(o);
                    // 曜日
                    x = l; y += this.f + s;
                    for (i = 0; i < w.length; i++) {
                        o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                        o.setAttribute('x', x);
                        o.setAttribute('y', y);
                        o.setAttribute('font-family', 'MS Gothic');
                        o.setAttribute('font-size', this.f + 'px');
                        o.setAttribute('text-rendering', 'optimizeLegibility');
                        o.appendChild(document.createTextNode(w[i]));
                        document.rootElement.appendChild(o);
                        x += this.f + s;
                    }
                    // 日
                    x = l + (this.f + s) * (new Date(this.y, m, 1).getDay()); y += this.f + s;
                    for (i = 0; i < d[m] ; i++) {
                        o = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                        o.setAttribute('x', (i + 1 < 10) ? x + s : x);
                        o.setAttribute('y', y);
                        o.setAttribute('font-family', 'MS Gothic');
                        o.setAttribute('font-size', this.f + 'px');
                        o.setAttribute('text-rendering', 'optimizeLegibility');
                        o.appendChild(document.createTextNode(i + 1));
                        document.rootElement.appendChild(o);
                        if (new Date(this.y, m, i + 1).getDay() == 6) {
                            x = l; y += this.f + s;
                        } else {
                            x += this.f + s;
                        }
                    }
                    y += this.f + s;
                }
                // ビューポート
                document.rootElement.setAttribute('width', l + (this.f + s) * w.length);
                document.rootElement.setAttribute('height', y);
                // ビューボックス
                document.rootElement.setAttribute('viewBox', '0 0 ' + (l + (this.f + s) * w.length) + ' ' + y);
                document.rootElement.setAttribute('preserveAspectRatio', 'xMinYMin slice');
            };
        };
    ]]>
    </script>
</svg>

Index

Feed

Other

Link

Pathtraq

loading...