質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

13738閲覧

java カレンダー作成

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/04/18 05:07

編集2016/04/18 06:38

追記:JDKのバージョンは1.6.0_19です。
そして指示によりimportは使用できないようになっています。


コマンドライン引数で年月の値を引き渡し(201604の様に6桁で)、それでカレンダーを表示させるプログラムを考えています。

一応理想の形で表示させることが出来るようになったのですが、もっと『ここはこうするべき』『こうした方がスマートで分かりやすい』『最初から大幅にやり直すべき』などご指摘がございましたら是非お願いいたします!


public class CalShow {

public static void main(String[] args) { java.util.Calendar cal = java.util.Calendar.getInstance(); int year = Integer.parseInt(args[0].substring(0, 4)); int month = Integer.parseInt(args[0].substring(4)); System.out.println( year + "年" + month + "月"); System.out.println(" 日 月 火 水 木 金 土"); //year,month,1で年月日設定 cal.set(year, month - 1, 1); //月初日が何曜日なのか設定 int startDay = cal.get(java.util.Calendar.DAY_OF_WEEK); int lastDay = cal.getActualMaximum(java.util.Calendar.DATE); if(startDay != 7){ for(int i = 1 ; i < startDay; i++ ){ System.out.print(" "); } } int day = 1; for(int i = startDay; i <= 7; i++) { if(day < 10){ System.out.print(" "); } System.out.print(" "+ day); day ++; } System.out.println(""); for(int j = 1; j < 7; j++){ for(int k = 0; k < 7; k++){ if(day <= lastDay){ if(day < 10){ System.out.print(" "); } System.out.print(" "+ day); day ++; } } System.out.println(""); } }

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KiyoshiMotoki

2016/04/18 05:10 編集

お使いのJDKのバージョンは何ですか?それによって、回答が変わってくる可能性がありますので。
退会済みユーザー

退会済みユーザー

2016/04/18 05:12

JDKは1.6.0_19です。あと申し訳ありません、記載するのを忘れていたのですが、importは使用せずに作成したいと思っております。
KiyoshiMotoki

2016/04/18 05:16

返信ありがとうございます。お手数ですが、「JDKは1.6.0_19です。」は質問欄に追記願います。誰もがこの"情報の追加・修正の依頼をする"欄を読むとは限りませんので。あと、「importは使用せずに作成したいと思っております。」は、なぜですか?理由によっては、その方針自体、考え直すべきかもしれません。
guest

回答3

0

java

1for(int j = 1; j < 7; j++){ 2 for(int k = 0; k < 7; k++){ 3 if(day <= lastDay){ 4 if(day < 10){ 5 System.out.print(" "); 6 } 7 System.out.print(" "+ day); 8 day ++; 9 } 10 } 11 System.out.println(""); 12}

とりあえず、ここのfor文のネストは可読性を落とすだけなのでやめたほうがいいでしょう。
そのうえでjava.util.Calendarを有効活用するならこんなコードもありですね。

java

1java.util.Calendar cal = java.util.Calendar.getInstance(); 2cal.set(year, month - 1, 1); 3 4int monthStartDayOfWeek = cal.get(java.util.Calendar.DAY_OF_WEEK); 5 6int dateConst = java.util.Calendar.DATE; 7 8System.out.println( year + "/" + (month--) + ""); 9System.out.print(" sun mon tue wed thu fri sat"); 10 11for(int i = 1; ; i++) { 12 if(i % 7 == 1){ System.out.println(); } 13 if (i < monthStartDayOfWeek) { 14 System.out.print(" "); 15 continue; 16 } 17 System.out.print(String.format("% 4d", cal.get(dateConst))); 18 cal.add(dateConst, 1); 19 if (cal.get(java.util.Calendar.MONTH) != month) { 20 System.out.println(); 21 break; 22 } 23} 24

投稿2016/04/18 07:33

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/18 08:14

可読性についてのご指摘ありがとうございました。 なるべくfor文がネストしないよう作っていきたいと思います。 まだまだ分からないことばかりで、有効活用の記載分についてはまだ理解出来かねる部分が多いのですが、理解できるよう頑張っていきます。 またよろしくお願いいたします。
guest

0

ベストアンサー

入力値をチェックしていない

入力値が渡されなかった場合、ArrayIndexOutOfBoundsExceptionが発生してプログラムが異常終了します。

また、"201613"や"123456789"など、年月として無効な値が渡された場合でも、そのまま実行されてしまいます。
これに関しては、cal.setを実行する前にcal.setLenient(false)を実行しておくことで、おかしな日付を黙って計算してしまう事態を防ぐことができます。
https://docs.oracle.com/javase/jp/6/api/java/util/Calendar.html#setLenient(boolean)

文字数の調整方法

java

1if (day < 10) { 2 System.out.print(" "); 3} 4System.out.print(" " + day);

部分で一桁の日付の表示幅を調整しながら出力していますが、String.formatメソッドを使用すれば、以下のように簡潔に書けます。

java

1System.out.print(String.format("% 3d", day));

定数の値に依存した実装

java

1for (int i = startDay; i <= 7; i++) {

などの部分は、Calendar.SUNDAY = 1であることなどに依存した実装になっています。
しかし、万が一、後のバージョンアップで曜日も(月のように)0から始まる連番に変更された場合、このプログラムは正しく動かなくなります。
定数の値が何なのかを気にしなくても良いように実装すべきです。

例えば、あまり良いコードではありませんが、以下のような感じです。

java

1// year,month,1で年月日設定 2cal.set(year, month - 1, 1); 3 4// 理由は不明だが、ここでこれを呼び出しておかないと1月を指定したときにおかしな動きをする。 5// おそらく年・月・日以外のフィールドの値が変更されていないためと思われ。 6cal.getTime(); 7 8// さらに、その週の日曜日に日付を設定 9cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); 10 11while (("" + cal.get(Calendar.YEAR) + (cal.get(Calendar.MONTH) + 1)).compareTo("" + year + month) <= 0) { 12 if (cal.get(Calendar.MONTH) + 1 != month) { 13 // 前月の間は空欄表示 14 System.out.print(" "); 15 } else { 16 System.out.print(String.format("% 3d", cal.get(Calendar.DAY_OF_MONTH))); 17 } 18 19 // 土曜日なら折り返し 20 if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) { 21 System.out.println(); 22 } 23 cal.add(Calendar.DAY_OF_MONTH, 1); 24}

そして指示によりimportは使用できないようになっています。

これを指示した方に、その理由を質問することを強くおすすめします。

何のための制限なのか、正直 理解できません。

あるいは、
「java.langパッケージ以外は使わないこと」
という意味なのかもしれません。

投稿2016/04/18 07:02

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/18 08:12

定数に依存しない実装を教えていただきありがとうございます。 表示幅の簡潔な表し方についても大変勉強になりました! ちなみにimportを使うな、という指示は私がフルネームでAPIメソッドを使用出来るかどうかをチェックしていただけだそうでした;
KiyoshiMotoki

2016/04/18 09:37

お役に立てたなら、幸いです。 > 私がフルネームでAPIメソッドを使用出来るかどうかをチェックしていただけだそうでした; それができたところで何がうれしいのか分かりかねますが(笑)、了解しました。 丁寧なご報告、ありがとうございます。
guest

0

その月の最終日はgetActualMaximumというメソッドにCalendar.DATEを渡せば取得できます。
また、もっとCalendarクラスを活用すれば表示の部分も簡略化できそうです。

投稿2016/04/18 06:06

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/18 06:34

最終日取得についてのご指摘ありがとうございます。 簡略化は是非とも行いたいところですので、『もっとCalendarクラスを活用』についてももう少し詳しくご教授願えませんでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問