Web開発

【HTML・JavaScript】日付の入力で西暦と和暦の切り替えをする

スポンサーリンク

概要

少し前に、Webの日付の入力フォームで、西暦と和暦を切り替えられるようにできないかとの話があった時のメモです。

サンプル

最終的に、

  • 西暦・和暦を切り替えるプルダウンを作る
  • 西暦はinput[type=”date”]を使用する
  • 和暦は、元号をプルダウン、年・月・日はinput[type=”number”]を使用する

ということで、以下のような形になりました。

See the Pen 和暦・西暦切り替え入力フォーム by take it easy (@take-it-easy) on CodePen.

実装例

HTML

<div class="date-wrapper">
  <!-- 西暦・和暦の切り替え -->
  <select id="date_type">
    <option value="1" selected>西暦</option>
    <option value="2">和暦</option>
  </select>
  <label>:</label>
  <!-- 西暦の入力用 -->
  <input type="date" id="seireki">
  <!-- 和暦の入力用 -->
  <div id="wareki" style="display: none;">
    <!-- 元号 -->
    <select id="gengou"></select>
    <!-- 年 -->
    <input type="number" id="year" min=1 max=64>
    <label>年</label>
    <!-- 月 -->
    <input type="number" id="month" min=1 max=12>
    <label>月</label>
    <!-- 日 -->
    <input type="number" id="day" min=1 max=31>
    <label>日</label>
  </div>
</div>

JavaScript

/**
 * 和暦マスター
 */
const SEIREKI_WAREKI_MST = [
  ['2019/05/01', '令和'],
  ['1989/01/08', '平成'],
  ['1926/12/25', '昭和'],
  ['1912/07/30', '大正'],
  ['1873/01/01', '明治']
];

/**
 * ページが表示される場合
 */
window.onload = function(){
  // 元号のプルダウンを設定  
  for (var i = 0; i < SEIREKI_WAREKI_MST.length; i++) {
    var option = document.createElement('option');
    option.value = SEIREKI_WAREKI_MST[i][1];
    option.text = SEIREKI_WAREKI_MST[i][1];
    gengou.appendChild(option);
  }
}

/**
 * 和暦・西暦のプルダウン変更時の処理
 */
function changeDateType(e) {
  
  // 西暦が選択されている場合
  if (e.currentTarget.value == '1') {
    wareki.style.display = 'none';
    seireki.style.display = 'flex';
  }
  // 和暦が選択されている場合
  else {
    wareki.style.display = 'flex';
    seireki.style.display = 'none';
  }
}

/**
 * 西暦→和暦変換
 */
function seirekiToWareki(e) {
  
  // 西暦を日付型に変換
  var d = new Date(e.currentTarget.value);
  
  for (let i = 0; i < SEIREKI_WAREKI_MST.length; i++) {
    
    // 元号の開始日を日付型に変換する
    let rd = new Date(SEIREKI_WAREKI_MST[i][0]);
    
    // 入力された日が元号の開始日より未来日の場合
    if (rd <= d) {
      // 年
      year.value = d.getFullYear() - rd.getFullYear() + 1;
      // 月
      month.value = d.getMonth() + 1;
      // 日
      day.value = d.getDate();
      
      break;
    }
  }
}

/**
 * 和暦→西暦
 */
function warekiToSeireki() {
  
  // 元号・年・月・日のいずれか見入力があれば処理しない
  if (gengou.value == ''
      || year.value == ''
      || month.value == ''
      || day.value == '') {
    return;
  }
  
  for (let i = 0; i < SEIREKI_WAREKI_MST.length; i++) {
    
    // 元号が同じ場合
    if (SEIREKI_WAREKI_MST[i][1] == gengou.value) {
      
      // 元号の開始日を日付型に変換する
      let rd = new Date(SEIREKI_WAREKI_MST[i][0]);
      // 年を取得
      var startYear = rd.getFullYear();
      
      // 年
      var yyyy = startYear + Number(year.value) - 1;
      // 月
      var mm = ("0" + month.value).slice(-2);
      // 日
      var dd = ("0" + day.value).slice(-2);
      
      // ハイフンで連結した値を設定
      seireki.value = yyyy + '-' + mm + '-' + dd;
      
      break;
    }
  }
}

// 西暦・和暦
var dateType = document.getElementById('date_type');
dateType.addEventListener('change', changeDateType);

// 西暦の日付
var seireki = document.getElementById('seireki');
seireki.addEventListener('focusout', seirekiToWareki);

// 元号
var gengou = document.getElementById('gengou');
gengou.addEventListener('focusout', warekiToSeireki);

// 和暦の年
var year = document.getElementById('year');
year.addEventListener('focusout', warekiToSeireki);

// 和暦の月
var month = document.getElementById('month');
month.addEventListener('focusout', warekiToSeireki);

// 和暦の日
var day = document.getElementById('day');
day.addEventListener('focusout', warekiToSeireki);

和暦マスターに、和暦の開始日、元号名の配列を準備しておきます。

ページが表示される時に、元号のプルダウンを作成します。

和暦・西暦のプルダウンの切り替えがあった時、入力フォームの切り替えをしています。

西暦が入力されてフォーカスが外れた場合は、和暦へ変換をして和暦の入力フォームへ値を設定します。

和暦が入力されて元号、年、月、日よりフォーカスが外れたら西暦に日付を設定します。

CSS

label {
  margin: 0;
  padding: 0;
}

input,
select {
  height: 26px;
  margin: 0 5px;
  padding: 3px 2px;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  -moz-appearance: textfield;
  margin: 0;
}

input[type="number"] {
  -moz-appearance: textfield;
}

div.date-wrapper {
  display: flex;
}

select#date_type {
  width: 55px;
}

select#gengou {
  width: 55px;
}

input#year,
input#month,
input#day {
  width: 30px;
}

input[type=”number”]のスピンボタン(上下のボタン)は非表示になるようにしています。

あくまでサンプルコードです。使用する場合はご自身の利用に合うかご確認の上使用をしてください。

タイトルとURLをコピーしました