import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
/**
* 誕生日:通常は西暦で管理しており、年齢などを出力するが、
* 必要に応じて和暦で表示する。
*/
public class AdapterTest {
public static void main(String[] args) {
ArrayList<JapaneseBirthDay> chkDays = new ArrayList<JapaneseBirthDay>();
chkDays.add(new JapaneseBirthDay(2023, 5, 2));
chkDays.add(new JapaneseBirthDay(2019, 5, 1));
chkDays.add(new JapaneseBirthDay(2019, 4, 30));
chkDays.add(new JapaneseBirthDay(1989, 1, 8));
chkDays.add(new JapaneseBirthDay(1989, 1, 7));
for (JapaneseBirthDay jbd : chkDays) {
System.out.println(jbd);
System.out.println(jbd.yearsOld());
System.out.println(jbd.toWareki());
System.out.println("-----");
}
}
}
/**
* 誕生日クラス
* Calendar や LocalDate など、年月日を保持するクラスを継承してもよかったが、
* 今回はメンバーとして持つことにした。
*
* 誕生日クラス自身も、Calendar に対するアダプタークラス(オブジェクト・アダプター:移譲を利用)といえる
* (なぜなら、yearsOld() を追加しているので)
* また、toString()をシンプルにしている。
* もし、Calendar クラスを継承していたら、toString()はCalendarクラスのメソッドをオーバーライドすることになる。
*/
class BirthDay {
protected Calendar cal;
public BirthDay(int year, int month, int day) {
cal = Calendar.getInstance();
cal.set(year, month, day);
}
// 誕生日をYYYY/MM/DD で返す
public String toString() {
// return bd.toString();
return String.format("%4d/%02d/%02d", cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH));
}
// 何歳何ヶ月?を返す
public String yearsOld() {
LocalDate curDate = LocalDate.now();
Period sabun = Period.between(cal.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), curDate);
return String.format("%3d yrs %2d months %2d days", sabun.getYears(), sabun.getMonths(),
sabun.getDays());
}
}
/**
* 和暦で誕生日を表示できるクラス (継承によるAdapter)
*/
class JapaneseBirthDay extends BirthDay {
public JapaneseBirthDay(int year, int month, int day) {
super(year, month, day);
}
/**
* 和暦での誕生日表記を返す
* @return 和暦での誕生日表記
*/
public String toWareki() {
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
return getNengo() + "/" + String.format("%02d/%02d", month, day);
}
/**
* 年号アルファベット+年 を返す
* @return 年号アルファベット+年
*/
private String getNengo() {
String[] nengoArray = { "M", "T", "S", "H", "R" }; // Meiji,Taisho,Showa,Heisei,Reiwa
int[] fromYear = { 1868, 1912, 1926, 1989, 2019 };
int[] fromMonth = { 1, 7, 12, 1, 5 };
int[] fromDay = { 25, 30, 25, 8, 1 };
int year = cal.get(Calendar.YEAR);
String ymd = this.toString(); // 形式:YYYY/MM/DD (例: 1999/10/22)
String nengo = null;
int nengoYear = 0;
for (int i = nengoArray.length - 1; i > 0; i--) {
String fromYMD = new BirthDay(fromYear[i], fromMonth[i], fromDay[i]).toString();
// System.out.print(" >> check "+fromYMD+" <= "+ymd);
if (fromYMD.compareTo(ymd) <= 0) { // YYYY/MM/DD文字列の大小関係でチェックしている
// System.out.println(" OK");
nengo = nengoArray[i];
nengoYear = year - fromYear[i]+1;
break;
} else {
// System.out.println(" X");
}
}
if (nengo == null) {
nengo = "E";
nengoYear = year - 1603 + 1;
}
return String.format("%s%02d", nengo, nengoYear); // ex. R05 H30
}
}