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 } }