【jQuery】日付プルダウンの期間指定と年齢の自動計算

#やりたいこと
1.日付プルダウンで、現在から4年前までの期間のみを選択可能にする。
2.日付プルダウンで選択された年月日で年齢を自動計算できるようにする。

#完成図

```html
<tr>
  <td><label>お子様のお誕生日</label></td>
  <td>
    <select name="year">
      <!-- 
      <option value='2018'>2018年</option>
      <option value='2019'>2019年</option>
      <option value='2020'>2020年</option> 
      -->
    </select>
    <select name="month">
      <!-- 
      <option value="1">1月</option>
      <option value="2">2月</option>
      <option value="3">3月</option>
      <option value="4">4月</option>
      <option value="5">5月</option>
      <option value="6">6月</option>
      <option value="7">7月</option>
      <option value="8">8月</option>
      <option value="9">9月</option>
      <option value="10">10月</option>
      <option value="11">11月</option>
      <option value="12">12月</option>
      -->
    </select>
    <select name="day">
      <!-- 
      <option value="1">1日</option>
      <option value="2">2日</option>
      <option value="3">3日</option>
      <option value="4">4日</option>
      <option value="5">5日</option>
      <option value="6">6日</option>
      <option value="7">7日</option>
      <option value="8">8日</option>
      <option value="9">9日</option>
      <option value="10">10日</option>
      <option value="11">11日</option>
      <option value="12">12日</option>
      <option value="13">13日</option>
      <option value="14">14日</option>
      <option value="15">15日</option>
      <option value="16">16日</option>
      <option value="17">17日</option>
      <option value="18">18日</option>
      <option value="19">19日</option>
      <option value="20">20日</option>
      <option value="21">21日</option>
      <option value="22">22日</option>
      <option value="23">23日</option>
      <option value="24">24日</option>
      <option value="25">25日</option>
      <option value="26">26日</option>
      <option value="27">27日</option>
      <option value="28">28日</option>
      <option value="29">29日</option>
      <option value="30">30日</option>
      <option value="31">31日</option>
      -->
    </select>
    <select name="old1">
      <option value="0">0歳</option>
      <option value='1'>1歳</option>
      <option value="2">2歳</option>
      <option value="3">3歳</option>
    </select>
    <select name="old2">
      <option value="0">0ヶ月</option>
      <option value="1">1ヶ月</option>
      <option value="2">2ヶ月</option>
      <option value="3">3ヶ月</option>
      <option value="4">4ヶ月</option>
      <option value="5">5ヶ月</option>
      <option value="6">6ヶ月</option>
      <option value="7">7ヶ月</option>
      <option value="8">8ヶ月</option>
      <option value="9">9ヶ月</option>
      <option value="10">10ヶ月</option>
      <option value="11">11ヶ月</option>
    </select>
  </td>
</tr>

```

```js
// 現在年月日を変数に代入
let today = new Date();

// 現在年月日をそれぞれ変数に代入
let year_val = today.getFullYear();
let month_val = today.getMonth() + 1;
let day_val = today.getDate();

// 期限（始）
start_year = year_val;
start_month = month_val;
start_day = day_val;

// 期限（終）
end_year = year_val - 4;
end_month = month_val;
end_day = day_val;

setYear()
setMonth();
setDay();
setOld();

$('select[name=year]').change(function () {
  setMonth();
  setDay();
  setOld();
});

$('select[name=month]').change(function () {
  setDay();
  setOld();
});

$('select[name=day]').change(function () {
  setOld();
});

// 年プルダウンの制御
function setYear() {
  let min_year = end_year; //(2016)
  let max_year = start_year; //(2020) 

  // 初期化
  $('select[name=year] option').remove();

  // 要素をひとつずつ取得
  for (var i = min_year; i <= max_year; i++){
    $('select[name=year]').append('<option value="' + i + '">' + i + '年' + '</option>');
  }
}

// 月プルダウンの制御
function setMonth() {
  // 選択した月を値を取得
  year_val = $('select[name=year]').val();

  // 初期化
  $('select[name=month] option').remove();

  // 初期値
  var min_month = 1;
  var max_month = 12;

  // 月範囲
  if (year_val == start_year) { // 選択した値と現在の年が等しい場合、1月〜現在月までを選択範囲にする
    min_month = 1;
    max_month = start_month;
  } else if (year_val == end_year) { // 選択した値と期限末の年が等しい場合、現在月〜12月までを選択範囲にする
    min_month = start_month;
  }

  // 要素をひとつずつ取得
  for (var i = min_month; i <= max_month; i++){
    $('select[name=month]').append('<option value="' + i + '">' + i + '月' + '</option>');
  }
}

// 日プルダウンの制御
function setDay() {
  // 選択した年の値を取得
  year_val = $('select[name=year]').val();
  // 選択した月の値を取得
  month_val = $('select[name=month]').val();

  // 指定月の末日
  var t = 31;
  // 2月
  if (month_val == 2) {
    //　4で割りきれる且つ100で割りきれない年、または400で割り切れる年は閏年
    if (Math.floor(year_val%4) == 0 && Math.floor(year_val%100) != 0 || Math.floor(year_val%400) == 0) {
      t = 29;
    }  else {
      t = 28;
    }
    // 4,6,9,11月
  } else if (month_val == 4 || month_val == 6 || month_val == 9 || month_val == 11) {
    t = 30;
  }

  // 初期化
  $('select[name=day] option').remove();

  // 初期値
  var min_day = 1;
  var max_day = t;    
  
 
  if (year_val == start_year && month_val == start_month) { //選択した年月と現在の年月が等しい時、1日〜現在日までを選択範囲とする
    max_day = start_day;
  } else if (year_val == end_year && month_val == end_month) { //選択した年月と期限末の年月が等しい時、現在日の次の日〜指定月の末尾までを選択範囲とする
    min_day = start_day +1;
  }

  // 要素をひとつずつ取得
  for (var i = min_day; i <= max_day; i++){
    $('select[name=day]').append('<option value="' + i + '">' + i + '日' + '</option>');
  }
}

// 年齢プルダウンの制御
function setOld() {
  // 選択した年の値取得
  select_year = $('select[name=year]').val(); 
  // 選択した月の値取得
  select_month = $('select[name=month]').val();
  // 選択した日の値取得
  select_day = $('select[name=day]').val();  

  let current = new Date();

  let birthday  = new Date(select_year, select_month, select_day); // 選択した年月日を変数に代入
  let age = today.getFullYear() - birthday.getFullYear();  // 現在の年と設定した年を差し引き年齢を取得
  let current_year = ( current.getFullYear() * 12 ) + (current.getMonth());  // 現在生年月日の月数を取得し、変数に代入
  let birthday_year = ( birthday.getFullYear() * 12 ) + birthday.getMonth();  // 誕生年月日の月数を取得し、変数に代入
  let month = current_year - birthday_year;  // 現在生年月日の月数を誕生年月日の月数で差し引き、月数を取得
  if(month >= 12) {  // month が 12 以上の時
    month = month % 12  // 12で割った余りを month に代入
    if (select_day <= start_day) {  // 今日の日付が選択した日付より大きい時に mouth に 1 を足す
      month = month + 1;
    } else {
      ;
    }
  } else {  // month が 12 以下の時
    if (select_day <= start_day) {
      month = month + 1;
    } else {
      ;
    }  
  }
  //  絶対値
  if (month == 12 || month == -12) {
    month = 0;
  }
  // 選択した月と現在の月が一致している　&& 選択した日が今日よりも大きい場合年齢をひとつ下げる
  if ( (select_day > start_day) && (select_month == start_month) ) {
    age = age - 1
  }

  $('select[name=old1] option[value=' + age + ']').prop('selected', true);
  $('select[name=old2] option[value=' + Math.abs(month) + ']').prop('selected', true);
}
```

#参考サイト
http://php.o0o0.jp/article/jquery-term_pulldown
https://javascript.programmer-reference.com/js-calculation-age/