エンジニア成長日記 swaponQ

コンピュータサイエンス専攻の一般人のブログです。

新・明解 Java 入門 演習 10-4 解答

Hello, Terminal!swaponQです!

今回は演習 10-4 に取り組んでいこうと思います。

  • 演習 10-4

日付クラス第4版を以下のように改良せよ。
・引数を受け取らないコンストラクタによるインスタンスの生成時は、西暦1年1月1日で初期化するのではなく、プログラム実行時の日付で初期化する。
・引数を受け取るコンストラクタに不正な値が指定された場合は、適当な値に調整する。
さらに、以下に示すメソッドを追加すること。
・年内での経過日数を求めるメソッド ←本ブログではこちらを実装しました!
・年内の残り日数を求めるメソッド
・他の日付との前後関係を判定するメソッド
等々…

・Day.java

import java.util.GregorianCalendar;
import static java.util.GregorianCalendar.*;

public class Day {
  static GregorianCalendar today = new GregorianCalendar();
  private int year = today.get(YEAR);
  private int month = today.get(MONTH)+1;
  private int date = today.get(DATE);

  public static boolean isLeap(int y) {
    return y%4 == 0 && y%100 != 0 || y%400 == 0;
  }

  public Day() {}
  public Day(int year) {
    if (year < 1) this.year = 1;
    else this.year = year;
  }
  public Day(int year, int month) {
    this(year);
    if (month > 12) this.month = 12;
    else if (month < 1) this.month = 1;
    else this.month = month;
  }
  public Day(int year, int month, int date) {
    this(year,month);
    if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && date > 31) this.date = 31;
    else if ((month == 4 || month == 6 || month == 9 || month == 11) && date > 30) this.date = 30;
    else if (month == 2 && isLeap(year) == true && date > 29) this.date = 29;
    else if (month == 2 && isLeap(year) == false && date > 28) this.date = 28;
    else if (date < 1) this.date = 1;
    else this.date = date;
  }
  public Day(Day d) {
    this(d.year, d.month, d.date);
  }

  public int getYear()      {return year;}
  public int getMonth()     {return month;}
  public int getDay()       {return date;}

  public void setYear(int year)       {this.year = year;}
  public void setMonth(int month)     {this.month = month;}
  public void setDate(int date)       {this.date = date;}

  public void set(int year, int month, int date){
    this.year = year;
    this.month = month;
    this.date = date;
  }

  public boolean isLeap() {
    return isLeap(year);
  }

  public int dayOfWeek(){
    int y = year;
    int m = month;
    if (m == 1 || m == 2){
      y--;
      m += 12;
    }
    return(y+y/4-y/100+y/400+(13*m+8)/5+date)%7;
  }

  public int daysPast(){
    int r =0;
    int y = year;
    int m = month;
    int d = date;
    if(m == 1) r = d;
    else if (m == 2) r = d+31;
    else if (m == 3) r = d+60;
    else if (m == 4) r = d+91;
    else if (m == 5) r = d+121;
    else if (m == 6) r = d+152;
    else if (m == 7) r = d+182;
    else if (m == 8) r = d+213;
    else if (m == 9) r = d+244;
    else if (m == 10) r = d+274;
    else if (m == 11) r = d+305;
    else r = d+335;
    if (isLeap(y) == false) r--;
    return r;
  }

  public String toString() {
    String[] wd = {"日","月","火","水","木","金","土"};
    return String.format("%04d年%02d月%02d日(%s)", year, month,date,wd[dayOfWeek()]);
  }
}

・DayTester.java

import java.util.Scanner;
import java.util.GregorianCalendar;
import static java.util.GregorianCalendar.*;

class DayTester{
	public static void main(String[] args){
		Scanner stdIn = new Scanner(System.in);

		Day t = new Day();
		System.out.println(t.toString());
		System.out.println(t.getYear() +"年は閏年"+(t.isLeap()?"です":"ではありません"));
		System.out.println(t.toString()+"は"+t.getYear()+"年の1月1日から"+t.daysPast()+"日です。");

		int y,m,d;
		System.out.print("年:");
		y = stdIn.nextInt();
		System.out.print("月:");
		m = stdIn.nextInt();
		System.out.print("日:");
		d = stdIn.nextInt();

		Day a = new Day(y,m,d);
		System.out.println(a.toString());
		System.out.println(a.getYear() +"年は閏年"+(a.isLeap()?"です":"ではありません"));
		System.out.println(a.toString()+"は"+a.getYear()+"年の1月1日から"+a.daysPast()+"日です。");
	}
}


・実行結果

2020年08月05日(水)
2020年は閏年です
2020年08月05日(水)は2020年の1月1日から218日です。
年:2020
月:20
日:20
2020年12月20日(日)
2020年は閏年です
2020年12月20日(日)は2020年の1月1日から355日です。

今回は以上です。お疲れ様でした!
次回は演習 10-5 です。

Goodbye, Terminal… swaponQでした!