生年月日入力フォームに「西暦と和暦」を表示するよう実装した話

# はじめに
自分の生まれた年は西暦で分かると思いますが、自分の親や親せきの人の生年月日は西暦だけだと分からないですよね。

そこで西暦と和暦を両方表示させてユーザーが選びやすいように、実務で実装を行ったため、備忘録として残します。
# 使用技術
HTML, Javascript, Laravel

# 実装コード
HTML
```html
<dl>
    <dt>
        <label>生年月日(西暦)<span>必須</span></label>
    </dt>
    <dd>
        <select id="birth_date_year" class="form-control{{ $errors->has('birth_date_year') ? ' is-invalid' : '' }}" name="birth_date_year"></select>
        <select name="birth_date_month" id="birth_date_month" class="form-control{{ $errors->has('birth_date_month') ? ' is-invalid' : '' }}"></select><span class="subscript">月</span>
        <select name="birth_date_day" id="birth_date_day" class="form-control{{ $errors->has('birth_date_day') ? ' is-invalid' : '' }}"></select><span class="subscript">日</span>
    </dd>
</dl>
```

Javascript
```javascript
    const select = document.getElementById('birth_date_year');
    const select_m = document.getElementById('birth_date_month');
    const select_d = document.getElementById('birth_date_day');
    const now = new Date();
    let now_year = now.getFullYear();
    now_year = now_year - 120;
    let thisMonthDay = 31;

    const createYearOption = () => {
        for(let i = 0; i < 122; i++) {
            let option = document.createElement("option");
            option.text = convertYearToJapaneseEra(now_year);
            if(i == 56){
                option.text = '未選択';
                option.value = '';
                option.selected = true;
            }
            else{
                option.value = now_year;
            }
            select.appendChild(option);
            if(i !== 56){
                now_year = now_year + 1;
            }
        }
    }

    const createMonthOption = () => {
        for(let i = 0; i < 12; i++){
            let option2 = document.createElement("option");
            option2.text = i + 1;
            option2.value = i + 1;
            select_m.appendChild(option2);
        }
    }

    const createDayOption = (startNum, endNum) => {
        for(let i = startNum; i < endNum; i++){
            let option3 = document.createElement("option");
            option3.text = i + 1;
            option3.value = i + 1;
            select_d.appendChild(option3);
        }
    }

    function convertYearToJapaneseEra(year) {
        let formatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {year: 'numeric',});
        let era0 = formatter.format(new Date(year, 0, 1));
        let era1 = formatter.format(new Date(year, 11, 31));
        if (era1.endsWith('元年') && era0 !== era1) {
            return year + '年' + '(' + era1 + ')';
        }
        else{
            return year + '年' + '(' + era0 + ')';
        }
    }

    window.addEventListener('load', () => {
        createYearOption();
        createMonthOption();
        createDayOption(0,thisMonthDay);
        setOldValue();
    });

    select.addEventListener('change',() => {
        const selected_year = select.value;
        const selected_month = select_m.value;

        const month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31];
        thisMonthDay = month_days[selected_month];
        if(selected_month == 2 && isLeapYear(selected_year)){
            thisMonthDay = 29;
        }

        select_d.innerHTML = '';
        createDayOption(0,thisMonthDay);
    })

    select_m.addEventListener('change',() => {
        const selected_year = select.value;
        const selected_month = select_m.value;
        const selected_day = select_d.value;

        const month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31];
        thisMonthDay = month_days[selected_month];
        if(selected_month == 2 && isLeapYear(selected_year)){
            thisMonthDay = 29;
        }

        select_d.innerHTML = '';
        createDayOption(0,thisMonthDay);
    })

    function isLeapYear(year){
        if( (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
            return true;
        } else{
            return false;
        }
    }

```