年間カレンダー
Posted feedbacks - Bash
「車輪の再発明」の誹りは免れませんが、Shell Scriptで書いてみました。
Bourne Shellでも動作するように書いたので、Unix系OSなら大半で動作すると思います。
時間のある時に AIX, HP-UX, Linux, Solaris などで動作確認してみます。
# 手元のCygwinで動作することを確認しました。
以下のワンライナーを実行することで、「年間カレンダー」を表示することが可能です。
e.g.
$ for i in `seq 1 12`; do ./cal.sh $i 2008; done
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 | #!/bin/sh
case "`echo -e`" in
-e) echo_() { echo "$@"; };;
*) echo_() { echo -e "$@"; };;
esac
case "`echo_ '\r'`" in
'\r') case "`(print X) 2>/dev/null`" in
X) echo_() { print "$@"; };;
*) PATH=/usr/5bin:$PATH; export PATH;;
esac
;;
esac
is_numeric() { return `echo_ $1 | grep -E '^[0-9]+$' >/dev/null 2>&1`; }
dow() {
y=$1; m=$2
[ $2 -le 2 ] && { y=`expr $y - 1`; m=`expr $m + 12`; }
expr \( 5 \* $y / 4 - $y / 100 + $y / 400 + \( 26 \* $m + 16 \) / 10 + $3 \) % 7
}
eom() {
case $2 in
1|3|5|7|8|10|12) echo_ 31;;
4|6|9|11) echo_ 30;;
2) is_leap_year $1 && echo_ 29 || echo_ 28;;
esac
}
is_leap_year() {
[ `expr $1 % 400` -eq 0 ] && return 0
[ `expr $1 % 100` -eq 0 ] && return 1
[ `expr $1 % 4` -eq 0 ] && return 0
return 1
}
main() {
[ $# -ne 2 ] && { echo_ "usage: $0 [month] [year]"; return 1; }
is_numeric $1 || return 1; [ $1 -lt 1 -o $1 -gt 12 ] && return 1
is_numeric $2 || return 1; [ $2 -lt 1 -o $2 -gt 9999 ] && return 1
w=`dow $2 $1 1`
d=`eom $2 $1`
echo_ "$2/\c"; [ `echo_ "$1\c" | wc -m` -eq 1 ] && echo_ ' \c'; echo_ "$1"
echo_ 'Su Mo Tu We Th Fr Sa'
for i in `seq 1 $w`; do echo_ ' \c'; done
for i in `seq 1 $d`; do
[ `echo_ "$i\c" | wc -m` -eq 1 ] && echo_ ' \c'
echo_ "$i\c"
[ `dow $2 $1 $i` -eq 6 ] && echo_ '' || echo_ ' \c'
done
echo_ '\n'
return 0
}
main $*
|
ANSIカラーに対応してみました。
# ダム端末ではエスケープシーケンスがそのまま表示されるため、レイアウトが崩れます。
e.g.
53,54c54,59
< echo_ "$i\c"
< [ `dow $2 $1 $i` -eq 6 ] && echo_ '' || echo_ ' \c'
---
> case "`dow $2 $1 $i`" in
> 0) echo_ "\033[31m$i\033[m \c";;
> 6) echo_ "\033[34m$i\033[m" ;;
> *) echo_ "$i \c" ;;
> esac
いくつかのUnix系OSでは正常に動作しなかったので、若干修正しました。 以下のOSで動作を確認。 AIX (5.2, 5.3) HP-UX (11.00, 11.11, 11.23) Linux (2.2, 2.4, 2.6) Solaris (5.5, 5.6, 5.7, 5.9, 5.10)
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 | #!/bin/sh
case "`echo -e`" in
-e) echo_() { echo "$@"; };;
*) echo_() { echo -e "$@"; };;
esac
case "`echo_ '\r'`" in
'\r') case "`(print X) 2>/dev/null`" in
X) echo_() { print "$@"; };;
*) PATH=/usr/5bin:$PATH; export PATH;;
esac
;;
esac
(echo '' | grep -E '' >/dev/null 2>&1) && grep_() { grep "$@"; } || grep_() { /usr/xpg4/bin/grep "$@"; }
seq_() { i=$1; while [ $i -le $2 ]; do echo_ "$i \c"; i=`expr $i + 1`; done; }
is_numeric() { return `echo_ $1 | grep_ -E '^[0-9]+$' >/dev/null 2>&1`; }
dow() {
y=$1; m=$2
[ $2 -le 2 ] && { y=`expr $y - 1`; m=`expr $m + 12`; }
expr \( 5 \* $y / 4 - $y / 100 + $y / 400 + \( 26 \* $m + 16 \) / 10 + $3 \) % 7
}
eom() {
case $2 in
1|3|5|7|8|10|12) echo_ 31;;
4|6|9|11) echo_ 30;;
2) is_leap_year $1 && echo_ 29 || echo_ 28;;
esac
}
is_leap_year() {
[ `expr $1 % 400` -eq 0 ] && return 0
[ `expr $1 % 100` -eq 0 ] && return 1
[ `expr $1 % 4` -eq 0 ] && return 0
return 1
}
main() {
[ $# -ne 2 ] && { echo_ "usage: $0 [month] [year]"; return 1; }
is_numeric $1 || return 1; [ $1 -lt 1 -o $1 -gt 12 ] && return 1
is_numeric $2 || return 1; [ $2 -lt 1 -o $2 -gt 9999 ] && return 1
w=`dow $2 $1 1`
d=`eom $2 $1`
echo_ "$2/\c"; [ `echo_ "$1\c" | wc -c` -eq 1 ] && echo_ ' \c'; echo_ "$1"
echo_ 'Su Mo Tu We Th Fr Sa'
for i in `seq_ 1 $w`; do echo_ ' \c'; done
for i in `seq_ 1 $d`; do
[ `echo_ "$i\c" | wc -c` -eq 1 ] && echo_ ' \c'
case "`dow $2 $1 $i`" in
0) echo_ "\033[31m$i\033[m \c";;
6) echo_ "\033[34m$i\033[m" ;;
*) echo_ "$i \c" ;;
esac
done
echo_ '\n'
return 0
}
main $*
|





186
#4884()
Rating4/4=1.00
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> ----[ reply ]