countdownプログラムを作ってみよう4
こんちは、管理人イガジーです。
プログラミングでやっかいなのは、人の入力や操作の相手をする部分です。
人それぞれに、好みやこだわりがあり、使う人が増えれば増えるほど、
要求は多様になってきます。
自分専用のプログラムの場合でも、時間が経つと気も変わります。
例えば、年月日を指定する場合を考えてみましょう。
YYYYMMDD と、年(YYYY)を4桁、月(MM)を2桁、日(DD)を2桁、
計8桁の数字(例えば、”20111210″という形)で入力してもらうのが
処理する側(プログラムの作り方)としては簡単です。
ただ、桁は少ない方が入力が楽なので
YYMMDD と、年(YY)を2桁、月(MM)を2桁、日(DD)を2桁、にして
年は20xx年に固定する方法もあります。
20xxに固定するのは、なんとなく融通が効かない気がする場合は
現在の年(今なら2011年)の上位2桁を設定するようにしておけば、
21xx年になっても使えます。
(もちろん、そこまでこだわらなくてもいいだろう、という考えもあります。)
同じ年の場合は年を省略して MMDD の4桁でも受け付けて欲しいですし
さらに、11月に 0123(1月23日)の様に、前の月日を指定したら、
自動的に来年の1月23日にして欲しくなったりします。
(また、年月日は、yy/mm/dd と”/” で区切るものだ
という信念を持った人もいるでしょうし、
mm/dd/yy の順序、あるいは dd/mm/yyの順序がイイ
という人もいると思います。)
では、以下に実際のプログラム例を示します。
まず、main()から、コンストラクタCountDown() に argsを渡すようにします。
CountDown(String [] as) { // constructor
//...略
}
main(String [] args) {
new CountDown(args);
}
コンストラクタでは、as という変数名にしていますが
何でもかまいません。main と同じ args という名称でも良いのですが
混乱を招く可能性があるので違う名称にしています。
起動時に引数(アーギュメント)を指定しなかった場合、
as[] の要素数はゼロなので、無条件に as[0]を参照すると
例外が発生します(エラーが表示される)。
そこで、まずは as.length で、要素数が0かどうかを判定してから
処理するようにします。
int dyy=cyy+1;
int dmm=0;
int ddd=1;
if (as.length>0) {
// ... 引数があった場合に年月日の処理をする
}
d=new GregorianCalendar(dyy,dmm,ddd);
という感じですね。
当月の残り日数は “-m” と指定することにすると
if (as.length>0) {
// ... 引数があった場合に年月日の処理をする
}
の部分は、
if (as.length>0) {
// ... 引数があった場合に年月日の処理をする
}
の部分は
if (as.length>0) {
if (as[0].equals("-m")) {
dyy=cyy;
dmm=cmm+1;
if (dmm>11) {++dyy; dmm=0;}
}else{
// 年月日の数字指定の処理
}
}
という感じでしょう。
cyyは現在の(実行した時点での)年、cmmは現在の月です。
さて、数字指定の処理です。
まず
int ymd=Integer.parseInt(as[0]);
で、数字を得ることができますが、
数字にできない文字列が含まれていた場合に例外が発生するので
try-catch で囲うようにします。
int ymd=0;
try {
ymd=Integer.parseInt(as[0]);
}catch(Exception e){
ymd=0;
}
int y0=ymd/10000;
dmm=(ymd%10000)/100 - 1;
ddd=ymd%100;
という形でy0に年、dmmに月、dddに日が得られます。
年を省略した場合、y0 は 0 になるので
その時は dyyにcyy(現在の年)を入れるようにします。
その際、月日が現在の月日よりも前だったら、年(dyy)を +1 します。
年が 0 ではなく、100未満だったら、cyyの上位2桁を補います。
複雑に感じると思いますが、これが人の入力を処理する面倒なところです。
プログラム例は次のような感じです。
if (y0==0) { // 年が省略されていたら
dyy=cyy; // 現在の年をセット
if ((dmm*100+ddd)<(cmm*100+cdd)) ++dyy; // 月日が過去だったら年を+1
}else if (y0<100) dyy=(cyy/100)*100+y0; // 年が2桁入力だったら補う
こういった処理の他に
例えば、11月35日や2月30日などと指定されたらどうするか、
とか、9999年などの指定があったらどうするか、
なども気になるかもしれませんね。
意地悪入力を全く考えないのは困りますが、考えすぎるのもよくないのです。
キリがないので、どこかで割り切りが必要になります。
実際に動かしてみると、意地悪入力よりも悩ましい事が起きます。
何かというと、これを表示しっぱなしにしていた場合
日付が変わっても残り日数はそのまま、変化しません。
起動した時に計算して表示して終わり、その後の処理は無いので
当然なのですが、これで良いのか?と悩むわけです。
仕様としては、次のような例が考えられるでしょう。
(aa)一切、更新しないのが仕様だ。と割りきって終わる
(bb)更新ボタンを付けてクリックされたら、計算しなおして再表示する
(cc)フォーカスが当たったら、計算しなおして再表示する
(dd)タイマーを使って、時計の様に更新し続ける
明日は(cc)を考えてみることにします。
countdownプログラムを作ってみよう1
countdownプログラムを作ってみよう2
countdownプログラムを作ってみよう3
countdownプログラムを作ってみよう4(この記事)
countdownプログラムを作ってみよう5
countdownプログラムを作ってみよう6
この記事へのコメントはこちら