日付

システムで日付の入力や表示を取り扱う場面は多いものです。入力する対象の日付の性質に応じて、適したUIは異なります。

カレンダー

カレンダー入力は、リアル世界のカレンダーを模すことで直感的な年月日の入力を可能にします。基本的には現在時点から見て比較的近い日付を指定するのに適しています。

例えば3日後から30日後の日付のみ指定できるようにするなど、受付可能な範囲の日付のみ入力可能なように制限をかけることでエラーの発生を回避するのにも有用です。

曜日を表示
月・日の10の位を0で埋めない
カレンダー内に前後の月の日も表示
年・月をプルダウンに
複数月を表示
週単位で選択

年月 ドロップダウン

カレンダーは年月だけを指定するような場合には必ずしも向いていません。カレンダー入力が直感的なのは現実のカレンダーのモデルについての慣れを利用するから直感的なのであって、実際によく使い慣れたものとして年月のみのカレンダーが存在しない以上、その効果は期待できないからです。

生年月日

生年月日のように年を多く移動し曜日を基準にしないような日付の指定の場合にはカレンダー入力ではなくドロップダウンで年・月・日をそれぞれ選択するほうが適切です。日の選択項目は選択した年月に応じて制御し、存在する日付だけ選択できるようにします。

また、ターゲットの生年月日に最頻値や中央値があるようなら、よいデフォルト値として初期状態ではあらかじめ選択された状態にしておきましょう。平均的な移動距離を短くすることができます。

30

生年月日と年齢の両方を同時に入力させてはいけません。年齢は生年月日からシステム側で算出するようにすれば、情報の不整合によるエラーは起こらなくて済みます。

期間

開始と終了があるパターンです。

カレンダー
から
まで
HTML
<div class="col-md-3 col-all-closer col-all-closer--leftend col-sm-closer--rightend col-xs-closer--rightend">
  <div class="form-group">
    <label><span class="label-text">&nbsp;</span></label>
    <div class="input-group">
      <div class="input-with-icon">
        <input type="text" class="form-control" id="datepicker-from" value="" placeholder="入力または選択"/>
      </div>
      <span class="input-group-addon prn">から</span>
    </div>
  </div>
</div>
<div class="col-md-3 col-all-closer col-all-closer--rightend col-sm-closer--leftend col-xs-closer--leftend">
  <div class="form-group">
    <label><span class="label-text">&nbsp;</span></label>
    <div class="input-group">
      <div class="input-with-icon">
        <input type="text" class="form-control" id="datepicker-to" value="" placeholder="入力または選択"/>
      </div>
      <span class="input-group-addon prn">まで</span>
    </div>
  </div>
</div>
JavaScript
$('#exampleDatepicker-from').datepicker({
  // オプション指定
  showOn: 'both',
  onSelect: function (selectDate) {   // DatePickerが選択された際に実行
    const option = 'minDate';
    $('#exampleDatepicker-to').datepicker('option', option, selectDate);
  }
});
$('#exampleDatepicker-to').datepicker({
  // オプション指定
  showOn: 'both',
  onSelect: function (selectDate) {   // DatePickerが選択された際に実行
    const option = 'maxDate';
    $('#exampleDatepicker-from').datepicker('option', option, selectDate);
  }
});
年月 ドロップダウン
から
まで
HTML
<div class="form-inline mtn">
  <div class="form-group">
    <label for=""><span class="label-text">開始年月</span></label>
    <select name="input" data-group="from-01" class="select-block select--year" id="select--year-from-01" data-live-search="true">
      <option value="2010">2010年</option>
      <option value="2011">2011年</option>
      <option value="2012">2012年</option>
      <option value="2013">2013年</option>
      <option value="2014">2014年</option>
      <option value="2015">2015年</option>
      <option value="2016">2016年</option>
      <option value="2017">2017年</option>
      <option value="2018">2018年</option>
      <option value="2019">2019年</option>
      <option value="2020">2020年</option>
      <option value="2021">2021年</option>
      <option value="2022">2022年</option>
      <option value="2023">2023年</option>
      <option value="2024">2024年</option>
      <option value="2025">2025年</option>
      <option value="2026">2026年</option>
      <option value="2027">2027年</option>
      <option value="2028">2028年</option>
      <option value="2029">2029年</option>
      <option value="2030">2030年</option>
      <option value="2031">2031年</option>
      <option value="2032">2032年</option>
      <option value="2033">2033年</option>
      <option value="2034">2034年</option>
      <option value="2035">2035年</option>
      <option value="2036">2036年</option>
      <option value="2037">2037年</option>
      <option value="2038">2038年</option>
      <option value="2039">2039年</option>
      <option value="2040">2040年</option>
    </select>
  </div>

  <div class="form-group">
    <label class="invisible" for=""><span class="label-text">開始月</span></label>
    <select name="input" data-group="from-01" class="select-block select--month" id="select--month-from-01">
      <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>
  </div>
  <div class="form-group">
    <div class="input-group mtl">
      <span class="input-group-addon ptl phn">から</span>
    </div>
  </div>

  <div class="form-group">
    <label for=""><span class="label-text">終了年月</span></label>
    <select name="input" data-group="to-01" class="select-block select--year" id="select--year-to-01" data-live-search="true">
      <option value="2010">2010年</option>
      <option value="2011">2011年</option>
      <option value="2012">2012年</option>
      <option value="2013">2013年</option>
      <option value="2014">2014年</option>
      <option value="2015">2015年</option>
      <option value="2016">2016年</option>
      <option value="2017">2017年</option>
      <option value="2018">2018年</option>
      <option value="2019">2019年</option>
      <option value="2020">2020年</option>
      <option value="2021">2021年</option>
      <option value="2022">2022年</option>
      <option value="2023">2023年</option>
      <option value="2024">2024年</option>
      <option value="2025">2025年</option>
      <option value="2026">2026年</option>
      <option value="2027">2027年</option>
      <option value="2028">2028年</option>
      <option value="2029">2029年</option>
      <option value="2030">2030年</option>
      <option value="2031">2031年</option>
      <option value="2032">2032年</option>
      <option value="2033">2033年</option>
      <option value="2034">2034年</option>
      <option value="2035">2035年</option>
      <option value="2036">2036年</option>
      <option value="2037">2037年</option>
      <option value="2038">2038年</option>
      <option value="2039">2039年</option>
      <option value="2040">2040年</option>
    </select>
  </div>
  <div class="form-group">
    <label class="invisible" for=""><span class="label-text">終了月</span></label>
    <select name="input" data-group="to-01" class="select-block select--month" id="select--month-to-01">
      <option value="0">1年</option>
      <option value="1">2年</option>
      <option value="2">3年</option>
      <option value="3">4年</option>
      <option value="4">5年</option>
      <option value="5">6年</option>
      <option value="6">7年</option>
      <option value="7">8年</option>
      <option value="8">9年</option>
      <option value="9">10年</option>
      <option value="10">11年</option>
      <option value="11">12年</option>
    </select>
  </div>
  <div class="form-group">
    <div class="input-group mtl">
      <span class="input-group-addon ptl phn">まで</span>
    </div>
  </div>
</div>
年月日 ドロップダウン
から
まで
JavaScript
/**
* 年月日 関数
* @param  {Object} $month 選択したドロップダウンメニュー
*/
function formSetDay($month) {
  /**
  * グループ設定
  * @type {String}
  */
  const group = $month.attr('data-group');

  /**
  * 選択された'年'の値を数値で取得
  * @type {Number}
  */
  const year = parseInt($month.closest('.form-inline').find('.select--year[data-group=' + group + ']').selectpicker('val'));

  /**
  * 選択された'月'の値を数値で取得
  * @type {Number}
  */
  const month = parseInt($month.closest('.form-inline').find('.select--month[data-group=' + group + ']').selectpicker('val'));

  /**
  * 選択した月の最終日
  * @type {Number}
  */
  const lastday = formSetLastDay(year, month);

  let option = '';

  for(let i = 1; i <= lastday; i=(i+1)|0) {
    option += '<option value="' + i + '">' + String(i) + '日</option>\n';
  }
  return option;
}

/**
* 最終日 関数
* @param  {Number} year  選択された年
* @param  {Number} month 選択された月
* @return {Number}       選択された年・月の最終日
*/
function formSetLastDay(year, month) {
  'use strict';
  let lastday = new Array('', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

  /**
  * うるう年 判定
  */
  if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0){
    lastday[2] = 29;
  }
  return lastday[month];
}

/**
* 年月の変更を監視
* bootstrap-select イベント
*/
$('#select--year-02, #select--year-03, #select--year-04, #select--month-02, #select--month-03, #select--month-04').on('changed.bs.select', function(){
  const option_days = formSetDay($(this));
  const group       = $(this).attr('data-group');
  $('.select--day[data-group=' + group + ']').html(option_days).selectpicker('refresh');
});

日付の書式

入力だけでなく、ログイン日時や更新日の表示、そのほかシステム内で取り扱う日時の表記は統一しましょう。

  • 区切り字をどうするか。“/(半角スラッシュ)”とするか、“年”“月”“日”とするか(例:2018/8/31 または 2018年8月31日)
  • 月や日が一桁の場合に10の位を0で埋めるか(例:2018/8/1 または 2018/08/01)
  • 曜日を表記するか(曜日は必要な箇所のみ表示も可)

国際標準としてはISO8601で"YYYYMMDD"方式あるいはハイフンを入れた"YYYY-MM-DD"方式と定められていますが、人間であるユーザーにとっては伝統や視認の容易さなどから各地域・文化圏で様々な表記が一般的に普及しています。年月日の順について、“日/月/年”と“月/日/年”は数値で判別できずに誤解をうむ場合がある(例:04/01/2019は1月4日か4月1日なのか判りにくい)ため、月を数字ではなく月名(January、Janなど)で表記することもあります。多言語でUIを用意する場合には、これらについてもよく確認し方針を決めてシステム内で統一します。

  • 区切り字をどうするか。“/(半角スラッシュ)”とするか、“-(ハイフン)”とするか(例:8/31/2018 または 8-31-2018)
  • 順序はどうするか。(例:欧州ローカル方式 - 曜日/日/月/年、米国ローカル方式 - 曜日/月/日/年
  • 曜日を表記する場合短縮するか(例:Wed または Wednesday)
  • 月の表記をアルファベットにするか(例:8/31/2018 または August/31/2018)
  • 月の表記をアルファベットにする場合短縮するか(例:August/31/2018 または Aug/31/2018)